@runtypelabs/persona 4.17.1 → 4.18.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 (158) hide show
  1. package/dist/chunk-3I2S3I5P.js +1 -0
  2. package/dist/chunk-76IELU7F.js +1 -0
  3. package/dist/chunk-EFJBUH5F.js +1 -0
  4. package/dist/chunk-PDPVORUF.js +1 -0
  5. package/dist/chunk-Q735PSZL.js +1 -0
  6. package/dist/chunk-VK6JOIYJ.js +1 -0
  7. package/dist/codegen.cjs +4 -4
  8. package/dist/codegen.js +4 -4
  9. package/dist/{context-mentions-BTSTIBFC.js → context-mentions-MJL6S6P2.js} +1 -1
  10. package/dist/context-mentions.cjs +9 -8
  11. package/dist/context-mentions.d.cts +1212 -14
  12. package/dist/context-mentions.d.ts +1212 -14
  13. package/dist/context-mentions.js +9 -8
  14. package/dist/event-stream-view-4EZ7BGFK.js +1 -0
  15. package/dist/event-stream-view.cjs +129 -0
  16. package/dist/event-stream-view.d.cts +8384 -0
  17. package/dist/event-stream-view.d.ts +8384 -0
  18. package/dist/event-stream-view.js +129 -0
  19. package/dist/history-view-BD6OXLNA.js +898 -0
  20. package/dist/history-view.cjs +898 -0
  21. package/dist/history-view.d.cts +1461 -0
  22. package/dist/history-view.d.ts +1461 -0
  23. package/dist/history-view.js +898 -0
  24. package/dist/index.cjs +77 -77
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +1987 -17
  27. package/dist/index.d.ts +1987 -17
  28. package/dist/index.global.js +67 -66
  29. package/dist/index.global.js.map +1 -1
  30. package/dist/index.js +77 -77
  31. package/dist/index.js.map +1 -1
  32. package/dist/launcher.global.js +5 -4
  33. package/dist/launcher.global.js.map +1 -1
  34. package/dist/plugin-kit.cjs +1 -1
  35. package/dist/plugin-kit.d.cts +0 -8
  36. package/dist/plugin-kit.d.ts +0 -8
  37. package/dist/plugin-kit.js +1 -1
  38. package/dist/smart-dom-reader.d.cts +1212 -14
  39. package/dist/smart-dom-reader.d.ts +1212 -14
  40. package/dist/theme-editor-preview.cjs +970 -73
  41. package/dist/theme-editor-preview.d.cts +1331 -15
  42. package/dist/theme-editor-preview.d.ts +1331 -15
  43. package/dist/theme-editor-preview.js +81 -81
  44. package/dist/theme-editor.cjs +7 -7
  45. package/dist/theme-editor.d.cts +1215 -15
  46. package/dist/theme-editor.d.ts +1215 -15
  47. package/dist/theme-editor.js +9 -9
  48. package/dist/theme-reference.cjs +1 -1
  49. package/dist/theme-reference.d.cts +226 -7
  50. package/dist/theme-reference.d.ts +226 -7
  51. package/dist/theme-reference.js +1 -1
  52. package/dist/widget.css +1 -1
  53. package/package.json +16 -4
  54. package/src/client-history-rest.test.ts +1034 -0
  55. package/src/client-visitor-history.test.ts +596 -0
  56. package/src/client.ts +1040 -24
  57. package/src/components/artifact-inline.ts +8 -1
  58. package/src/components/artifact-pane.test.ts +278 -1
  59. package/src/components/artifact-pane.ts +135 -67
  60. package/src/components/artifact-preview.test.ts +14 -1
  61. package/src/components/artifact-preview.ts +9 -0
  62. package/src/components/header-builder.ts +3 -0
  63. package/src/components/header-layouts.test.ts +171 -7
  64. package/src/components/header-layouts.ts +83 -53
  65. package/src/components/header-parts.test.ts +154 -1
  66. package/src/components/header-parts.ts +266 -138
  67. package/src/components/history-confirm-dialog.ts +177 -0
  68. package/src/components/history-shell-copy.ts +99 -0
  69. package/src/components/history-view/announcer.ts +40 -0
  70. package/src/components/history-view/copy.ts +105 -0
  71. package/src/components/history-view/css.ts +1078 -0
  72. package/src/components/history-view/grouping.test.ts +142 -0
  73. package/src/components/history-view/grouping.ts +142 -0
  74. package/src/components/history-view/icons.ts +73 -0
  75. package/src/components/history-view/rows.ts +341 -0
  76. package/src/components/history-view/state.ts +309 -0
  77. package/src/components/history-view.test.ts +2660 -0
  78. package/src/components/history-view.ts +1891 -0
  79. package/src/components/launcher-surface.test.ts +133 -0
  80. package/src/components/launcher.test.ts +18 -0
  81. package/src/components/launcher.ts +7 -7
  82. package/src/components/panel.ts +17 -7
  83. package/src/components/welcome.ts +72 -2
  84. package/src/defaults.ts +36 -3
  85. package/src/event-stream-view-bundle.test.ts +69 -0
  86. package/src/event-stream-view-entry.ts +19 -0
  87. package/src/event-stream-view-loader.ts +31 -0
  88. package/src/event-stream-view.ts +19 -0
  89. package/src/generated/runtype-openapi-contract.ts +1 -0
  90. package/src/history-render.ts +325 -0
  91. package/src/history-view-bundle.test.ts +78 -0
  92. package/src/history-view-entry.ts +41 -0
  93. package/src/history-view-loader.test.ts +30 -0
  94. package/src/history-view-loader.ts +32 -0
  95. package/src/history-view.ts +28 -0
  96. package/src/index-core.ts +50 -2
  97. package/src/index-global.ts +55 -0
  98. package/src/internal/demo-history-provider.test.ts +402 -0
  99. package/src/internal/demo-history-provider.ts +689 -0
  100. package/src/internal/history-provider-registry.ts +25 -0
  101. package/src/internal/history-provider.ts +150 -0
  102. package/src/internal/runtype-history-provider.test.ts +313 -0
  103. package/src/internal/runtype-history-provider.ts +240 -0
  104. package/src/plugin-kit.test.ts +16 -0
  105. package/src/plugin-kit.ts +13 -5
  106. package/src/plugins/types.ts +177 -1
  107. package/src/session-history.test.ts +1397 -0
  108. package/src/session.ts +1200 -26
  109. package/src/styles/widget-styles.test.ts +133 -0
  110. package/src/styles/widget.css +227 -8
  111. package/src/theme-editor/preview-utils.test.ts +19 -0
  112. package/src/theme-editor/preview-utils.ts +15 -1
  113. package/src/theme-editor/preview.ts +7 -1
  114. package/src/theme-editor/role-mappings.ts +4 -1
  115. package/src/theme-editor/sections.test.ts +168 -1
  116. package/src/theme-editor/sections.ts +136 -7
  117. package/src/theme-editor/webmcp/summary.ts +16 -2
  118. package/src/theme-reference.ts +20 -6
  119. package/src/types/theme.ts +213 -7
  120. package/src/types.ts +927 -7
  121. package/src/ui.artifact-rail-resize.test.ts +235 -0
  122. package/src/ui.attachments-drop.test.ts +1 -0
  123. package/src/ui.header-update-stability.test.ts +2 -2
  124. package/src/ui.history-chunk.test.ts +72 -0
  125. package/src/ui.history-config-provider.test.ts +318 -0
  126. package/src/ui.history-controller.test.ts +711 -0
  127. package/src/ui.history-lifecycle.test.ts +456 -0
  128. package/src/ui.history-render-hooks.test.ts +904 -0
  129. package/src/ui.history-shell.test.ts +1887 -0
  130. package/src/ui.rail-overlay.test.ts +573 -0
  131. package/src/ui.rail-resize.test.ts +284 -0
  132. package/src/ui.rebuild-composer.test.ts +21 -0
  133. package/src/ui.render-welcome.test.ts +42 -0
  134. package/src/ui.shortcuts.test.ts +166 -0
  135. package/src/ui.ts +3071 -240
  136. package/src/utils/__fixtures__/client-conversation-history-wire.json +108 -0
  137. package/src/utils/artifact-file.ts +15 -0
  138. package/src/utils/artifact-gate.test.ts +4 -0
  139. package/src/utils/artifact-gate.ts +13 -17
  140. package/src/utils/artifact-resize.test.ts +28 -0
  141. package/src/utils/artifact-resize.ts +9 -2
  142. package/src/utils/buttons.ts +188 -1
  143. package/src/utils/config-merge.test.ts +91 -0
  144. package/src/utils/dropdown.ts +10 -1
  145. package/src/utils/history-messages.test.ts +284 -0
  146. package/src/utils/history-messages.ts +284 -0
  147. package/src/utils/icons.ts +3 -0
  148. package/src/utils/shortcuts.test.ts +288 -0
  149. package/src/utils/shortcuts.ts +221 -0
  150. package/src/utils/theme.test.ts +501 -4
  151. package/src/utils/theme.ts +42 -3
  152. package/src/utils/tokens.ts +153 -15
  153. package/src/utils/tooltip-timing.ts +4 -0
  154. package/src/utils/tooltip.test.ts +249 -7
  155. package/src/utils/tooltip.ts +146 -4
  156. package/src/utils/visitor-store.test.ts +425 -0
  157. package/src/utils/visitor-store.ts +337 -0
  158. package/dist/chunk-QJ4LV2KW.js +0 -1
@@ -0,0 +1,1078 @@
1
+ /**
2
+ * All styles for the Messages view, carried by the lazy history-view chunk and
3
+ * injected on mount (`injectStyles`) rather than shipped in `widget.css`:
4
+ * the eager stylesheet is at its size cap and this surface only ever renders
5
+ * after the chunk loads.
6
+ *
7
+ * Every rule is scoped under `.persona-history-view` (and interactive elements
8
+ * additionally by tag), so demo/host resets such as `[data-persona-root] h2`
9
+ * cannot outrank a single-class widget rule. The one exception is the
10
+ * "shell-hosted top bar" block at the end: those nodes live in the widget's own
11
+ * header, outside the view, so their selectors are doubled up instead.
12
+ *
13
+ * History-specific custom properties, all with a themed fallback chain:
14
+ * --persona-history-surface-bg list/background surface
15
+ * --persona-history-topbar-bg top bar background
16
+ * --persona-history-border hairlines and dividers
17
+ * --persona-history-row-hover-bg row hover/active-press wash
18
+ * --persona-history-row-avatar-bg leading row avatar plate
19
+ * --persona-history-row-active-bg selected conversation wash (wash-only, no
20
+ * edge marker; the divider-chain default cannot collapse into the surface)
21
+ * --persona-history-skeleton-bg loading placeholder blocks
22
+ * --persona-history-focus-ring focus-visible outline color
23
+ * --persona-history-slide entrance/exit horizontal travel
24
+ * --persona-history-row-min-height / --persona-history-topbar-min-height
25
+ *
26
+ * Section notes are JS comments between concatenated literals, never CSS
27
+ * comments inside them: the chunk is at its size cap and only JS comments are
28
+ * minified away. Backticks in a note would terminate the literal.
29
+ */
30
+
31
+ export const HISTORY_VIEW_CSS =
32
+ `
33
+ .persona-history-view {
34
+ --persona-history-surface-bg: var(--persona-surface, #ffffff);
35
+ --persona-history-topbar-bg: var(--persona-header-bg, var(--persona-surface, #ffffff));
36
+ --persona-history-border: var(--persona-divider, var(--persona-border, #e5e7eb));
37
+ --persona-history-row-hover-bg: var(--persona-button-ghost-hover-bg, rgba(0, 0, 0, 0.04));
38
+ --persona-history-row-avatar-bg: var(--persona-header-icon-bg, var(--persona-primary, #2563eb));
39
+ --persona-history-row-active-bg: var(--persona-divider, var(--persona-border, #e5e7eb));
40
+ --persona-history-skeleton-bg: var(--persona-divider, var(--persona-border, #e5e7eb));
41
+ --persona-history-focus-ring: var(--persona-primary, #2563eb);
42
+ --persona-history-slide: 20px;
43
+ --persona-history-row-min-height: 60px;
44
+ --persona-history-topbar-min-height: 56px;
45
+ box-sizing: border-box;
46
+ display: flex;
47
+ flex-direction: column;
48
+ width: 100%;
49
+ max-width: 100%;
50
+ min-width: 0;
51
+ height: 100%;
52
+ overflow: hidden;
53
+ background: var(--persona-history-surface-bg);
54
+ color: var(--persona-text, #111827);
55
+ font-family: var(--persona-font-family, inherit);
56
+ font-size: 14px;
57
+ line-height: 1.45;
58
+ opacity: 1;
59
+ }
60
+ .persona-history-view *,
61
+ .persona-history-view *::before,
62
+ .persona-history-view *::after {
63
+ box-sizing: border-box;
64
+ }
65
+ ` +
66
+ /* In-panel navigation, not a sheet: only the body moves, so the bar is never
67
+ animated or replaced. The mirrored exit is playExit() in history-view.ts. */
68
+ `.persona-history-view--enter .persona-history-body {
69
+ animation: persona-history-enter-body var(--persona-history-enter-ms, 180ms)
70
+ var(--persona-history-enter-easing, cubic-bezier(0, 0, 0.2, 1)) both;
71
+ }
72
+ @keyframes persona-history-enter-body {
73
+ from { opacity: 0; transform: translateX(var(--persona-history-slide)); }
74
+ to { opacity: 1; transform: none; }
75
+ }
76
+ ` +
77
+ /* Ambient identity states collapse to the caption above the list; the sentence
78
+ stays in the accessibility tree for its aria-describedby. Panel date
79
+ headings go the same way: one flat list, but the lists stay labelled. */
80
+ `.persona-history-view .persona-history-sr-only,
81
+ .persona-history-view--panel .persona-history-group-heading,
82
+ .persona-history-view--panel .persona-history-conversations-title,
83
+ .persona-history-view .persona-history-scope-alert[data-persona-history-scope-tone="ambient"] {
84
+ position: absolute;
85
+ width: 1px;
86
+ height: 1px;
87
+ margin: -1px;
88
+ padding: 0;
89
+ overflow: hidden;
90
+ clip: rect(0 0 0 0);
91
+ clip-path: inset(50%);
92
+ white-space: nowrap;
93
+ border: 0;
94
+ }
95
+
96
+ ` +
97
+ /* --- top bar ------------------------------------------------------------ */
98
+ /* --shell = the same bar hosted in the widget's own header (block below). */
99
+ `.persona-history-view .persona-history-topbar,
100
+ .persona-history-topbar.persona-history-topbar--shell {
101
+ display: grid;
102
+ grid-template-columns: 44px minmax(0, 1fr) 44px;
103
+ align-items: center;
104
+ gap: 4px;
105
+ }
106
+ .persona-history-view .persona-history-topbar {
107
+ min-height: var(--persona-history-topbar-min-height);
108
+ padding: 6px 8px;
109
+ background: var(--persona-history-topbar-bg);
110
+ border-bottom: 1px solid var(--persona-history-border);
111
+ }
112
+ .persona-history-view .persona-history-heading-group,
113
+ .persona-history-topbar--shell .persona-history-heading-group {
114
+ min-width: 0;
115
+ text-align: center;
116
+ }
117
+ .persona-history-view .persona-history-title,
118
+ .persona-history-topbar--shell .persona-history-title {
119
+ margin: 0;
120
+ padding: 0;
121
+ ` +
122
+ /* Pinned like the main header stamps it inline: without a declaration here,
123
+ a non-shadow host's own h2 font rule fills the gap and the two titles
124
+ drift apart. The inherit fallback resolves to the widget's font. */
125
+ ` font-family: var(--persona-components-header-title-fontFamily, inherit);
126
+ font-size: var(--persona-components-header-title-fontSize, 1rem);
127
+ font-weight: var(--persona-components-header-title-fontWeight, 600);
128
+ line-height: var(--persona-components-header-title-lineHeight, 1.5rem);
129
+ color: var(--persona-header-title-fg, var(--persona-primary, #0f0f0f));
130
+ overflow: hidden;
131
+ text-overflow: ellipsis;
132
+ white-space: nowrap;
133
+ }
134
+ ` +
135
+ /* Ambient privacy caption: a body row above the list, never a second bar line.
136
+ The row also carries the list overflow trigger at its trailing end. */
137
+ `.persona-history-view .persona-history-caption {
138
+ position: relative;
139
+ display: flex;
140
+ align-items: center;
141
+ gap: 8px;
142
+ padding: 0 4px;
143
+ }
144
+ .persona-history-view .persona-history-scope {
145
+ flex: 1 1 auto;
146
+ margin: 0;
147
+ font-size: 12px;
148
+ line-height: 1.35;
149
+ color: var(--persona-text-muted, #6b7280);
150
+ overflow-wrap: anywhere;
151
+ }
152
+ ` +
153
+ /* Heading over the list block. Visible only in the rail (the panel sr-onlys
154
+ it above); rail-specific placement is in the rail section below. Every
155
+ text property is pinned: a bare host h3 rule beats inheritance for
156
+ whatever this rule leaves undeclared. */
157
+ `.persona-history-view .persona-history-conversations-title {
158
+ margin: 0;
159
+ font-family: var(--persona-components-history-listHeading-fontFamily, inherit);
160
+ font-size: var(--persona-components-history-listHeading-fontSize, 14px);
161
+ font-weight: var(--persona-components-history-listHeading-fontWeight, 600);
162
+ line-height: var(--persona-components-history-listHeading-lineHeight, 20px);
163
+ letter-spacing: var(--persona-components-history-listHeading-letterSpacing, normal);
164
+ color: var(--persona-components-history-listHeading-color, var(--persona-text, #111827));
165
+ overflow: hidden;
166
+ text-overflow: ellipsis;
167
+ white-space: nowrap;
168
+ }
169
+ ` +
170
+ /* Rail-only caption chrome: hidden until the rail block below reveals it. */
171
+ `.persona-history-view .persona-history-scope-icon {
172
+ display: none;
173
+ }
174
+ .persona-history-view .persona-history-scope-description {
175
+ display: block;
176
+ }
177
+ .persona-history-view .persona-history-scope-alert {
178
+ display: flex;
179
+ flex-direction: column;
180
+ align-items: flex-start;
181
+ gap: 8px;
182
+ margin: 0;
183
+ padding: 10px 12px;
184
+ border: 1px solid var(--persona-history-border);
185
+ border-radius: var(--persona-radius-md, 8px);
186
+ font-size: 12px;
187
+ color: var(--persona-text-muted, #6b7280);
188
+ }
189
+ .persona-history-view .persona-history-scope-alert-title {
190
+ display: block;
191
+ font-weight: 600;
192
+ color: var(--persona-text, #111827);
193
+ }
194
+
195
+ ` +
196
+ /* --- shared controls ---------------------------------------------------- */
197
+ `.persona-history-view button.persona-history-icon-button,
198
+ .persona-history-topbar--shell button.persona-history-icon-button {
199
+ display: inline-flex;
200
+ align-items: center;
201
+ justify-content: center;
202
+ width: 44px;
203
+ height: 44px;
204
+ min-width: 44px;
205
+ min-height: 44px;
206
+ padding: 0;
207
+ margin: 0;
208
+ border: 0;
209
+ border-radius: var(--persona-button-ghost-radius, var(--persona-radius-md, 8px));
210
+ background: transparent;
211
+ color: var(--persona-header-action-icon-fg, var(--persona-text-muted, #6b7280));
212
+ cursor: pointer;
213
+ }
214
+ .persona-history-view button.persona-history-icon-button:hover:not(:disabled),
215
+ .persona-history-topbar--shell button.persona-history-icon-button:hover:not(:disabled) {
216
+ background: var(--persona-button-ghost-hover-bg, rgba(0, 0, 0, 0.04));
217
+ }
218
+ .persona-history-view button:focus-visible,
219
+ .persona-history-view [role="menuitem"]:focus-visible,
220
+ .persona-history-topbar--shell button:focus-visible {
221
+ outline: 2px solid var(--persona-history-focus-ring, var(--persona-primary, #2563eb));
222
+ outline-offset: 2px;
223
+ }
224
+ .persona-history-view button:disabled {
225
+ opacity: 0.55;
226
+ cursor: default;
227
+ }
228
+ ` +
229
+ /* List overflow trigger: answers to the caption beside it, not to the 44px
230
+ header controls, and goes back to a real target for coarse pointers. */
231
+ `.persona-history-view button.persona-history-list-options {
232
+ width: 28px;
233
+ height: 28px;
234
+ min-width: 28px;
235
+ min-height: 28px;
236
+ margin-left: auto;
237
+ }
238
+ .persona-history-view button.persona-history-list-options[aria-expanded="true"] {
239
+ background: var(--persona-button-ghost-hover-bg, rgba(0, 0, 0, 0.04));
240
+ color: var(--persona-text, #111827);
241
+ }
242
+
243
+ ` +
244
+ /* --- body / regions ----------------------------------------------------- */
245
+ `.persona-history-view .persona-history-body {
246
+ flex: 1 1 auto;
247
+ min-height: 0;
248
+ overflow-y: auto;
249
+ overflow-x: hidden;
250
+ padding: 12px 16px 16px;
251
+ display: flex;
252
+ flex-direction: column;
253
+ gap: 16px;
254
+ }
255
+ ` +
256
+ /* Shared skeleton; each presentation styles its own shape below (panel: a
257
+ floating pill under the list, rail: a row above it). */
258
+ `.persona-history-view button.persona-history-new {
259
+ display: inline-flex;
260
+ align-items: center;
261
+ gap: 8px;
262
+ max-width: 100%;
263
+ border: 1px solid transparent;
264
+ border-radius: var(--persona-button-radius, var(--persona-radius-lg, 10px));
265
+ font: inherit;
266
+ font-size: 14px;
267
+ line-height: 20px;
268
+ text-align: left;
269
+ cursor: pointer;
270
+ }
271
+ .persona-history-view button.persona-history-new span {
272
+ min-width: 0;
273
+ overflow-wrap: anywhere;
274
+ }
275
+ .persona-history-view .persona-history-list-region {
276
+ display: flex;
277
+ flex-direction: column;
278
+ gap: 16px;
279
+ min-width: 0;
280
+ }
281
+
282
+ ` +
283
+ /* --- groups and rows ---------------------------------------------------- */
284
+ `.persona-history-view .persona-history-group-heading {
285
+ margin: 0 0 4px;
286
+ padding: 0 4px;
287
+ font-family: var(--persona-components-history-groupHeading-fontFamily, inherit);
288
+ font-size: var(--persona-components-history-groupHeading-fontSize, 12px);
289
+ font-weight: var(--persona-components-history-groupHeading-fontWeight, 600);
290
+ line-height: var(--persona-components-history-groupHeading-lineHeight, 1.35);
291
+ letter-spacing: var(--persona-components-history-groupHeading-letterSpacing, normal);
292
+ color: var(--persona-components-history-groupHeading-color, var(--persona-text-muted, #6b7280));
293
+ }
294
+ .persona-history-view ul.persona-history-list {
295
+ list-style: none;
296
+ margin: 0;
297
+ padding: 0;
298
+ }
299
+ .persona-history-view li.persona-history-item {
300
+ position: relative;
301
+ margin: 0;
302
+ padding: 0;
303
+ list-style: none;
304
+ }
305
+ .persona-history-view button.persona-history-row {
306
+ display: flex;
307
+ align-items: center;
308
+ gap: 8px;
309
+ width: 100%;
310
+ min-height: var(--persona-history-row-min-height);
311
+ padding: 10px 16px;
312
+ margin: 0;
313
+ border: 0;
314
+ border-radius: 0;
315
+ background: transparent;
316
+ color: inherit;
317
+ font: inherit;
318
+ text-align: left;
319
+ cursor: pointer;
320
+ }
321
+ ` +
322
+ /* Hover keyed to the li so the wash holds over the sibling menu trigger. */
323
+ `.persona-history-view li.persona-history-item:hover button.persona-history-row:not(:disabled),
324
+ .persona-history-view button.persona-history-row:hover:not(:disabled) {
325
+ background: var(--persona-history-row-hover-bg);
326
+ }
327
+ .persona-history-view button.persona-history-row[aria-current="page"] {
328
+ background: var(--persona-history-row-active-bg);
329
+ }
330
+ .persona-history-view .persona-history-row-avatar {
331
+ display: flex;
332
+ flex: 0 0 auto;
333
+ align-items: center;
334
+ justify-content: center;
335
+ width: 40px;
336
+ height: 40px;
337
+ overflow: hidden;
338
+ border-radius: 16.7%;
339
+ background: var(--persona-history-row-avatar-bg);
340
+ color: var(--persona-header-icon-fg, var(--persona-text-inverse, #ffffff));
341
+ font-size: 20px;
342
+ line-height: 1;
343
+ }
344
+ .persona-history-view .persona-history-row-avatar img {
345
+ width: 100%;
346
+ height: 100%;
347
+ object-fit: cover;
348
+ }
349
+ .persona-history-view .persona-history-row-body {
350
+ flex: 1 1 auto;
351
+ min-width: 0;
352
+ line-height: 21px;
353
+ }
354
+ .persona-history-view .persona-history-row-head {
355
+ display: flex;
356
+ align-items: baseline;
357
+ gap: 8px;
358
+ min-width: 0;
359
+ }
360
+ .persona-history-view .persona-history-row-title {
361
+ flex: 1 1 auto;
362
+ min-width: 0;
363
+ font-size: 14px;
364
+ font-weight: 600;
365
+ color: var(--persona-text, #111827);
366
+ }
367
+ .persona-history-view .persona-history-truncate {
368
+ display: block;
369
+ overflow: hidden;
370
+ text-overflow: ellipsis;
371
+ white-space: nowrap;
372
+ }
373
+ .persona-history-view time.persona-history-row-time {
374
+ flex: 0 0 auto;
375
+ white-space: nowrap;
376
+ font-size: 14px;
377
+ font-weight: 400;
378
+ font-variant-numeric: tabular-nums;
379
+ color: var(--persona-text-muted, #6b7280);
380
+ }
381
+ .persona-history-view .persona-history-row-star {
382
+ flex: 0 0 auto;
383
+ display: inline-flex;
384
+ align-self: center;
385
+ color: var(--persona-text-muted, #6b7280);
386
+ }
387
+ .persona-history-view .persona-history-row-preview {
388
+ font-size: 14px;
389
+ color: var(--persona-text-muted, #6b7280);
390
+ }
391
+ ` +
392
+ /* No per-row menu in the reference design: the trigger takes the time's slot
393
+ on hover/focus and stays put for coarse pointers and while its menu is open. */
394
+ `.persona-history-view button.persona-history-row-menu-button {
395
+ position: absolute;
396
+ top: 50%;
397
+ right: 6px;
398
+ transform: translateY(-50%);
399
+ color: var(--persona-text-muted, #6b7280);
400
+ }
401
+ @media (hover: hover) {
402
+ .persona-history-view button.persona-history-row-menu-button {
403
+ opacity: 0;
404
+ transition: opacity 120ms ease;
405
+ }
406
+ .persona-history-view li.persona-history-item:hover time.persona-history-row-time,
407
+ .persona-history-view li.persona-history-item:focus-within time.persona-history-row-time {
408
+ opacity: 0;
409
+ }
410
+ .persona-history-view li.persona-history-item:hover button.persona-history-row-menu-button,
411
+ .persona-history-view li.persona-history-item:focus-within button.persona-history-row-menu-button {
412
+ opacity: 1;
413
+ }
414
+ }
415
+ .persona-history-view button.persona-history-row-menu-button[aria-expanded="true"] {
416
+ opacity: 1;
417
+ }
418
+ ` +
419
+ /* The chip composites the wash twice over the opaque surface: one step to
420
+ match the hovered row, one to stand off it, so text never shows through. */
421
+ `.persona-history-view button.persona-history-row-menu-button:hover:not(:disabled),
422
+ .persona-history-view button.persona-history-row-menu-button[aria-expanded="true"] {
423
+ background: linear-gradient(var(--persona-history-row-hover-bg), var(--persona-history-row-hover-bg)),
424
+ linear-gradient(var(--persona-history-row-hover-bg), var(--persona-history-row-hover-bg)),
425
+ var(--persona-history-surface-bg);
426
+ color: var(--persona-text, #111827);
427
+ }
428
+ ` +
429
+ /* Long previews taper out before the trigger zone instead of running under
430
+ the glyph: whenever the trigger is present (revealed on hover/focus, held
431
+ by an open menu, or always for coarse pointers). */
432
+ `@media (hover: hover) {
433
+ .persona-history-view li.persona-history-item:hover .persona-history-row-preview,
434
+ .persona-history-view li.persona-history-item:focus-within .persona-history-row-preview,
435
+ .persona-history-view li.persona-history-item:has(button[aria-expanded="true"]) .persona-history-row-preview {
436
+ -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 84px), transparent calc(100% - 36px));
437
+ mask-image: linear-gradient(to right, #000 calc(100% - 84px), transparent calc(100% - 36px));
438
+ }
439
+ }
440
+ ` +
441
+ /* showDelete:false rows render no trigger, so the time keeps its slot on
442
+ hover and the preview never tapers. Must stay after the rules above (the
443
+ hover pairs tie on specificity) but outranks the coarse mask below. */
444
+ `.persona-history-view li.persona-history-item--no-menu:hover time.persona-history-row-time,
445
+ .persona-history-view li.persona-history-item--no-menu:focus-within time.persona-history-row-time {
446
+ opacity: 1;
447
+ }
448
+ .persona-history-view li.persona-history-item--no-menu:hover .persona-history-row-preview,
449
+ .persona-history-view li.persona-history-item--no-menu:focus-within .persona-history-row-preview,
450
+ .persona-history-view li.persona-history-item--no-menu .persona-history-row-preview {
451
+ -webkit-mask-image: none;
452
+ mask-image: none;
453
+ }
454
+ .persona-history-view .persona-history-menu {
455
+ position: absolute;
456
+ top: calc(50% + 20px);
457
+ right: 8px;
458
+ z-index: 2;
459
+ min-width: 160px;
460
+ max-width: calc(100% - 16px);
461
+ padding: 4px;
462
+ border: 1px solid var(--persona-history-border);
463
+ border-radius: var(--persona-history-menu-radius, 12px);
464
+ background: var(--persona-history-surface-bg);
465
+ background: var(--persona-history-menu-bg, color-mix(in srgb, var(--persona-history-surface-bg) 92%, #fff));
466
+ box-shadow: 0 8px 28px rgba(0, 0, 0, 0.12);
467
+ }
468
+ ` +
469
+ /* The list menu hangs off the caption row's trailing end instead of a row. */
470
+ `.persona-history-view .persona-history-caption .persona-history-menu {
471
+ top: calc(100% - 2px);
472
+ right: 4px;
473
+ }
474
+ ` +
475
+ /* Rail caption is a two-row grid (heading + scope line); grid-placing the
476
+ abspos menu makes row 1 its containing block, so 100% means "below the
477
+ trigger row", not "below the whole caption". Spanning both columns keeps
478
+ the base rule's max-width resolving against the full caption width. */
479
+ `.persona-history-view--rail .persona-history-caption .persona-history-menu {
480
+ grid-row: 1 / 2;
481
+ grid-column: 1 / -1;
482
+ top: calc(100% + 2px);
483
+ right: 0;
484
+ }
485
+ .persona-history-view button.persona-history-menu-item {
486
+ display: block;
487
+ width: 100%;
488
+ min-height: 32px;
489
+ padding: 6px 10px;
490
+ border: 0;
491
+ border-radius: 8px;
492
+ background: transparent;
493
+ color: var(--persona-text, #111827);
494
+ font: inherit;
495
+ text-align: left;
496
+ cursor: pointer;
497
+ }
498
+ .persona-history-view button.persona-history-menu-item--danger {
499
+ color: var(--persona-history-danger-fg, var(--persona-palette-colors-error-600, #b91c1c));
500
+ }
501
+ .persona-history-view button.persona-history-menu-item:hover:not(:disabled) {
502
+ background: var(--persona-history-row-hover-bg);
503
+ }
504
+ .persona-history-view .persona-history-row-error {
505
+ display: flex;
506
+ flex-wrap: wrap;
507
+ align-items: center;
508
+ gap: 8px;
509
+ padding: 8px 16px 12px;
510
+ font-size: 13px;
511
+ color: var(--persona-history-danger-fg, var(--persona-palette-colors-error-600, #b91c1c));
512
+ }
513
+
514
+ ` +
515
+ /* --- pagination and states ----------------------------------------------- */
516
+ `.persona-history-view button.persona-history-secondary {
517
+ display: inline-flex;
518
+ align-items: center;
519
+ justify-content: center;
520
+ gap: 8px;
521
+ width: 100%;
522
+ min-height: 44px;
523
+ padding: 10px 16px;
524
+ margin: 0;
525
+ border: 1px solid var(--persona-history-border);
526
+ border-radius: var(--persona-button-radius, var(--persona-radius-lg, 10px));
527
+ background: transparent;
528
+ color: var(--persona-text, #111827);
529
+ font: inherit;
530
+ font-weight: 500;
531
+ cursor: pointer;
532
+ }
533
+ .persona-history-view button.persona-history-secondary:hover:not(:disabled) {
534
+ background: var(--persona-history-row-hover-bg);
535
+ }
536
+ .persona-history-view .persona-history-state {
537
+ display: flex;
538
+ flex-direction: column;
539
+ align-items: flex-start;
540
+ gap: 8px;
541
+ padding: 8px 4px;
542
+ }
543
+ .persona-history-view .persona-history-state-title {
544
+ margin: 0;
545
+ font-size: 14px;
546
+ font-weight: 600;
547
+ color: var(--persona-text, #111827);
548
+ }
549
+ .persona-history-view .persona-history-state-description {
550
+ margin: 0;
551
+ font-size: 13px;
552
+ color: var(--persona-text-muted, #6b7280);
553
+ overflow-wrap: anywhere;
554
+ }
555
+ .persona-history-view button.persona-history-state-action {
556
+ width: auto;
557
+ min-width: 44px;
558
+ }
559
+ .persona-history-view .persona-history-view-loading {
560
+ display: flex;
561
+ flex-direction: column;
562
+ ` +
563
+ /* Show-delay: loads that resolve inside 250ms never flash the skeleton. */
564
+ ` animation: persona-history-skeleton-in 120ms ease-out 250ms both;
565
+ }
566
+ @keyframes persona-history-skeleton-in {
567
+ from { opacity: 0; }
568
+ to { opacity: 1; }
569
+ }
570
+ ` +
571
+ /* Mirrors the row anatomy exactly (same box, head line with the time slot,
572
+ preview under), so the loaded rows land where the skeleton stood. Bar
573
+ height splits the 21px line: text-sized pill, line-spaced rhythm. */
574
+ `.persona-history-view .persona-history-skeleton-row {
575
+ display: flex;
576
+ flex-direction: column;
577
+ justify-content: center;
578
+ gap: 9px;
579
+ min-height: var(--persona-history-row-min-height);
580
+ padding: 10px 16px;
581
+ }
582
+ .persona-history-view .persona-history-skeleton-head {
583
+ display: flex;
584
+ align-items: center;
585
+ justify-content: space-between;
586
+ gap: 8px;
587
+ }
588
+ .persona-history-view .persona-history-skeleton-bar {
589
+ height: 12px;
590
+ border-radius: 999px;
591
+ background: var(--persona-history-skeleton-bg);
592
+ animation: persona-history-pulse 1400ms ease-in-out infinite;
593
+ }
594
+ .persona-history-view .persona-history-skeleton-bar--time {
595
+ flex: 0 0 auto;
596
+ width: 22px;
597
+ }
598
+ .persona-history-view .persona-history-skeleton-bar--preview {
599
+ width: 88%;
600
+ }
601
+ @keyframes persona-history-pulse {
602
+ 0%, 100% { opacity: 1; }
603
+ 50% { opacity: 0.55; }
604
+ }
605
+
606
+ ` +
607
+ /* --- panel presentation -------------------------------------------------- */
608
+ /* One flat, edge-to-edge list. The date headings stay in the DOM for their
609
+ list labelling; rows carry a relative time, so nothing is lost. */
610
+ `.persona-history-view--panel .persona-history-list-region {
611
+ gap: 0;
612
+ }
613
+ .persona-history-view--panel .persona-history-group {
614
+ margin: 0 -16px;
615
+ }
616
+ .persona-history-view--panel button.persona-history-load-more {
617
+ margin-top: 12px;
618
+ }
619
+ ` +
620
+ /* Floating pill over the end of the list: last in flex order, pinned to the
621
+ bottom of the scrolling body, and still in flow so the last row clears it. */
622
+ `.persona-history-view--panel button.persona-history-new {
623
+ order: 1;
624
+ position: sticky;
625
+ bottom: 12px;
626
+ z-index: 1;
627
+ align-self: center;
628
+ width: auto;
629
+ min-height: 40px;
630
+ padding: 10px 16px;
631
+ margin: auto 0 0;
632
+ background: var(--persona-button-primary-bg, var(--persona-primary, #2563eb));
633
+ color: var(--persona-button-primary-fg, var(--persona-text-inverse, #ffffff));
634
+ font-weight: 600;
635
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.18);
636
+ }
637
+
638
+ ` +
639
+ /* --- rail presentation --------------------------------------------------- */
640
+ /* A sidebar of single-line titles on their own surface: no avatar, preview,
641
+ time, divider or edge marker, and 36px rows inset 6px from both edges so
642
+ the hover and selection washes read as rounded chips. The host draws the
643
+ divider, on whichever edge faces the conversation. */
644
+ `.persona-history-view--rail {
645
+ --persona-history-slide: 12px;
646
+ --persona-history-surface-bg: var(--persona-container, #f7f7f8);
647
+ --persona-history-topbar-bg: transparent;
648
+ --persona-history-topbar-min-height: 48px;
649
+ --persona-history-row-min-height: 36px;
650
+ }
651
+ ` +
652
+ /* The rail bar IS the sidebar header: a header-height strip that lines up
653
+ with the conversation column's own header band beside it. Identity leads,
654
+ the collapse toggle takes the inner edge facing the conversation, and there
655
+ is no third track to push the title off the leading edge. */
656
+ `.persona-history-view--rail .persona-history-topbar {
657
+ grid-template-columns: minmax(0, 1fr) auto;
658
+ min-height: var(
659
+ --persona-history-rail-header-min-height,
660
+ var(--persona-header-min-height, 56px)
661
+ );
662
+ padding: 2px 6px;
663
+ background: var(
664
+ --persona-history-rail-header-bg,
665
+ var(--persona-history-surface-bg)
666
+ );
667
+ border-bottom: var(--persona-history-rail-header-border, 0);
668
+ }
669
+ ` +
670
+ /* Identity sits at the leading edge on the rows' 16px text inset, which the
671
+ bar's own 6px padding already covers 6 of. */
672
+ `.persona-history-view--rail .persona-history-heading-group {
673
+ text-align: left;
674
+ padding-left: 10px;
675
+ }
676
+ ` +
677
+ /* A right-docked rail faces the conversation with its LEFT edge, so the
678
+ toggle leads there and the identity trails it, inset from the outer edge. */
679
+ `.persona-history-view--rail-right .persona-history-topbar {
680
+ grid-template-columns: auto minmax(0, 1fr);
681
+ }
682
+ .persona-history-view--rail-right .persona-history-heading-group {
683
+ padding: 0 10px 0 0;
684
+ }
685
+ ` +
686
+ /* The sidebar toggle answers to the 36px rows beside it, not to the 44px
687
+ header controls; the auto tracks above take their width from it. Its color
688
+ answers to the rail surface, not the conversation header: the shared
689
+ icon-button rule reads the header action token, which brand themes tint
690
+ for a colored header band, and that tint has no contrast on the rail. */
691
+ `.persona-history-view--rail .persona-history-topbar button.persona-history-icon-button {
692
+ width: 36px;
693
+ height: 36px;
694
+ min-width: 36px;
695
+ min-height: 36px;
696
+ color: var(--persona-text-muted, #6b7280);
697
+ }
698
+ ` +
699
+ /* Touch has no hover to aim with, so the target goes back to 44px. */
700
+ `@media (pointer: coarse) {
701
+ .persona-history-view--rail .persona-history-topbar button.persona-history-icon-button {
702
+ width: 44px;
703
+ height: 44px;
704
+ min-width: 44px;
705
+ min-height: 44px;
706
+ }
707
+ .persona-history-view button.persona-history-menu-item {
708
+ min-height: 44px;
709
+ padding: 10px 12px;
710
+ }
711
+ .persona-history-view .persona-history-row-preview {
712
+ -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 84px), transparent calc(100% - 36px));
713
+ mask-image: linear-gradient(to right, #000 calc(100% - 84px), transparent calc(100% - 36px));
714
+ }
715
+ .persona-history-view button.persona-history-list-options {
716
+ width: 40px;
717
+ height: 40px;
718
+ min-width: 40px;
719
+ min-height: 40px;
720
+ }
721
+ }
722
+ .persona-history-view--rail .persona-history-title {
723
+ font-family: var(--persona-components-history-railHeader-title-fontFamily, inherit);
724
+ font-size: var(--persona-components-history-railHeader-title-fontSize, 14px);
725
+ font-weight: var(--persona-components-history-railHeader-title-fontWeight, 600);
726
+ line-height: var(--persona-components-history-railHeader-title-lineHeight, inherit);
727
+ letter-spacing: var(--persona-components-history-railHeader-title-letterSpacing, normal);
728
+ color: var(
729
+ --persona-components-history-railHeader-title-color,
730
+ var(--persona-text, #111827)
731
+ );
732
+ }
733
+ ` +
734
+ /* features.history.rail.brand, expanded: the mark leads on the same 16px
735
+ text inset as the rows, the view title follows as the wordmark. */
736
+ `.persona-history-view .persona-history-heading-brand {
737
+ display: flex;
738
+ align-items: center;
739
+ gap: 8px;
740
+ min-width: 0;
741
+ }
742
+ .persona-history-view .persona-history-brand-mark {
743
+ display: flex;
744
+ flex: none;
745
+ align-items: center;
746
+ justify-content: center;
747
+ }
748
+ .persona-history-view .persona-history-brand-mark > img,
749
+ .persona-history-view .persona-history-brand-mark > svg {
750
+ width: 20px;
751
+ height: 20px;
752
+ object-fit: contain;
753
+ }
754
+ .persona-history-view .persona-history-wordmark {
755
+ min-width: 0;
756
+ overflow: hidden;
757
+ color: var(--persona-text, #111827);
758
+ font-size: 14px;
759
+ font-weight: 600;
760
+ text-overflow: ellipsis;
761
+ white-space: nowrap;
762
+ }
763
+ ` +
764
+ /* The same brand is the collapsed toggle's rest face; the glyph under it
765
+ takes over on hover and keyboard focus, so the control still reads as one. */
766
+ `.persona-history-view .persona-history-toggle-brand {
767
+ display: none;
768
+ }
769
+ .persona-history-view--rail-collapsed .persona-history-back--branded .persona-history-toggle-brand {
770
+ display: flex;
771
+ }
772
+ .persona-history-view--rail-collapsed .persona-history-back--branded > svg {
773
+ display: none;
774
+ }
775
+ .persona-history-view--rail-collapsed .persona-history-back--branded:hover .persona-history-toggle-brand,
776
+ .persona-history-view--rail-collapsed .persona-history-back--branded:focus-visible .persona-history-toggle-brand {
777
+ display: none;
778
+ }
779
+ .persona-history-view--rail-collapsed .persona-history-back--branded:hover > svg,
780
+ .persona-history-view--rail-collapsed .persona-history-back--branded:focus-visible > svg {
781
+ display: block;
782
+ }
783
+ ` +
784
+ /* Touch has no hover to bring the glyph up with, so it stays the only face. */
785
+ `@media (pointer: coarse) {
786
+ .persona-history-view--rail-collapsed .persona-history-back--branded .persona-history-toggle-brand {
787
+ display: none;
788
+ }
789
+ .persona-history-view--rail-collapsed .persona-history-back--branded > svg {
790
+ display: block;
791
+ }
792
+ }
793
+ .persona-history-view--rail .persona-history-body {
794
+ gap: 8px;
795
+ padding: 4px 0 12px;
796
+ }
797
+ ` +
798
+ /* Rows and headings carry their own 16px text inset, so everything else in
799
+ the body has to opt into it. */
800
+ `.persona-history-view--rail .persona-history-caption,
801
+ .persona-history-view--rail .persona-history-scope-alert,
802
+ .persona-history-view--rail .persona-history-state {
803
+ padding-right: 16px;
804
+ padding-left: 16px;
805
+ }
806
+ ` +
807
+ /* Rail list header: heading and overflow trigger on the first line, the
808
+ scope caption spanning under them. DOM order is heading, scope, trigger,
809
+ so each cell is placed explicitly. */
810
+ `.persona-history-view--rail .persona-history-caption {
811
+ display: grid;
812
+ grid-template-columns: minmax(0, 1fr) auto;
813
+ /* Explicit rows: the abspos menu is grid-placed into row 1, and abspos
814
+ grid placement only resolves against explicit lines (implicit/auto ends
815
+ fall back to the padding-box edge, i.e. below the scope line). */
816
+ grid-template-rows: auto auto;
817
+ align-items: center;
818
+ row-gap: 2px;
819
+ }
820
+ .persona-history-view--rail .persona-history-conversations-title {
821
+ grid-row: 1;
822
+ grid-column: 1;
823
+ }
824
+ .persona-history-view--rail .persona-history-caption button.persona-history-list-options {
825
+ grid-row: 1;
826
+ grid-column: 2;
827
+ margin-left: 0;
828
+ }
829
+ .persona-history-view--rail .persona-history-scope {
830
+ grid-row: 2;
831
+ grid-column: 1 / -1;
832
+ display: flex;
833
+ align-items: center;
834
+ gap: 6px;
835
+ }
836
+ ` +
837
+ /* The explicit display beats the UA hidden rule, so restate it: attention
838
+ states hide the caption and speak through the alert block instead. */
839
+ `.persona-history-view--rail .persona-history-scope[hidden] {
840
+ display: none;
841
+ }
842
+ .persona-history-view--rail .persona-history-scope-title {
843
+ min-width: 0;
844
+ overflow: hidden;
845
+ text-overflow: ellipsis;
846
+ white-space: nowrap;
847
+ }
848
+ ` +
849
+ /* Device icon only for the browser-only scope; the line is hidden for
850
+ everything but the ambient states. */
851
+ `.persona-history-view--rail .persona-history-scope[data-persona-history-identity="browser_only"] .persona-history-scope-icon {
852
+ display: flex;
853
+ flex: none;
854
+ align-items: center;
855
+ }
856
+ ` +
857
+ /* A nav block above the list closes off with a hairline over the header. */
858
+ `.persona-history-view--rail.persona-history-view--has-nav .persona-history-caption {
859
+ margin-top: 4px;
860
+ padding-top: 12px;
861
+ border-top: 1px solid var(--persona-history-border);
862
+ }
863
+ ` +
864
+ /* New-conversation row: the same geometry as a conversation, icon leading. */
865
+ `.persona-history-view--rail button.persona-history-new {
866
+ width: calc(100% - 12px);
867
+ min-height: 36px;
868
+ padding: 6px 10px;
869
+ margin: 0 6px;
870
+ border-radius: 10px;
871
+ background: transparent;
872
+ color: inherit;
873
+ font-weight: 500;
874
+ }
875
+ .persona-history-view--rail button.persona-history-new:hover:not(:disabled) {
876
+ background: var(--persona-history-row-hover-bg);
877
+ }
878
+ .persona-history-view--rail .persona-history-list-region {
879
+ gap: 24px;
880
+ }
881
+ ` +
882
+ /* Host nav sections. Rail-only, so they take the row geometry unconditionally;
883
+ the footer bucket sinks to the bottom of the body. */
884
+ `.persona-history-view .persona-history-nav {
885
+ display: flex;
886
+ flex-direction: column;
887
+ gap: 2px;
888
+ }
889
+ .persona-history-view .persona-history-nav--footer {
890
+ margin-top: auto;
891
+ }
892
+ ` +
893
+ /* A render-backed section that yielded nothing keeps its heading out too. */
894
+ `.persona-history-view .persona-history-nav[hidden] {
895
+ display: none;
896
+ }
897
+ .persona-history-view button.persona-history-nav-item {
898
+ display: flex;
899
+ align-items: center;
900
+ gap: 8px;
901
+ width: calc(100% - 12px);
902
+ min-height: 36px;
903
+ padding: 6px 10px;
904
+ margin: 0 6px;
905
+ border: 0;
906
+ border-radius: 10px;
907
+ background: transparent;
908
+ color: inherit;
909
+ font: inherit;
910
+ text-align: left;
911
+ cursor: pointer;
912
+ }
913
+ .persona-history-view button.persona-history-nav-item:hover:not(:disabled) {
914
+ background: var(--persona-history-row-hover-bg);
915
+ }
916
+ .persona-history-view .persona-history-nav-icon {
917
+ display: flex;
918
+ flex: none;
919
+ align-items: center;
920
+ justify-content: center;
921
+ width: 20px;
922
+ height: 20px;
923
+ color: var(--persona-text-muted, #6b7280);
924
+ }
925
+ .persona-history-view .persona-history-nav-icon > * {
926
+ width: 20px;
927
+ height: 20px;
928
+ object-fit: contain;
929
+ }
930
+ .persona-history-view .persona-history-nav-label {
931
+ flex: 1 1 auto;
932
+ min-width: 0;
933
+ }
934
+ .persona-history-view .persona-history-nav-badge {
935
+ flex: none;
936
+ padding: 0 6px;
937
+ border-radius: 999px;
938
+ background: var(--persona-history-row-hover-bg);
939
+ color: var(--persona-text-muted, #6b7280);
940
+ font-size: 11px;
941
+ line-height: 18px;
942
+ }
943
+ .persona-history-view--rail .persona-history-group-heading {
944
+ margin: 0 0 6px;
945
+ padding: 0 16px;
946
+ font-size: var(--persona-components-history-groupHeading-fontSize, 13px);
947
+ font-weight: var(--persona-components-history-groupHeading-fontWeight, 500);
948
+ line-height: var(--persona-components-history-groupHeading-lineHeight, 20px);
949
+ }
950
+ .persona-history-view--rail .persona-history-row-avatar,
951
+ .persona-history-view--rail .persona-history-row-preview,
952
+ .persona-history-view--rail time.persona-history-row-time {
953
+ display: none;
954
+ }
955
+ .persona-history-view--rail button.persona-history-row {
956
+ min-height: 36px;
957
+ padding: 6px 10px;
958
+ margin: 0 6px;
959
+ width: calc(100% - 12px);
960
+ border-radius: 10px;
961
+ }
962
+ .persona-history-view--rail .persona-history-row-title {
963
+ font-weight: 400;
964
+ }
965
+ .persona-history-view--rail button.persona-history-row-menu-button {
966
+ right: 10px;
967
+ width: 28px;
968
+ height: 28px;
969
+ min-width: 28px;
970
+ min-height: 28px;
971
+ }
972
+ .persona-history-view--rail .persona-history-skeleton-row {
973
+ padding: 6px 16px;
974
+ }
975
+ .persona-history-view--rail .persona-history-skeleton-bar--preview,
976
+ .persona-history-view--rail .persona-history-skeleton-bar--time {
977
+ display: none;
978
+ }
979
+ ` +
980
+ /* Collapsed rail: an icon column of the expand toggle over an icon-only
981
+ new-conversation square. Everything else is hidden, so the host can carry
982
+ the rail down to 52px. */
983
+ `.persona-history-view--rail-collapsed .persona-history-topbar {
984
+ grid-template-columns: minmax(0, 1fr);
985
+ justify-items: center;
986
+ padding: 2px;
987
+ }
988
+ .persona-history-view--rail-collapsed .persona-history-heading-group,
989
+ .persona-history-view--rail-collapsed .persona-history-body > :not(.persona-history-new):not(.persona-history-nav) {
990
+ display: none;
991
+ }
992
+ .persona-history-view--rail-collapsed button.persona-history-new {
993
+ width: 36px;
994
+ padding: 0;
995
+ margin: 0 auto;
996
+ justify-content: center;
997
+ }
998
+ .persona-history-view--rail-collapsed button.persona-history-new span {
999
+ display: none;
1000
+ }
1001
+ ` +
1002
+ /* Nav sections keep only their icon rows, squared off like the one above. A
1003
+ labelled row with no icon has nothing to show in a 52px column. */
1004
+ `.persona-history-view--rail-collapsed .persona-history-nav .persona-history-group-heading,
1005
+ .persona-history-view--rail-collapsed button.persona-history-nav-item:not(.persona-history-nav-item--icon),
1006
+ .persona-history-view--rail-collapsed .persona-history-nav-label,
1007
+ .persona-history-view--rail-collapsed .persona-history-nav-badge {
1008
+ display: none;
1009
+ }
1010
+ .persona-history-view--rail-collapsed button.persona-history-nav-item {
1011
+ width: 36px;
1012
+ padding: 0;
1013
+ margin: 0 auto;
1014
+ justify-content: center;
1015
+ }
1016
+
1017
+ ` +
1018
+ /* --- shell-hosted top bar ------------------------------------------------ */
1019
+ /* Panel keeps ONE bar: the shell header stays, its own children are suppressed,
1020
+ and this bar mounts inside it. Unscoped: these nodes are outside the view. */
1021
+ `[data-persona-history-suppressed] { display: none !important; }
1022
+ .persona-history-header-host {
1023
+ display: flex;
1024
+ flex: 1 1 auto;
1025
+ align-self: stretch;
1026
+ align-items: center;
1027
+ min-width: 0;
1028
+ }
1029
+ ` +
1030
+ /* Shell-owned rail host: only its width animates, and only on a collapse. */
1031
+ `.persona-history-rail-host {
1032
+ transition: flex-basis 180ms cubic-bezier(0, 0, 0.2, 1);
1033
+ }
1034
+ ` +
1035
+ /* The header supplies padding and background; the bar only fills it. Its
1036
+ controls follow the header's sizing tokens so the band height never
1037
+ changes between surfaces; the 40px coarse floor matches
1038
+ .persona-header-control. */
1039
+ `.persona-history-topbar.persona-history-topbar--shell {
1040
+ flex: 1 1 auto;
1041
+ min-width: 0;
1042
+ grid-template-columns: var(--persona-header-control-size, 44px) minmax(0, 1fr) var(--persona-header-control-size, 44px);
1043
+ }
1044
+ .persona-history-topbar--shell button.persona-history-icon-button {
1045
+ width: var(--persona-header-control-size, 44px);
1046
+ height: var(--persona-header-control-size, 44px);
1047
+ min-width: var(--persona-header-control-size, 44px);
1048
+ min-height: var(--persona-header-control-size, 44px);
1049
+ }
1050
+ .persona-history-topbar--shell button.persona-history-icon-button svg {
1051
+ width: var(--persona-header-control-icon-size, 20px);
1052
+ height: var(--persona-header-control-icon-size, 20px);
1053
+ }
1054
+ @media (pointer: coarse) {
1055
+ .persona-history-topbar--shell button.persona-history-icon-button {
1056
+ min-width: 40px;
1057
+ min-height: 40px;
1058
+ }
1059
+ }
1060
+ ` +
1061
+ /* The bar never animates; only its arrival in the shell header does. */
1062
+ `.persona-history-topbar--shell.persona-history-topbar--shell-enter {
1063
+ animation: persona-history-header-fade 120ms cubic-bezier(0, 0, 0.2, 1) both;
1064
+ }
1065
+ @keyframes persona-history-header-fade {
1066
+ from { opacity: 0; }
1067
+ to { opacity: 1; }
1068
+ }
1069
+
1070
+ @media (prefers-reduced-motion: reduce) {
1071
+ .persona-history-view--enter .persona-history-body { animation: none; }
1072
+ .persona-history-topbar--shell.persona-history-topbar--shell-enter {
1073
+ animation: none;
1074
+ }
1075
+ .persona-history-view .persona-history-skeleton-bar { animation: none; }
1076
+ .persona-history-rail-host { transition: none; }
1077
+ }
1078
+ `;