@rohansguliani/mux-chat-ui 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1237 @@
1
+ import { className, createComponent, delegateEvents, effect, insert, memo, render, setAttribute, setStyleProperty, style, template, use } from "solid-js/web";
2
+ import { For, Match, Show, Switch, batch, createComputed, createEffect, createMemo, createSignal, on, onCleanup, onMount, untrack } from "solid-js";
3
+ import { createAppClient, createChatSession, createMemoryStore, createRuntimeTransport, isSessionStreaming, sessionPermissions, sessionQuestions, sessionTurns, textSubmission } from "@rohansguliani/mux-chat-core";
4
+ import createDOMPurify from "dompurify";
5
+ import { Marked } from "marked";
6
+ //#endregion
7
+ //#region src/styles.ts
8
+ /** Mux's stylesheets in its cascade order, then the embed's layout on top. */
9
+ var styles = [
10
+ "/* Synced from Mux frontend/src/ui/styles/theme.css @ 37d6096b450cb33dfe9d7112e9d4ff75975d20b2. Do not edit; run npm run sync-styles. */\n:host {\n --font-family-sans: \"Inter\", \"Inter Fallback\";\n --font-family-sans--font-feature-settings: \"ss03\" 1;\n --font-family-mono: \"IBM Plex Mono\", \"IBM Plex Mono Fallback\";\n --font-family-mono--font-feature-settings: \"ss01\" 1;\n\n --font-size-small: 13px;\n --font-size-base: 14px;\n --font-size-large: 16px;\n --font-size-x-large: 20px;\n --font-weight-regular: 400;\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --line-height-normal: 130%;\n --line-height-large: 150%;\n --line-height-x-large: 180%;\n --line-height-2x-large: 200%;\n --letter-spacing-normal: 0;\n --letter-spacing-tight: -0.16px;\n --letter-spacing-tightest: -0.32px;\n --paragraph-spacing-base: 0;\n\n --spacing: 0.25rem;\n\n /* Label track for transcript activity rows (tool/thinking/context triggers).\n Content-sized, so each label sits one 8px gap from its detail text.\n Set a fixed length here to align column 2 across rows instead. */\n --activity-label-width: max-content;\n\n --breakpoint-sm: 40rem;\n --breakpoint-md: 48rem;\n --breakpoint-lg: 64rem;\n --breakpoint-xl: 80rem;\n --breakpoint-2xl: 96rem;\n\n --container-3xs: 16rem;\n --container-2xs: 18rem;\n --container-xs: 20rem;\n --container-sm: 24rem;\n --container-md: 28rem;\n --container-lg: 32rem;\n --container-xl: 36rem;\n --container-2xl: 42rem;\n --container-3xl: 48rem;\n --container-4xl: 56rem;\n --container-5xl: 64rem;\n --container-6xl: 72rem;\n --container-7xl: 80rem;\n\n --radius-xs: 0.125rem;\n --radius-sm: 0.25rem;\n --radius-md: 0.375rem;\n --radius-lg: 0.5rem;\n --radius-xl: 0.625rem;\n\n --shadow-xs:\n 0 1px 2px -0.5px light-dark(hsl(0 0% 0% / 0.04), hsl(0 0% 0% / 0.06)),\n 0 0.5px 1.5px 0 light-dark(hsl(0 0% 0% / 0.025), hsl(0 0% 0% / 0.08)),\n 0 1px 3px 0 light-dark(hsl(0 0% 0% / 0.05), hsl(0 0% 0% / 0.1));\n --shadow-sm:\n 0 1px 3px 0 light-dark(hsl(0 0% 0% / 0.06), hsl(0 0% 0% / 0.12)),\n 0 1px 2px -1px light-dark(hsl(0 0% 0% / 0.06), hsl(0 0% 0% / 0.12));\n --shadow-md:\n 0 6px 12px -2px light-dark(hsl(0 0% 0% / 0.075), hsl(0 0% 0% / 0.1)),\n 0 4px 8px -2px light-dark(hsl(0 0% 0% / 0.075), hsl(0 0% 0% / 0.15)),\n 0 1px 2px light-dark(hsl(0 0% 0% / 0.1), hsl(0 0% 0% / 0.15));\n --shadow-lg:\n 0 16px 48px -6px light-dark(hsl(0 0% 0% / 0.05), hsl(0 0% 0% / 0.15)),\n 0 6px 12px -2px light-dark(hsl(0 0% 0% / 0.025), hsl(0 0% 0% / 0.1)),\n 0 1px 2.5px light-dark(hsl(0 0% 0% / 0.025), hsl(0 0% 0% / 0.1));\n --shadow-xl:\n 0 24px 64px -12px light-dark(hsl(0 0% 0% / 0.12), hsl(0 0% 0% / 0.4)),\n 0 8px 20px -6px light-dark(hsl(0 0% 0% / 0.06), hsl(0 0% 0% / 0.2));\n --shadow-xxs-border: 0 0 0 0.5px var(--border-weak-base, rgba(0, 0, 0, 0.07));\n --shadow-xs-border:\n 0 0 0 1px var(--border-base, rgba(11, 6, 0, 0.2)), 0 1px 2px -1px rgba(19, 16, 16, 0.04),\n 0 1px 2px 0 rgba(19, 16, 16, 0.06), 0 1px 3px 0 rgba(19, 16, 16, 0.08);\n --shadow-xs-border-base:\n 0 0 0 1px var(--border-weak-base, rgba(17, 0, 0, 0.12)), 0 1px 2px -1px rgba(19, 16, 16, 0.04),\n 0 1px 2px 0 rgba(19, 16, 16, 0.06), 0 1px 3px 0 rgba(19, 16, 16, 0.08);\n --shadow-xs-border-select:\n 0 0 0 3px var(--border-weak-selected, rgba(1, 103, 255, 0.29)),\n 0 0 0 1px var(--border-selected, rgba(0, 74, 255, 0.99)), 0 1px 2px -1px rgba(19, 16, 16, 0.25),\n 0 1px 2px 0 rgba(19, 16, 16, 0.08), 0 1px 3px 0 rgba(19, 16, 16, 0.12);\n --shadow-xs-border-focus:\n 0 0 0 1px var(--border-base, rgba(11, 6, 0, 0.2)), 0 1px 2px -1px rgba(19, 16, 16, 0.25),\n 0 1px 2px 0 rgba(19, 16, 16, 0.08), 0 1px 3px 0 rgba(19, 16, 16, 0.12), 0 0 0 2px var(--background-weak, #f1f0f0),\n 0 0 0 3px var(--border-selected, rgba(0, 74, 255, 0.99));\n --shadow-xs-border-hover:\n 0 0 0 1px var(--border-weak-selected, rgba(0, 112, 255, 0.22)), 0 1px 2px -1px rgba(19, 16, 16, 0.04),\n 0 1px 2px 0 rgba(19, 16, 16, 0.06), 0 1px 3px 0 rgba(19, 16, 16, 0.08);\n --shadow-xs-border-critical-base: 0 0 0 1px var(--border-critical-selected, #fc543a);\n --shadow-xs-border-critical-focus:\n 0 0 0 3px var(--border-critical-weak, rgba(251, 34, 0, 0.18)), 0 0 0 1px var(--border-critical-selected, #fc543a),\n 0 1px 2px -1px rgba(19, 16, 16, 0.25), 0 1px 2px 0 rgba(19, 16, 16, 0.08), 0 1px 3px 0 rgba(19, 16, 16, 0.12);\n --shadow-lg-border-base:\n 0 0 0 1px var(--border-weak-base, rgba(0, 0, 0, 0.07)), 0 36px 80px 0 rgba(0, 0, 0, 0.03),\n 0 13.141px 29.201px 0 rgba(0, 0, 0, 0.04), 0 6.38px 14.177px 0 rgba(0, 0, 0, 0.05),\n 0 3.127px 6.95px 0 rgba(0, 0, 0, 0.06), 0 1.237px 2.748px 0 rgba(0, 0, 0, 0.09);\n\n color-scheme: light;\n --text-mix-blend-mode: multiply;\n\n /* OC-2 fallback variables (light) */\n --background-base: #f8f8f8;\n --background-weak: #f3f3f3;\n --background-strong: #fcfcfc;\n --background-stronger: #fcfcfc;\n --surface-base: rgba(0, 0, 0, 0.031);\n --base: rgba(0, 0, 0, 0.034);\n --surface-base-hover: rgba(0, 0, 0, 0.059);\n --surface-base-active: rgba(0, 0, 0, 0.051);\n --surface-base-interactive-active: rgba(3, 76, 255, 0.09);\n --base2: rgba(0, 0, 0, 0.034);\n --base3: rgba(0, 0, 0, 0.034);\n --surface-inset-base: rgba(0, 0, 0, 0.034);\n --surface-inset-base-hover: rgba(0, 0, 0, 0.055);\n --surface-inset-strong: rgba(0, 0, 0, 0.09);\n --surface-inset-strong-hover: rgba(0, 0, 0, 0.09);\n --surface-raised-base: rgba(0, 0, 0, 0.031);\n --surface-float-base: #161616;\n --surface-float-base-hover: #1c1c1c;\n --surface-raised-base-hover: rgba(0, 0, 0, 0.051);\n --surface-raised-base-active: rgba(0, 0, 0, 0.09);\n --surface-raised-strong: #fcfcfc;\n --surface-raised-strong-hover: #ffffff;\n --surface-raised-stronger: #ffffff;\n --surface-raised-stronger-hover: #ffffff;\n --surface-weak: rgba(0, 0, 0, 0.051);\n --surface-weaker: rgba(0, 0, 0, 0.071);\n --surface-strong: #ffffff;\n --surface-stronger-non-alpha: var(--surface-raised-stronger-non-alpha);\n --surface-raised-stronger-non-alpha: #ffffff;\n --surface-panel: var(--surface-raised-stronger-non-alpha);\n --surface-panel-base: var(--surface-raised-stronger-non-alpha);\n --surface-brand-base: #dcde8d;\n --surface-brand-hover: #d0d283;\n --surface-interactive-base: #ecf3ff;\n --surface-interactive-hover: #e0eaff;\n --surface-interactive-weak: #f7faff;\n --surface-interactive-weak-hover: #ecf3ff;\n --surface-success-base: #dbfed7;\n --surface-success-weak: #f0feee;\n --surface-success-strong: #12c905;\n --surface-warning-base: #fcf3cb;\n --surface-warning-weak: #fdfaec;\n --surface-warning-strong: #fbdd46;\n --surface-critical-base: #fff2f0;\n --surface-critical-weak: #fff8f6;\n --surface-critical-strong: #fc533a;\n --surface-info-base: #fdecfe;\n --surface-info-weak: #fef7ff;\n --surface-info-strong: #a753ae;\n --surface-diff-unchanged-base: #ffffff00;\n --surface-diff-skip-base: #f8f8f8;\n --surface-diff-hidden-base: #eaf4ff;\n --surface-diff-hidden-weak: #f6faff;\n --surface-diff-hidden-weaker: #fbfdff;\n --surface-diff-hidden-strong: #cae3ff;\n --surface-diff-hidden-stronger: #2090f5;\n --surface-diff-add-base: #e3fae1;\n --surface-diff-add-weak: #f4fcf3;\n --surface-diff-add-weaker: #fbfefb;\n --surface-diff-add-strong: #c2eebf;\n --surface-diff-add-stronger: #9ff29a;\n --surface-diff-delete-base: #feefeb;\n --surface-diff-delete-weak: #fff8f6;\n --surface-diff-delete-weaker: #fffcfb;\n --surface-diff-delete-strong: #fdc3b7;\n --surface-diff-delete-stronger: #fc533a;\n --input-base: #fcfcfc;\n --input-hover: #f8f8f8;\n --input-active: #fcfdff;\n --input-selected: #e0eaff;\n --input-focus: #fcfdff;\n --input-disabled: #ededed;\n --text-base: #6f6f6f;\n --text-weak: #8f8f8f;\n --text-weaker: #c7c7c7;\n --text-strong: #171717;\n --text-invert-base: #f8f8f8;\n --text-invert-weak: #f3f3f3;\n --text-invert-weaker: #ededed;\n --text-invert-strong: #fcfcfc;\n --text-interactive-base: #034cff;\n --text-subtle: var(--text-weak);\n --accent: var(--text-interactive-base);\n --accent-base: var(--text-interactive-base);\n --danger-base: #ed4831;\n --danger-muted: rgba(237, 72, 49, 0.12);\n --text-danger-base: var(--danger-base);\n --text-text-danger-base: var(--danger-base);\n --text-on-brand-base: rgba(0, 0, 0, 0.574);\n --text-on-interactive-base: #fcfcfc;\n --text-on-interactive-weak: rgba(0, 0, 0, 0.574);\n --text-on-success-base: #2dba26;\n --text-on-critical-base: #ed4831;\n --text-on-critical-weak: #fe806a;\n --text-on-critical-strong: #601a0f;\n --text-on-warning-base: rgba(0, 0, 0, 0.574);\n --text-on-info-base: rgba(0, 0, 0, 0.574);\n --text-diff-add-base: #3a8437;\n --text-diff-delete-base: #ed4831;\n --text-diff-delete-strong: #601a0f;\n --text-diff-add-strong: #1d3e1c;\n --text-on-info-weak: rgba(0, 0, 0, 0.453);\n --text-on-info-strong: rgba(0, 0, 0, 0.915);\n --text-on-warning-weak: rgba(0, 0, 0, 0.453);\n --text-on-warning-strong: rgba(0, 0, 0, 0.915);\n --text-on-success-weak: #96ec8e;\n --text-on-success-strong: #044202;\n --text-on-brand-weak: rgba(0, 0, 0, 0.453);\n --text-on-brand-weaker: rgba(0, 0, 0, 0.232);\n --text-on-brand-strong: rgba(0, 0, 0, 0.915);\n --button-primary-base: #171717;\n --button-secondary-base: #fcfcfc;\n --button-secondary-hover: #f8f8f8;\n --button-ghost-hover: rgba(0, 0, 0, 0.031);\n --button-ghost-hover2: rgba(0, 0, 0, 0.051);\n --border-base: rgba(0, 0, 0, 0.162);\n --border-hover: rgba(0, 0, 0, 0.236);\n --border-active: rgba(0, 0, 0, 0.46);\n --border-selected: rgba(3, 76, 255, 0.99);\n --border-disabled: rgba(0, 0, 0, 0.236);\n --border-focus: rgba(0, 0, 0, 0.46);\n --border-weak-base: #e5e5e5;\n --border-strong-base: rgba(0, 0, 0, 0.151);\n --border-strong-hover: rgba(0, 0, 0, 0.232);\n --border-strong-active: rgba(0, 0, 0, 0.151);\n --border-strong-selected: rgba(3, 76, 255, 0.31);\n --border-strong-disabled: rgba(0, 0, 0, 0.118);\n --border-strong-focus: rgba(0, 0, 0, 0.151);\n --border-weak-hover: rgba(0, 0, 0, 0.118);\n --border-weak-active: rgba(0, 0, 0, 0.151);\n --border-weak-selected: rgba(3, 76, 255, 0.24);\n --border-weak-disabled: rgba(0, 0, 0, 0.118);\n --border-weak-focus: rgba(0, 0, 0, 0.151);\n --border-weaker-base: #f0f0f0;\n --border-weaker-hover: rgba(0, 0, 0, 0.075);\n --border-weaker-active: rgba(0, 0, 0, 0.118);\n --border-weaker-selected: rgba(3, 76, 255, 0.16);\n --border-weaker-disabled: rgba(0, 0, 0, 0.034);\n --border-weaker-focus: rgba(0, 0, 0, 0.118);\n --border-interactive-base: #a3c1fd;\n --border-interactive-hover: #7ea9ff;\n --border-interactive-active: #034cff;\n --border-interactive-selected: #034cff;\n --border-interactive-disabled: #c7c7c7;\n --border-interactive-focus: #034cff;\n --border-success-base: #96ec8e;\n --border-success-hover: #7add71;\n --border-success-selected: #12c905;\n --border-warning-base: #e8d479;\n --border-warning-hover: #d8c158;\n --border-warning-selected: #fbdd46;\n --border-critical-base: #fdc3b7;\n --border-critical-hover: #ffa796;\n --border-critical-selected: #fc533a;\n --border-info-base: #f4bdf8;\n --border-info-hover: #e6a8ea;\n --border-info-selected: #a753ae;\n --border-color: #ffffff;\n --icon-base: #8f8f8f;\n --icon-hover: #6f6f6f;\n --icon-active: #171717;\n --icon-selected: #171717;\n --icon-disabled: #c7c7c7;\n --icon-focus: #171717;\n --icon-invert-base: #ffffff;\n --icon-weak-base: #dbdbdb;\n --icon-weak-hover: #c7c7c7;\n --icon-weak-active: #8f8f8f;\n --icon-weak-selected: #858585;\n --icon-weak-disabled: #e2e2e2;\n --icon-weak-focus: #8f8f8f;\n --icon-strong-base: #171717;\n --icon-strong-hover: #151313;\n --icon-strong-active: #020202;\n --icon-strong-selected: #020202;\n --icon-strong-disabled: #c7c7c7;\n --icon-strong-focus: #020202;\n --icon-brand-base: #171717;\n --icon-interactive-base: #034cff;\n --icon-success-base: #7add71;\n --icon-success-hover: #4cc944;\n --icon-success-active: #078901;\n --icon-warning-base: #ebb76e;\n --icon-warning-hover: #da9e40;\n --icon-warning-active: #95671b;\n --icon-critical-base: #ed4831;\n --icon-critical-hover: #ca2d17;\n --icon-critical-active: #601a0f;\n --icon-info-base: #e6a8ea;\n --icon-info-hover: #d58cda;\n --icon-info-active: #9b4da1;\n --icon-on-brand-base: rgba(0, 0, 0, 0.574);\n --icon-on-brand-hover: rgba(0, 0, 0, 0.915);\n --icon-on-brand-selected: rgba(0, 0, 0, 0.915);\n --icon-on-interactive-base: #fcfcfc;\n --icon-agent-plan-base: #a753ae;\n --icon-agent-docs-base: #fcb239;\n --icon-agent-ask-base: #2090f5;\n --icon-agent-build-base: #034cff;\n --icon-on-success-base: rgba(18, 201, 5, 0.9);\n --icon-on-success-hover: rgba(45, 186, 38, 0.9);\n --icon-on-success-selected: rgba(7, 137, 1, 0.9);\n --icon-on-warning-base: rgba(252, 178, 57, 0.9);\n --icon-on-warning-hover: rgba(239, 167, 46, 0.9);\n --icon-on-warning-selected: rgba(149, 103, 27, 0.9);\n --icon-on-critical-base: rgba(252, 83, 58, 0.9);\n --icon-on-critical-hover: rgba(237, 72, 49, 0.9);\n --icon-on-critical-selected: rgba(202, 45, 23, 0.9);\n --icon-on-info-base: #a753ae;\n --icon-on-info-hover: rgba(155, 73, 162, 0.9);\n --icon-on-info-selected: rgba(155, 77, 161, 0.9);\n --icon-diff-add-base: #3a8437;\n --icon-diff-add-hover: #1d3e1c;\n --icon-diff-add-active: #1d3e1c;\n --icon-diff-delete-base: #ed4831;\n --icon-diff-delete-hover: #ca2d17;\n --icon-diff-modified-base: #ff8c00;\n --syntax-comment: var(--text-weak);\n --syntax-regexp: var(--text-base);\n --syntax-string: #006656;\n --syntax-keyword: var(--text-weak);\n --syntax-primitive: #fb4804;\n --syntax-operator: var(--text-base);\n --syntax-variable: var(--text-strong);\n --syntax-property: #ed6dc8;\n --syntax-type: #596600;\n --syntax-constant: #007b80;\n --syntax-punctuation: var(--text-base);\n --syntax-object: var(--text-strong);\n --syntax-success: #2dba26;\n --syntax-warning: #efa72e;\n --syntax-critical: #ed4831;\n --syntax-info: #0092a8;\n --syntax-diff-add: #3a8437;\n --syntax-diff-delete: #ca2d17;\n --syntax-diff-unknown: #ff0000;\n --markdown-heading: #d68c27;\n --markdown-text: #1a1a1a;\n --markdown-link: #3b7dd8;\n --markdown-link-text: #318795;\n --markdown-code: #3d9a57;\n --markdown-block-quote: #b0851f;\n --markdown-emph: #b0851f;\n --markdown-strong: #d68c27;\n --markdown-horizontal-rule: #8a8a8a;\n --markdown-list-item: #3b7dd8;\n --markdown-list-enumeration: #318795;\n --markdown-image: #3b7dd8;\n --markdown-image-text: #318795;\n --markdown-code-block: #1a1a1a;\n --avatar-background-pink: #feeef8;\n --avatar-background-mint: #e1fbf4;\n --avatar-background-orange: #fff1e7;\n --avatar-background-purple: #f9f1fe;\n --avatar-background-cyan: #e7f9fb;\n --avatar-background-lime: #eefadc;\n --avatar-text-pink: #cd1d8d;\n --avatar-text-mint: #147d6f;\n --avatar-text-orange: #ed5f00;\n --avatar-text-purple: #8445bc;\n --avatar-text-cyan: #0894b3;\n --avatar-text-lime: #5d770d;\n --text-stronger: #171717;\n\n\n}\n\n@media (prefers-color-scheme: dark) {\n :host(:not([data-theme=\"light\"])) {\n color-scheme: dark;\n --text-mix-blend-mode: plus-lighter;\n\n /* OC-2 fallback variables (dark) */\n --background-base: #101010;\n --background-weak: #1e1e1e;\n --background-strong: #121212;\n --background-stronger: #151515;\n --surface-base: rgba(255, 255, 255, 0.031);\n --base: rgba(255, 255, 255, 0.034);\n --surface-base-hover: rgba(255, 255, 255, 0.039);\n --surface-base-active: rgba(255, 255, 255, 0.059);\n --surface-base-interactive-active: rgba(3, 76, 255, 0.125);\n --base2: rgba(255, 255, 255, 0.034);\n --base3: rgba(255, 255, 255, 0.034);\n --surface-inset-base: rgba(0, 0, 0, 0.5);\n --surface-inset-base-hover: rgba(0, 0, 0, 0.5);\n --surface-inset-strong: rgba(0, 0, 0, 0.8);\n --surface-inset-strong-hover: rgba(0, 0, 0, 0.8);\n --surface-raised-base: rgba(255, 255, 255, 0.059);\n --surface-float-base: #161616;\n --surface-float-base-hover: #1c1c1c;\n --surface-raised-base-hover: rgba(255, 255, 255, 0.078);\n --surface-raised-base-active: rgba(255, 255, 255, 0.102);\n --surface-raised-strong: rgba(255, 255, 255, 0.078);\n --surface-raised-strong-hover: rgba(255, 255, 255, 0.129);\n --surface-raised-stronger: rgba(255, 255, 255, 0.129);\n --surface-raised-stronger-hover: rgba(255, 255, 255, 0.169);\n --surface-weak: rgba(255, 255, 255, 0.078);\n --surface-weaker: rgba(255, 255, 255, 0.102);\n --surface-strong: rgba(255, 255, 255, 0.169);\n --surface-stronger-non-alpha: var(--surface-raised-stronger-non-alpha);\n --surface-raised-stronger-non-alpha: #1c1c1c;\n --surface-panel: var(--surface-raised-stronger-non-alpha);\n --surface-panel-base: var(--surface-raised-stronger-non-alpha);\n --surface-brand-base: #fab283;\n --surface-brand-hover: #eda779;\n --surface-interactive-base: #091f52;\n --surface-interactive-hover: #091f52;\n --surface-interactive-weak: #0b1730;\n --surface-interactive-weak-hover: #ecf3ff;\n --surface-success-base: #062d04;\n --surface-success-weak: #0a1e08;\n --surface-success-strong: #12c905;\n --surface-warning-base: #fdf3cf;\n --surface-warning-weak: #fdfaed;\n --surface-warning-strong: #fcd53a;\n --surface-critical-base: #1f0603;\n --surface-critical-weak: #28110c;\n --surface-critical-strong: #fc533a;\n --surface-info-base: #feecfe;\n --surface-info-weak: #fdf7fe;\n --surface-info-strong: #edb2f1;\n --surface-diff-unchanged-base: #161616;\n --surface-diff-skip-base: #00000000;\n --surface-diff-hidden-base: #0c1928;\n --surface-diff-hidden-weak: #09131d;\n --surface-diff-hidden-weaker: #082542;\n --surface-diff-hidden-strong: #073966;\n --surface-diff-hidden-stronger: #8ec2fc;\n --surface-diff-add-base: #1a2919;\n --surface-diff-add-weak: #1f351e;\n --surface-diff-add-weaker: #1a2919;\n --surface-diff-add-strong: #264024;\n --surface-diff-add-stronger: #9bcd97;\n --surface-diff-delete-base: #42120b;\n --surface-diff-delete-weak: #580f06;\n --surface-diff-delete-weaker: #42120b;\n --surface-diff-delete-strong: #6a1206;\n --surface-diff-delete-stronger: #faa494;\n --input-base: #1c1c1c;\n --input-hover: #1c1c1c;\n --input-active: #091123;\n --input-selected: #0b1730;\n --input-focus: #091123;\n --input-disabled: #282828;\n --text-base: rgba(255, 255, 255, 0.618);\n --text-weak: rgba(255, 255, 255, 0.422);\n --text-weaker: rgba(255, 255, 255, 0.284);\n --text-strong: rgba(255, 255, 255, 0.936);\n --text-invert-base: #a0a0a0;\n --text-invert-weak: #707070;\n --text-invert-weaker: #505050;\n --text-invert-strong: #ededed;\n --text-interactive-base: #9dbefe;\n --text-subtle: var(--text-weak);\n --accent: var(--text-interactive-base);\n --accent-base: var(--text-interactive-base);\n --danger-base: #fc533a;\n --danger-muted: rgba(252, 83, 58, 0.16);\n --text-danger-base: var(--danger-base);\n --text-text-danger-base: var(--danger-base);\n --text-on-brand-base: rgba(255, 255, 255, 0.603);\n --text-on-interactive-base: #ededed;\n --text-on-interactive-weak: rgba(255, 255, 255, 0.603);\n --text-on-success-base: #12c905;\n --text-on-critical-base: #fc533a;\n --text-on-critical-weak: #b72d1a;\n --text-on-critical-strong: #ffe0da;\n --text-on-warning-base: rgba(255, 255, 255, 0.603);\n --text-on-info-base: rgba(255, 255, 255, 0.603);\n --text-diff-add-base: #9bcd97;\n --text-diff-delete-base: #fc533a;\n --text-diff-delete-strong: #ffe0da;\n --text-diff-add-strong: #4a7348;\n --text-on-info-weak: rgba(255, 255, 255, 0.404);\n --text-on-info-strong: rgba(255, 255, 255, 0.928);\n --text-on-warning-weak: rgba(255, 255, 255, 0.404);\n --text-on-warning-strong: rgba(255, 255, 255, 0.928);\n --text-on-success-weak: #127d0d;\n --text-on-success-strong: #bafdb3;\n --text-on-brand-weak: rgba(255, 255, 255, 0.404);\n --text-on-brand-weaker: rgba(255, 255, 255, 0.266);\n --text-on-brand-strong: rgba(255, 255, 255, 0.928);\n --button-primary-base: #ededed;\n --button-secondary-base: #1c1c1c;\n --button-secondary-hover: rgba(255, 255, 255, 0.039);\n --button-ghost-hover: rgba(255, 255, 255, 0.031);\n --button-ghost-hover2: rgba(255, 255, 255, 0.059);\n --border-base: rgba(255, 255, 255, 0.195);\n --border-hover: rgba(255, 255, 255, 0.284);\n --border-active: rgba(255, 255, 255, 0.418);\n --border-selected: #9dbefe;\n --border-disabled: rgba(255, 255, 255, 0.284);\n --border-focus: rgba(255, 255, 255, 0.418);\n --border-weak-base: #282828;\n --border-strong-base: rgba(255, 255, 255, 0.266);\n --border-strong-hover: rgba(255, 255, 255, 0.266);\n --border-strong-active: rgba(255, 255, 255, 0.266);\n --border-strong-selected: rgba(3, 76, 255, 0.62);\n --border-strong-disabled: rgba(255, 255, 255, 0.138);\n --border-strong-focus: rgba(255, 255, 255, 0.266);\n --border-weak-hover: rgba(255, 255, 255, 0.181);\n --border-weak-active: rgba(255, 255, 255, 0.266);\n --border-weak-selected: rgba(3, 76, 255, 0.62);\n --border-weak-disabled: rgba(255, 255, 255, 0.138);\n --border-weak-focus: rgba(255, 255, 255, 0.266);\n --border-weaker-base: #202020;\n --border-weaker-hover: rgba(255, 255, 255, 0.084);\n --border-weaker-active: rgba(255, 255, 255, 0.138);\n --border-weaker-selected: rgba(3, 76, 255, 0.32);\n --border-weaker-disabled: rgba(255, 255, 255, 0.034);\n --border-weaker-focus: rgba(255, 255, 255, 0.138);\n --border-interactive-base: #a3c1fd;\n --border-interactive-hover: #7ea9ff;\n --border-interactive-active: #034cff;\n --border-interactive-selected: #034cff;\n --border-interactive-disabled: #505050;\n --border-interactive-focus: #034cff;\n --border-success-base: #96ec8e;\n --border-success-hover: #7add71;\n --border-success-selected: #12c905;\n --border-warning-base: #e9d282;\n --border-warning-hover: #dac063;\n --border-warning-selected: #fcd53a;\n --border-critical-base: #6a1206;\n --border-critical-hover: #952414;\n --border-critical-selected: #fc533a;\n --border-info-base: #eac5ec;\n --border-info-hover: #dab1dd;\n --border-info-selected: #edb2f1;\n --border-color: #ffffff;\n --icon-base: #7e7e7e;\n --icon-hover: #a0a0a0;\n --icon-active: #ededed;\n --icon-selected: #ededed;\n --icon-disabled: #3e3e3e;\n --icon-focus: #ededed;\n --icon-invert-base: #161616;\n --icon-weak-base: #343434;\n --icon-weak-hover: #d9d9d9;\n --icon-weak-active: #c8c8c8;\n --icon-weak-selected: #707070;\n --icon-weak-disabled: #ededed;\n --icon-weak-focus: #707070;\n --icon-strong-base: #ededed;\n --icon-strong-hover: #f6f3f3;\n --icon-strong-active: #fcfcfc;\n --icon-strong-selected: #fdfcfc;\n --icon-strong-disabled: #3e3e3e;\n --icon-strong-focus: #fdfcfc;\n --icon-brand-base: #ffffff;\n --icon-interactive-base: #034cff;\n --icon-success-base: #12c905;\n --icon-success-hover: #35c02d;\n --icon-success-active: #4de144;\n --icon-warning-base: #fbb73c;\n --icon-warning-hover: #885e08;\n --icon-warning-active: #f1b13f;\n --icon-critical-base: #fc533a;\n --icon-critical-hover: #faa494;\n --icon-critical-active: #ffe0da;\n --icon-info-base: #68446b;\n --icon-info-hover: #815484;\n --icon-info-active: #dfa7e3;\n --icon-on-brand-base: rgba(255, 255, 255, 0.603);\n --icon-on-brand-hover: rgba(255, 255, 255, 0.928);\n --icon-on-brand-selected: rgba(255, 255, 255, 0.928);\n --icon-on-interactive-base: #ededed;\n --icon-agent-plan-base: #edb2f1;\n --icon-agent-docs-base: #fbb73c;\n --icon-agent-ask-base: #2090f5;\n --icon-agent-build-base: #9dbefe;\n --icon-on-success-base: rgba(18, 201, 5, 0.9);\n --icon-on-success-hover: rgba(53, 192, 45, 0.9);\n --icon-on-success-selected: rgba(77, 225, 68, 0.9);\n --icon-on-warning-base: rgba(251, 183, 60, 0.9);\n --icon-on-warning-hover: rgba(245, 178, 56, 0.9);\n --icon-on-warning-selected: rgba(241, 177, 63, 0.9);\n --icon-on-critical-base: rgba(252, 83, 58, 0.9);\n --icon-on-critical-hover: rgba(245, 79, 54, 0.9);\n --icon-on-critical-selected: rgba(250, 164, 148, 0.9);\n --icon-on-info-base: #edb2f1;\n --icon-on-info-hover: rgba(231, 173, 235, 0.9);\n --icon-on-info-selected: rgba(223, 167, 227, 0.9);\n --icon-diff-add-base: #9bcd97;\n --icon-diff-add-hover: #c3f9bf;\n --icon-diff-add-active: #9bcd97;\n --icon-diff-delete-base: #fc533a;\n --icon-diff-delete-hover: #f54f36;\n --icon-diff-modified-base: #ffba92;\n --syntax-comment: var(--text-weak);\n --syntax-regexp: var(--text-base);\n --syntax-string: #00ceb9;\n --syntax-keyword: var(--text-weak);\n --syntax-primitive: #ffba92;\n --syntax-operator: var(--text-weak);\n --syntax-variable: var(--text-strong);\n --syntax-property: #ff9ae2;\n --syntax-type: #ecf58c;\n --syntax-constant: #93e9f6;\n --syntax-punctuation: var(--text-weak);\n --syntax-object: var(--text-strong);\n --syntax-success: #35c02d;\n --syntax-warning: #f5b238;\n --syntax-critical: #f54f36;\n --syntax-info: #93e9f6;\n --syntax-diff-add: #9bcd97;\n --syntax-diff-delete: #faa494;\n --syntax-diff-unknown: #ff0000;\n --markdown-heading: #9d7cd8;\n --markdown-text: #eeeeee;\n --markdown-link: #fab283;\n --markdown-link-text: #56b6c2;\n --markdown-code: #7fd88f;\n --markdown-block-quote: #e5c07b;\n --markdown-emph: #e5c07b;\n --markdown-strong: #f5a742;\n --markdown-horizontal-rule: #808080;\n --markdown-list-item: #fab283;\n --markdown-list-enumeration: #56b6c2;\n --markdown-image: #fab283;\n --markdown-image-text: #56b6c2;\n --markdown-code-block: #eeeeee;\n --avatar-background-pink: #501b3f;\n --avatar-background-mint: #033a34;\n --avatar-background-orange: #5f2a06;\n --avatar-background-purple: #432155;\n --avatar-background-cyan: #0f3058;\n --avatar-background-lime: #2b3711;\n --avatar-text-pink: #e34ba9;\n --avatar-text-mint: #95f3d9;\n --avatar-text-orange: #ff802b;\n --avatar-text-purple: #9d5bd2;\n --avatar-text-cyan: #369eff;\n --avatar-text-lime: #c4f042;\n --text-stronger: rgba(255, 255, 255, 0.936);\n }\n}\n:host([data-theme=\"dark\"]) {\n color-scheme: dark;\n --text-mix-blend-mode: plus-lighter;\n\n /* OC-2 fallback variables (dark) */\n --background-base: #101010;\n --background-weak: #1e1e1e;\n --background-strong: #121212;\n --background-stronger: #151515;\n --surface-base: rgba(255, 255, 255, 0.031);\n --base: rgba(255, 255, 255, 0.034);\n --surface-base-hover: rgba(255, 255, 255, 0.039);\n --surface-base-active: rgba(255, 255, 255, 0.059);\n --surface-base-interactive-active: rgba(3, 76, 255, 0.125);\n --base2: rgba(255, 255, 255, 0.034);\n --base3: rgba(255, 255, 255, 0.034);\n --surface-inset-base: rgba(0, 0, 0, 0.5);\n --surface-inset-base-hover: rgba(0, 0, 0, 0.5);\n --surface-inset-strong: rgba(0, 0, 0, 0.8);\n --surface-inset-strong-hover: rgba(0, 0, 0, 0.8);\n --surface-raised-base: rgba(255, 255, 255, 0.059);\n --surface-float-base: #161616;\n --surface-float-base-hover: #1c1c1c;\n --surface-raised-base-hover: rgba(255, 255, 255, 0.078);\n --surface-raised-base-active: rgba(255, 255, 255, 0.102);\n --surface-raised-strong: rgba(255, 255, 255, 0.078);\n --surface-raised-strong-hover: rgba(255, 255, 255, 0.129);\n --surface-raised-stronger: rgba(255, 255, 255, 0.129);\n --surface-raised-stronger-hover: rgba(255, 255, 255, 0.169);\n --surface-weak: rgba(255, 255, 255, 0.078);\n --surface-weaker: rgba(255, 255, 255, 0.102);\n --surface-strong: rgba(255, 255, 255, 0.169);\n --surface-stronger-non-alpha: var(--surface-raised-stronger-non-alpha);\n --surface-raised-stronger-non-alpha: #1c1c1c;\n --surface-panel: var(--surface-raised-stronger-non-alpha);\n --surface-panel-base: var(--surface-raised-stronger-non-alpha);\n --surface-brand-base: #fab283;\n --surface-brand-hover: #eda779;\n --surface-interactive-base: #091f52;\n --surface-interactive-hover: #091f52;\n --surface-interactive-weak: #0b1730;\n --surface-interactive-weak-hover: #ecf3ff;\n --surface-success-base: #062d04;\n --surface-success-weak: #0a1e08;\n --surface-success-strong: #12c905;\n --surface-warning-base: #fdf3cf;\n --surface-warning-weak: #fdfaed;\n --surface-warning-strong: #fcd53a;\n --surface-critical-base: #1f0603;\n --surface-critical-weak: #28110c;\n --surface-critical-strong: #fc533a;\n --surface-info-base: #feecfe;\n --surface-info-weak: #fdf7fe;\n --surface-info-strong: #edb2f1;\n --surface-diff-unchanged-base: #161616;\n --surface-diff-skip-base: #00000000;\n --surface-diff-hidden-base: #0c1928;\n --surface-diff-hidden-weak: #09131d;\n --surface-diff-hidden-weaker: #082542;\n --surface-diff-hidden-strong: #073966;\n --surface-diff-hidden-stronger: #8ec2fc;\n --surface-diff-add-base: #1a2919;\n --surface-diff-add-weak: #1f351e;\n --surface-diff-add-weaker: #1a2919;\n --surface-diff-add-strong: #264024;\n --surface-diff-add-stronger: #9bcd97;\n --surface-diff-delete-base: #42120b;\n --surface-diff-delete-weak: #580f06;\n --surface-diff-delete-weaker: #42120b;\n --surface-diff-delete-strong: #6a1206;\n --surface-diff-delete-stronger: #faa494;\n --input-base: #1c1c1c;\n --input-hover: #1c1c1c;\n --input-active: #091123;\n --input-selected: #0b1730;\n --input-focus: #091123;\n --input-disabled: #282828;\n --text-base: rgba(255, 255, 255, 0.618);\n --text-weak: rgba(255, 255, 255, 0.422);\n --text-weaker: rgba(255, 255, 255, 0.284);\n --text-strong: rgba(255, 255, 255, 0.936);\n --text-invert-base: #a0a0a0;\n --text-invert-weak: #707070;\n --text-invert-weaker: #505050;\n --text-invert-strong: #ededed;\n --text-interactive-base: #9dbefe;\n --text-subtle: var(--text-weak);\n --accent: var(--text-interactive-base);\n --accent-base: var(--text-interactive-base);\n --danger-base: #fc533a;\n --danger-muted: rgba(252, 83, 58, 0.16);\n --text-danger-base: var(--danger-base);\n --text-text-danger-base: var(--danger-base);\n --text-on-brand-base: rgba(255, 255, 255, 0.603);\n --text-on-interactive-base: #ededed;\n --text-on-interactive-weak: rgba(255, 255, 255, 0.603);\n --text-on-success-base: #12c905;\n --text-on-critical-base: #fc533a;\n --text-on-critical-weak: #b72d1a;\n --text-on-critical-strong: #ffe0da;\n --text-on-warning-base: rgba(255, 255, 255, 0.603);\n --text-on-info-base: rgba(255, 255, 255, 0.603);\n --text-diff-add-base: #9bcd97;\n --text-diff-delete-base: #fc533a;\n --text-diff-delete-strong: #ffe0da;\n --text-diff-add-strong: #4a7348;\n --text-on-info-weak: rgba(255, 255, 255, 0.404);\n --text-on-info-strong: rgba(255, 255, 255, 0.928);\n --text-on-warning-weak: rgba(255, 255, 255, 0.404);\n --text-on-warning-strong: rgba(255, 255, 255, 0.928);\n --text-on-success-weak: #127d0d;\n --text-on-success-strong: #bafdb3;\n --text-on-brand-weak: rgba(255, 255, 255, 0.404);\n --text-on-brand-weaker: rgba(255, 255, 255, 0.266);\n --text-on-brand-strong: rgba(255, 255, 255, 0.928);\n --button-primary-base: #ededed;\n --button-secondary-base: #1c1c1c;\n --button-secondary-hover: rgba(255, 255, 255, 0.039);\n --button-ghost-hover: rgba(255, 255, 255, 0.031);\n --button-ghost-hover2: rgba(255, 255, 255, 0.059);\n --border-base: rgba(255, 255, 255, 0.195);\n --border-hover: rgba(255, 255, 255, 0.284);\n --border-active: rgba(255, 255, 255, 0.418);\n --border-selected: #9dbefe;\n --border-disabled: rgba(255, 255, 255, 0.284);\n --border-focus: rgba(255, 255, 255, 0.418);\n --border-weak-base: #282828;\n --border-strong-base: rgba(255, 255, 255, 0.266);\n --border-strong-hover: rgba(255, 255, 255, 0.266);\n --border-strong-active: rgba(255, 255, 255, 0.266);\n --border-strong-selected: rgba(3, 76, 255, 0.62);\n --border-strong-disabled: rgba(255, 255, 255, 0.138);\n --border-strong-focus: rgba(255, 255, 255, 0.266);\n --border-weak-hover: rgba(255, 255, 255, 0.181);\n --border-weak-active: rgba(255, 255, 255, 0.266);\n --border-weak-selected: rgba(3, 76, 255, 0.62);\n --border-weak-disabled: rgba(255, 255, 255, 0.138);\n --border-weak-focus: rgba(255, 255, 255, 0.266);\n --border-weaker-base: #202020;\n --border-weaker-hover: rgba(255, 255, 255, 0.084);\n --border-weaker-active: rgba(255, 255, 255, 0.138);\n --border-weaker-selected: rgba(3, 76, 255, 0.32);\n --border-weaker-disabled: rgba(255, 255, 255, 0.034);\n --border-weaker-focus: rgba(255, 255, 255, 0.138);\n --border-interactive-base: #a3c1fd;\n --border-interactive-hover: #7ea9ff;\n --border-interactive-active: #034cff;\n --border-interactive-selected: #034cff;\n --border-interactive-disabled: #505050;\n --border-interactive-focus: #034cff;\n --border-success-base: #96ec8e;\n --border-success-hover: #7add71;\n --border-success-selected: #12c905;\n --border-warning-base: #e9d282;\n --border-warning-hover: #dac063;\n --border-warning-selected: #fcd53a;\n --border-critical-base: #6a1206;\n --border-critical-hover: #952414;\n --border-critical-selected: #fc533a;\n --border-info-base: #eac5ec;\n --border-info-hover: #dab1dd;\n --border-info-selected: #edb2f1;\n --border-color: #ffffff;\n --icon-base: #7e7e7e;\n --icon-hover: #a0a0a0;\n --icon-active: #ededed;\n --icon-selected: #ededed;\n --icon-disabled: #3e3e3e;\n --icon-focus: #ededed;\n --icon-invert-base: #161616;\n --icon-weak-base: #343434;\n --icon-weak-hover: #d9d9d9;\n --icon-weak-active: #c8c8c8;\n --icon-weak-selected: #707070;\n --icon-weak-disabled: #ededed;\n --icon-weak-focus: #707070;\n --icon-strong-base: #ededed;\n --icon-strong-hover: #f6f3f3;\n --icon-strong-active: #fcfcfc;\n --icon-strong-selected: #fdfcfc;\n --icon-strong-disabled: #3e3e3e;\n --icon-strong-focus: #fdfcfc;\n --icon-brand-base: #ffffff;\n --icon-interactive-base: #034cff;\n --icon-success-base: #12c905;\n --icon-success-hover: #35c02d;\n --icon-success-active: #4de144;\n --icon-warning-base: #fbb73c;\n --icon-warning-hover: #885e08;\n --icon-warning-active: #f1b13f;\n --icon-critical-base: #fc533a;\n --icon-critical-hover: #faa494;\n --icon-critical-active: #ffe0da;\n --icon-info-base: #68446b;\n --icon-info-hover: #815484;\n --icon-info-active: #dfa7e3;\n --icon-on-brand-base: rgba(255, 255, 255, 0.603);\n --icon-on-brand-hover: rgba(255, 255, 255, 0.928);\n --icon-on-brand-selected: rgba(255, 255, 255, 0.928);\n --icon-on-interactive-base: #ededed;\n --icon-agent-plan-base: #edb2f1;\n --icon-agent-docs-base: #fbb73c;\n --icon-agent-ask-base: #2090f5;\n --icon-agent-build-base: #9dbefe;\n --icon-on-success-base: rgba(18, 201, 5, 0.9);\n --icon-on-success-hover: rgba(53, 192, 45, 0.9);\n --icon-on-success-selected: rgba(77, 225, 68, 0.9);\n --icon-on-warning-base: rgba(251, 183, 60, 0.9);\n --icon-on-warning-hover: rgba(245, 178, 56, 0.9);\n --icon-on-warning-selected: rgba(241, 177, 63, 0.9);\n --icon-on-critical-base: rgba(252, 83, 58, 0.9);\n --icon-on-critical-hover: rgba(245, 79, 54, 0.9);\n --icon-on-critical-selected: rgba(250, 164, 148, 0.9);\n --icon-on-info-base: #edb2f1;\n --icon-on-info-hover: rgba(231, 173, 235, 0.9);\n --icon-on-info-selected: rgba(223, 167, 227, 0.9);\n --icon-diff-add-base: #9bcd97;\n --icon-diff-add-hover: #c3f9bf;\n --icon-diff-add-active: #9bcd97;\n --icon-diff-delete-base: #fc533a;\n --icon-diff-delete-hover: #f54f36;\n --icon-diff-modified-base: #ffba92;\n --syntax-comment: var(--text-weak);\n --syntax-regexp: var(--text-base);\n --syntax-string: #00ceb9;\n --syntax-keyword: var(--text-weak);\n --syntax-primitive: #ffba92;\n --syntax-operator: var(--text-weak);\n --syntax-variable: var(--text-strong);\n --syntax-property: #ff9ae2;\n --syntax-type: #ecf58c;\n --syntax-constant: #93e9f6;\n --syntax-punctuation: var(--text-weak);\n --syntax-object: var(--text-strong);\n --syntax-success: #35c02d;\n --syntax-warning: #f5b238;\n --syntax-critical: #f54f36;\n --syntax-info: #93e9f6;\n --syntax-diff-add: #9bcd97;\n --syntax-diff-delete: #faa494;\n --syntax-diff-unknown: #ff0000;\n --markdown-heading: #9d7cd8;\n --markdown-text: #eeeeee;\n --markdown-link: #fab283;\n --markdown-link-text: #56b6c2;\n --markdown-code: #7fd88f;\n --markdown-block-quote: #e5c07b;\n --markdown-emph: #e5c07b;\n --markdown-strong: #f5a742;\n --markdown-horizontal-rule: #808080;\n --markdown-list-item: #fab283;\n --markdown-list-enumeration: #56b6c2;\n --markdown-image: #fab283;\n --markdown-image-text: #56b6c2;\n --markdown-code-block: #eeeeee;\n --avatar-background-pink: #501b3f;\n --avatar-background-mint: #033a34;\n --avatar-background-orange: #5f2a06;\n --avatar-background-purple: #432155;\n --avatar-background-cyan: #0f3058;\n --avatar-background-lime: #2b3711;\n --avatar-text-pink: #e34ba9;\n --avatar-text-mint: #95f3d9;\n --avatar-text-orange: #ff802b;\n --avatar-text-purple: #9d5bd2;\n --avatar-text-cyan: #369eff;\n --avatar-text-lime: #c4f042;\n --text-stronger: rgba(255, 255, 255, 0.936);\n }\n",
11
+ "/* Synced from Mux frontend/src/ui/styles/animations.css @ 37d6096b450cb33dfe9d7112e9d4ff75975d20b2. Do not edit; run npm run sync-styles. */\n:host {\n --animate-pulse: pulse-opacity 2s ease-in-out infinite;\n --animate-pulse-scale: pulse-scale 1.2s ease-in-out infinite;\n}\n\n@keyframes pulse-opacity {\n 0%,\n 100% {\n opacity: 0.4;\n }\n 50% {\n opacity: 1;\n }\n}\n\n@keyframes pulse-scale {\n 0%,\n 100% {\n transform: scale(1);\n }\n 50% {\n transform: scale(0.6666667);\n }\n}\n\n@keyframes pulse-opacity-dim {\n 0%,\n 100% {\n opacity: 0.15;\n }\n 50% {\n opacity: 0.35;\n }\n}\n\n@keyframes fadeUp {\n from {\n opacity: 0;\n transform: translateY(5px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.fade-up-text {\n animation: fadeUp 0.4s ease-out forwards;\n opacity: 0;\n\n &:nth-child(1) {\n animation-delay: 0.1s;\n }\n &:nth-child(2) {\n animation-delay: 0.2s;\n }\n &:nth-child(3) {\n animation-delay: 0.3s;\n }\n &:nth-child(4) {\n animation-delay: 0.4s;\n }\n &:nth-child(5) {\n animation-delay: 0.5s;\n }\n &:nth-child(6) {\n animation-delay: 0.6s;\n }\n &:nth-child(7) {\n animation-delay: 0.7s;\n }\n &:nth-child(8) {\n animation-delay: 0.8s;\n }\n &:nth-child(9) {\n animation-delay: 0.9s;\n }\n &:nth-child(10) {\n animation-delay: 1s;\n }\n &:nth-child(11) {\n animation-delay: 1.1s;\n }\n &:nth-child(12) {\n animation-delay: 1.2s;\n }\n &:nth-child(13) {\n animation-delay: 1.3s;\n }\n &:nth-child(14) {\n animation-delay: 1.4s;\n }\n &:nth-child(15) {\n animation-delay: 1.5s;\n }\n &:nth-child(16) {\n animation-delay: 1.6s;\n }\n &:nth-child(17) {\n animation-delay: 1.7s;\n }\n &:nth-child(18) {\n animation-delay: 1.8s;\n }\n &:nth-child(19) {\n animation-delay: 1.9s;\n }\n &:nth-child(20) {\n animation-delay: 2s;\n }\n &:nth-child(21) {\n animation-delay: 2.1s;\n }\n &:nth-child(22) {\n animation-delay: 2.2s;\n }\n &:nth-child(23) {\n animation-delay: 2.3s;\n }\n &:nth-child(24) {\n animation-delay: 2.4s;\n }\n &:nth-child(25) {\n animation-delay: 2.5s;\n }\n &:nth-child(26) {\n animation-delay: 2.6s;\n }\n &:nth-child(27) {\n animation-delay: 2.7s;\n }\n &:nth-child(28) {\n animation-delay: 2.8s;\n }\n &:nth-child(29) {\n animation-delay: 2.9s;\n }\n &:nth-child(30) {\n animation-delay: 3s;\n }\n}\n",
12
+ "/* Synced from Mux frontend/src/ui/components/icon-button.css @ 37d6096b450cb33dfe9d7112e9d4ff75975d20b2. Do not edit; run npm run sync-styles. */\n[data-component=\"icon-button\"] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--radius-sm);\n text-decoration: none;\n user-select: none;\n aspect-ratio: 1;\n flex-shrink: 0;\n\n &[data-variant=\"primary\"] {\n background-color: var(--icon-strong-base);\n\n [data-slot=\"icon-svg\"] {\n /* color: var(--icon-weak-base); */\n color: var(--icon-invert-base);\n\n /* &:hover:not(:disabled) { */\n /* color: var(--icon-weak-hover); */\n /* } */\n /* &:active:not(:disabled) { */\n /* color: var(--icon-strong-active); */\n /* } */\n }\n\n @media (hover: hover) {\n &:hover:not(:disabled) {\n background-color: var(--icon-strong-hover);\n }\n }\n &:focus:not(:disabled) {\n background-color: var(--icon-strong-focus);\n }\n &:active:not(:disabled) {\n background-color: var(--icon-strong-active);\n }\n &:disabled {\n background-color: var(--icon-strong-disabled);\n\n [data-slot=\"icon-svg\"] {\n color: var(--icon-invert-base);\n }\n }\n }\n\n &[data-variant=\"secondary\"] {\n border: transparent;\n background-color: var(--button-secondary-base);\n color: var(--text-strong);\n box-shadow: var(--shadow-xs-border-base);\n\n @media (hover: hover) {\n &:hover:not(:disabled) {\n background-color: var(--button-secondary-hover);\n }\n }\n &:focus:not(:disabled) {\n background-color: var(--button-secondary-base);\n }\n &:focus-visible:not(:active) {\n background-color: var(--button-secondary-base);\n box-shadow: var(--shadow-xs-border-focus);\n }\n &:focus-visible:active {\n box-shadow: none;\n }\n &:active:not(:disabled) {\n background-color: var(--button-secondary-base);\n }\n\n [data-slot=\"icon-svg\"] {\n color: var(--icon-strong-base);\n }\n\n &:disabled {\n background-color: var(--icon-strong-disabled);\n color: var(--icon-invert-base);\n cursor: not-allowed;\n }\n }\n\n &[data-variant=\"ghost\"] {\n background-color: transparent;\n /* color: var(--icon-base); */\n\n [data-slot=\"icon-svg\"] {\n color: var(--icon-base);\n }\n\n @media (hover: hover) {\n &:hover:not(:disabled) {\n background-color: var(--surface-base-hover);\n\n /* [data-slot=\"icon-svg\"] { */\n /* color: var(--icon-hover); */\n /* } */\n }\n }\n &:focus-visible:not(:disabled) {\n background-color: var(--surface-base-hover);\n }\n &:active:not(:disabled) {\n background-color: var(--surface-base-active);\n /* [data-slot=\"icon-svg\"] { */\n /* color: var(--icon-active); */\n /* } */\n }\n &:selected:not(:disabled) {\n background-color: var(--surface-base-active);\n /* [data-slot=\"icon-svg\"] { */\n /* color: var(--icon-selected); */\n /* } */\n }\n &:disabled {\n color: var(--icon-invert-base);\n cursor: not-allowed;\n }\n }\n\n &[data-size=\"normal\"] {\n width: 24px;\n height: 24px;\n\n font-size: var(--font-size-small);\n line-height: var(--line-height-large);\n gap: calc(var(--spacing) * 0.5);\n }\n\n &[data-size=\"small\"] {\n width: 20px;\n height: 20px;\n }\n\n &[data-size=\"large\"] {\n height: 32px;\n /* padding: 0 8px 0 6px; */\n gap: 8px;\n\n /* text-12-medium */\n font-family: var(--font-family-sans);\n font-size: var(--font-size-small);\n font-style: normal;\n font-weight: var(--font-weight-medium);\n line-height: var(--line-height-large); /* 166.667% */\n letter-spacing: var(--letter-spacing-normal);\n }\n\n &:focus {\n outline: none;\n }\n}\n\n@media (prefers-reduced-motion: no-preference) {\n [data-component=\"icon-button\"][data-icon=\"stop\"] [data-slot=\"icon-svg\"] rect {\n transform-origin: center;\n transform-box: fill-box;\n animation: stop-pulse 1.8s ease-in-out infinite;\n }\n}\n\n@keyframes stop-pulse {\n 0%,\n 100% {\n transform: scale(0.95);\n }\n 50% {\n transform: scale(1.12);\n }\n}\n\n[data-component=\"icon-button\"].titlebar-icon {\n width: 32px;\n height: 24px;\n aspect-ratio: auto;\n}\n\n[data-component=\"icon-button\"].titlebar-icon[data-variant=\"ghost\"][aria-expanded=\"true\"] {\n background-color: var(--surface-raised-base-active);\n}\n\n[data-component=\"icon-button\"].titlebar-icon[data-variant=\"ghost\"][aria-expanded=\"true\"] [data-slot=\"icon-svg\"] {\n color: var(--icon-strong-base);\n}\n\n@media (hover: hover) {\n [data-component=\"icon-button\"].titlebar-icon[data-variant=\"ghost\"][aria-expanded=\"true\"]:hover:not(:disabled) {\n background-color: var(--surface-raised-base-active);\n }\n}\n",
13
+ "/* Synced from Mux frontend/src/ui/components/spinner.css @ 37d6096b450cb33dfe9d7112e9d4ff75975d20b2. Do not edit; run npm run sync-styles. */\n[data-component=\"spinner\"] {\n color: inherit;\n flex-shrink: 0;\n width: 18px;\n aspect-ratio: 1;\n}\n",
14
+ "/* Synced from Mux frontend/src/ui/components/collapsible.css @ 37d6096b450cb33dfe9d7112e9d4ff75975d20b2. Do not edit; run npm run sync-styles. */\n[data-slot=\"collapsible-collapse\"] {\n min-height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n\n [data-component=\"icon-button\"] {\n width: 28px;\n height: 28px;\n\n [data-slot=\"icon-svg\"] {\n transform: rotate(180deg);\n }\n }\n}\n\n[data-component=\"collapsible\"] {\n width: 100%;\n display: flex;\n flex-direction: column;\n background-color: transparent;\n border: none;\n transition: background-color 0.15s ease;\n border-radius: var(--radius-md);\n overflow: visible;\n\n &.tool-collapsible {\n gap: 8px;\n }\n\n [data-slot=\"collapsible-trigger\"]:has(\n > [data-layout=\"activity-row\"]\n ) {\n min-height: 28px;\n height: auto;\n }\n\n [data-slot=\"collapsible-trigger\"] {\n width: 100%;\n display: flex;\n height: 32px;\n padding: 0;\n align-items: center;\n align-self: stretch;\n cursor: default;\n user-select: none;\n color: var(--text-base);\n /* Triggers render as <button>, which still defaults to centered text. */\n text-align: start;\n\n [data-slot=\"collapsible-arrow\"] {\n opacity: 0;\n transition: opacity 0.15s ease;\n will-change: opacity;\n transform: translateZ(0);\n }\n\n [data-slot=\"collapsible-arrow-icon\"] {\n display: inline-flex;\n color: var(--icon-weaker);\n transform: translateZ(0) rotate(-90deg);\n transition: transform 0.15s ease;\n will-change: transform;\n }\n\n &:hover [data-slot=\"collapsible-arrow\"] {\n opacity: 1;\n }\n\n /* text-12-medium */\n font-family: var(--font-family-sans);\n font-size: var(--font-size-small);\n font-style: normal;\n font-weight: var(--font-weight-medium);\n line-height: var(--line-height-large); /* 166.667% */\n letter-spacing: var(--letter-spacing-normal);\n\n /* &:hover { */\n /* background-color: var(--surface-base); */\n /* } */\n &:focus-visible {\n outline: none;\n background-color: var(--surface-raised-base-hover);\n }\n &[data-disabled] {\n cursor: not-allowed;\n }\n\n [data-slot=\"collapsible-arrow\"] {\n flex-shrink: 0;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n\n &[data-size=\"compact\"] {\n width: 16px;\n height: 16px;\n }\n }\n }\n\n [data-slot=\"collapsible-trigger\"][aria-expanded=\"true\"] {\n [data-slot=\"collapsible-arrow\"] {\n opacity: 1;\n }\n\n [data-slot=\"collapsible-arrow-icon\"] {\n transform: translateZ(0) rotate(0deg);\n }\n }\n\n [data-slot=\"collapsible-content\"] {\n overflow: hidden;\n\n &[data-expanded] {\n overflow: visible;\n }\n }\n\n &[data-variant=\"ghost\"] {\n background-color: transparent;\n border: none;\n\n > [data-slot=\"collapsible-trigger\"] {\n background-color: transparent;\n border: none;\n padding: 0;\n\n /* &:hover { */\n /* color: var(--text-strong); */\n /* } */\n &:focus-visible {\n outline: none;\n background-color: var(--surface-raised-base-hover);\n }\n &[data-disabled] {\n cursor: not-allowed;\n }\n }\n }\n\n &[data-variant=\"ghost\"][data-scope=\"filetree\"] {\n > [data-slot=\"collapsible-trigger\"] {\n height: 24px;\n }\n }\n}\n",
15
+ "/* Synced from Mux frontend/src/ui/components/basic-tool.css @ 37d6096b450cb33dfe9d7112e9d4ff75975d20b2. Do not edit; run npm run sync-styles. */\n/* [data-component=\"tool-trigger\"] {\n content-visibility: auto;\n} */\n[data-component=\"tool-trigger\"][data-layout=\"activity-row\"] {\n width: fit-content;\n max-width: 100%;\n min-width: 0;\n display: grid;\n grid-template-columns: var(--activity-label-width) minmax(0, auto) auto auto;\n column-gap: 8px;\n align-items: baseline;\n justify-content: start;\n\n [data-slot=\"basic-tool-tool-trigger-content\"],\n [data-slot=\"basic-tool-tool-info\"],\n [data-slot=\"basic-tool-tool-info-structured\"],\n [data-slot=\"basic-tool-tool-info-main\"] {\n display: contents;\n }\n\n [data-slot=\"basic-tool-tool-title\"] {\n grid-column: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n [data-slot=\"basic-tool-tool-detail\"] {\n grid-column: 2;\n min-width: 0;\n max-width: 100%;\n overflow: hidden;\n }\n\n [data-slot=\"basic-tool-tool-action\"],\n [data-component=\"tool-action\"] {\n grid-column: 3;\n }\n\n > [data-slot=\"collapsible-arrow\"] {\n grid-column: 3;\n align-self: center;\n }\n\n &:has([data-slot=\"basic-tool-tool-action\"], [data-component=\"tool-action\"])\n > [data-slot=\"collapsible-arrow\"] {\n grid-column: 4;\n }\n\n [data-slot=\"basic-tool-tool-indicator\"] {\n width: 16px;\n height: 16px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n\n [data-component=\"spinner\"] {\n width: 16px;\n height: 16px;\n }\n }\n\n [data-slot=\"basic-tool-tool-spinner\"] {\n width: 16px;\n height: 16px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: var(--text-weak);\n\n [data-component=\"spinner\"] {\n width: 16px;\n height: 16px;\n }\n }\n\n [data-slot=\"icon-svg\"] {\n flex-shrink: 0;\n }\n\n [data-slot=\"basic-tool-tool-info\"] {\n display: contents;\n font-size: var(--font-size-base);\n }\n\n [data-slot=\"basic-tool-tool-info-structured\"],\n [data-slot=\"basic-tool-tool-info-main\"] {\n display: contents;\n }\n\n [data-slot=\"basic-tool-tool-title\"] {\n flex-shrink: 0;\n font-family: var(--font-family-sans);\n font-size: var(--font-size-base);\n font-style: normal;\n font-weight: var(--font-weight-medium);\n line-height: var(--line-height-large);\n letter-spacing: var(--letter-spacing-normal);\n color: var(--text-strong);\n\n &.capitalize {\n text-transform: capitalize;\n }\n\n &.agent-title {\n color: var(--text-strong);\n font-weight: var(--font-weight-medium);\n }\n }\n\n [data-slot=\"basic-tool-tool-detail\"] {\n display: block;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n direction: ltr;\n unicode-bidi: isolate;\n\n > :not(:first-child) {\n margin-left: 8px;\n }\n }\n\n [data-slot=\"basic-tool-tool-subtitle\"] {\n min-width: 0;\n font-family: var(--font-family-sans);\n font-variant-numeric: tabular-nums;\n font-size: var(--font-size-base);\n font-style: normal;\n font-weight: var(--font-weight-regular);\n line-height: var(--line-height-large);\n letter-spacing: var(--letter-spacing-normal);\n color: var(--text-base);\n\n &.webfetch-url {\n display: block;\n max-width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--font-size-small);\n }\n\n &.clickable {\n cursor: pointer;\n text-decoration: underline;\n transition: color 0.15s ease;\n\n &:hover {\n color: var(--text-base);\n }\n }\n }\n\n [data-slot=\"basic-tool-tool-arg\"] {\n flex-shrink: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: var(--font-family-sans);\n font-variant-numeric: tabular-nums;\n font-size: var(--font-size-base);\n font-style: normal;\n font-weight: var(--font-weight-regular);\n line-height: var(--line-height-large);\n letter-spacing: var(--letter-spacing-normal);\n color: var(--text-base);\n }\n\n [data-slot=\"basic-tool-tool-action\"] {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n }\n}\n\n/* Consecutive tool rows sit flush; a delegation card needs its own breathing room.\n Cards stop short of the full prose width so two short lines are not boxed\n inside a mostly empty frame. */\n[data-component=\"task-supervision\"] {\n width: 100%;\n max-width: 40rem;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding-block: 4px;\n}\n\n[data-component=\"task-tool-card\"] {\n width: 100%;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 4px;\n border-radius: 6px;\n border: 1px solid var(--border-weak-base, rgba(255, 255, 255, 0.08));\n background: color-mix(in srgb, var(--background-base) 92%, transparent);\n transition:\n border-color 0.15s ease,\n background-color 0.15s ease,\n color 0.15s ease;\n\n [data-slot=\"task-tool-body\"] {\n flex: 1 1 auto;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: inherit;\n color: inherit;\n text-decoration: none;\n }\n\n a[data-slot=\"task-tool-body\"] {\n cursor: pointer;\n }\n\n [data-slot=\"task-tool-info\"] {\n flex: 1 1 auto;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n [data-slot=\"task-tool-heading\"] {\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n font-family: var(--font-family-sans);\n font-size: var(--font-size-base);\n line-height: var(--line-height-large);\n letter-spacing: var(--letter-spacing-normal);\n }\n\n [data-slot=\"task-tool-description\"] {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--text-strong);\n font-weight: var(--font-weight-regular);\n }\n\n [data-slot=\"task-tool-meta\"] {\n min-width: 0;\n display: flex;\n align-items: baseline;\n white-space: nowrap;\n font-family: var(--font-family-sans);\n font-size: var(--font-size-small);\n line-height: var(--line-height-large);\n color: var(--text-weak);\n\n > * {\n flex-shrink: 0;\n }\n\n > * + *::before {\n content: \"·\";\n margin-inline: 6px;\n color: var(--text-weaker);\n }\n\n /* The model label is last and gives way on narrow layouts. */\n > :last-child:not(:first-child) {\n flex-shrink: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n }\n\n [data-slot=\"task-tool-state\"]:is([data-state=\"pending\"], [data-state=\"queued\"], [data-state=\"running\"]) {\n color: var(--text-interactive-base);\n }\n\n [data-slot=\"task-tool-state\"][data-state=\"error\"] {\n color: var(--text-danger-base);\n }\n\n [data-component=\"task-tool-spinner\"] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n\n [data-component=\"spinner\"] {\n width: 16px;\n height: 16px;\n }\n }\n\n [data-component=\"task-tool-action\"] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: var(--icon-weak);\n opacity: 0;\n transition:\n opacity 0.15s ease,\n color 0.15s ease;\n }\n\n [data-component=\"task-tool-title\"] {\n flex-shrink: 0;\n font-weight: var(--font-weight-medium);\n text-transform: capitalize;\n }\n\n > [data-component=\"button\"] {\n flex-shrink: 0;\n margin-inline-end: 8px;\n }\n\n &:hover,\n &:focus-within {\n background: color-mix(in srgb, var(--background-stronger) 88%, transparent);\n\n [data-component=\"task-tool-action\"] {\n opacity: 1;\n }\n }\n\n @media (hover: none) {\n [data-component=\"task-tool-action\"] {\n opacity: 1;\n }\n }\n}\n\n[data-component=\"task-supervision\"] > [data-slot=\"task-tool-failure\"] {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 3;\n overflow: hidden;\n padding-inline: 12px;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n font-size: var(--font-size-small);\n line-height: var(--line-height-large);\n color: var(--text-base);\n}\n\n[data-component=\"task-supervision\"] > [data-slot=\"task-tool-status-error\"] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding-inline: 12px;\n font-size: var(--font-size-small);\n line-height: var(--line-height-large);\n color: var(--text-weak);\n}\n",
16
+ "/* Synced from Mux frontend/src/ui/components/text-shimmer.css @ 37d6096b450cb33dfe9d7112e9d4ff75975d20b2. Do not edit; run npm run sync-styles. */\n[data-component=\"text-shimmer\"] {\n --text-shimmer-step: 45ms;\n --text-shimmer-duration: 1200ms;\n --text-shimmer-swap: 220ms;\n --text-shimmer-index: 0;\n --text-shimmer-angle: 90deg;\n --text-shimmer-spread: 5.2ch;\n --text-shimmer-size: 360%;\n --text-shimmer-base-color: var(--text-weak);\n --text-shimmer-peak-color: var(--text-strong);\n --text-shimmer-sweep: linear-gradient(\n var(--text-shimmer-angle),\n transparent calc(50% - var(--text-shimmer-spread)),\n var(--text-shimmer-peak-color) 50%,\n transparent calc(50% + var(--text-shimmer-spread))\n );\n --text-shimmer-base: linear-gradient(var(--text-shimmer-base-color), var(--text-shimmer-base-color));\n\n display: inline-flex;\n align-items: baseline;\n font: inherit;\n letter-spacing: inherit;\n line-height: inherit;\n}\n\n[data-component=\"text-shimmer\"] [data-slot=\"text-shimmer-char\"] {\n display: inline-grid;\n white-space: pre;\n font: inherit;\n letter-spacing: inherit;\n line-height: inherit;\n}\n\n[data-component=\"text-shimmer\"] [data-slot=\"text-shimmer-char-base\"],\n[data-component=\"text-shimmer\"] [data-slot=\"text-shimmer-char-shimmer\"] {\n grid-area: 1 / 1;\n white-space: pre;\n transition: opacity var(--text-shimmer-swap) ease-out;\n font: inherit;\n letter-spacing: inherit;\n line-height: inherit;\n}\n\n[data-component=\"text-shimmer\"] [data-slot=\"text-shimmer-char-base\"] {\n color: inherit;\n opacity: 1;\n}\n\n[data-component=\"text-shimmer\"] [data-slot=\"text-shimmer-char-shimmer\"] {\n color: var(--text-weaker);\n opacity: 0;\n}\n\n[data-component=\"text-shimmer\"][data-active=\"true\"] [data-slot=\"text-shimmer-char-shimmer\"] {\n opacity: 1;\n}\n\n[data-component=\"text-shimmer\"] [data-slot=\"text-shimmer-char-shimmer\"][data-run=\"true\"] {\n animation-name: text-shimmer-sweep;\n animation-duration: var(--text-shimmer-duration);\n animation-iteration-count: infinite;\n animation-timing-function: linear;\n animation-fill-mode: both;\n animation-delay: calc(var(--text-shimmer-step) * var(--text-shimmer-index) * -1);\n will-change: background-position;\n}\n\n@keyframes text-shimmer-sweep {\n 0% {\n background-position:\n 100% 0,\n 0 0;\n }\n\n 100% {\n background-position:\n 0% 0,\n 0 0;\n }\n}\n\n@supports ((-webkit-background-clip: text) or (background-clip: text)) {\n [data-component=\"text-shimmer\"] [data-slot=\"text-shimmer-char-shimmer\"] {\n color: transparent;\n -webkit-text-fill-color: transparent;\n background-image: var(--text-shimmer-sweep), var(--text-shimmer-base);\n background-size:\n var(--text-shimmer-size) 100%,\n 100% 100%;\n background-position:\n 100% 0,\n 0 0;\n background-repeat: no-repeat;\n -webkit-background-clip: text;\n background-clip: text;\n }\n\n [data-component=\"text-shimmer\"][data-active=\"true\"] [data-slot=\"text-shimmer-char-base\"] {\n opacity: 0;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n [data-component=\"text-shimmer\"] [data-slot=\"text-shimmer-char-base\"],\n [data-component=\"text-shimmer\"] [data-slot=\"text-shimmer-char-shimmer\"] {\n transition-duration: 0ms;\n }\n\n [data-component=\"text-shimmer\"] [data-slot=\"text-shimmer-char-shimmer\"] {\n animation: none !important;\n color: inherit;\n -webkit-text-fill-color: currentColor;\n background-image: none;\n }\n\n [data-component=\"text-shimmer\"] [data-slot=\"text-shimmer-char-base\"] {\n opacity: 1 !important;\n }\n}\n",
17
+ "/* Synced from Mux frontend/src/ui/components/tool-status-title.css @ 37d6096b450cb33dfe9d7112e9d4ff75975d20b2. Do not edit; run npm run sync-styles. */\n[data-component=\"tool-status-title\"] {\n display: inline-flex;\n align-items: baseline;\n white-space: nowrap;\n text-align: start;\n\n [data-slot=\"tool-status-suffix\"] {\n display: inline-flex;\n align-items: baseline;\n white-space: nowrap;\n }\n\n [data-slot=\"tool-status-prefix\"] {\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n [data-slot=\"tool-status-swap\"],\n [data-slot=\"tool-status-tail\"] {\n display: inline-grid;\n overflow: hidden;\n justify-items: start;\n transition: width var(--tool-motion-spring-ms, 480ms) var(--tool-motion-ease, cubic-bezier(0.22, 1, 0.36, 1));\n }\n\n [data-slot=\"tool-status-active\"],\n [data-slot=\"tool-status-done\"] {\n grid-area: 1 / 1;\n white-space: nowrap;\n justify-self: start;\n text-align: start;\n transition-property: opacity, filter, transform;\n transition-duration:\n var(--tool-motion-fade-ms, 240ms), calc(var(--tool-motion-fade-ms, 240ms) * 0.8),\n calc(var(--tool-motion-fade-ms, 240ms) * 0.8);\n transition-timing-function: ease-out, ease-out, ease-out;\n }\n\n &[data-ready=\"false\"] {\n [data-slot=\"tool-status-swap\"],\n [data-slot=\"tool-status-tail\"] {\n transition-duration: 0ms;\n }\n\n [data-slot=\"tool-status-active\"],\n [data-slot=\"tool-status-done\"] {\n transition-duration: 0ms;\n }\n }\n\n [data-slot=\"tool-status-active\"] {\n opacity: 0;\n filter: blur(calc(var(--tool-motion-blur, 2px) * 0.45));\n transform: translateY(0.03em);\n }\n\n [data-slot=\"tool-status-done\"] {\n color: var(--text-strong);\n opacity: 1;\n filter: blur(0);\n transform: translateY(0);\n }\n\n &[data-active=\"true\"] {\n [data-slot=\"tool-status-active\"] {\n opacity: 1;\n filter: blur(0);\n transform: translateY(0);\n }\n\n [data-slot=\"tool-status-done\"] {\n opacity: 0;\n filter: blur(calc(var(--tool-motion-blur, 2px) * 0.45));\n transform: translateY(0.03em);\n }\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n [data-component=\"tool-status-title\"] [data-slot=\"tool-status-swap\"],\n [data-component=\"tool-status-title\"] [data-slot=\"tool-status-tail\"] {\n transition-duration: 0ms;\n }\n\n [data-component=\"tool-status-title\"] [data-slot=\"tool-status-active\"],\n [data-component=\"tool-status-title\"] [data-slot=\"tool-status-done\"] {\n transition-duration: 0ms;\n }\n}\n",
18
+ "/* Synced from Mux frontend/src/ui/components/dock-surface.css @ 37d6096b450cb33dfe9d7112e9d4ff75975d20b2. Do not edit; run npm run sync-styles. */\n[data-dock-surface=\"shell\"] {\n background-color: var(--surface-raised-stronger-non-alpha);\n box-shadow: var(--shadow-xs-border);\n position: relative;\n z-index: 10;\n border-radius: 12px;\n overflow: clip;\n}\n\n[data-dock-surface=\"tray\"] {\n background-color: var(--background-base);\n border: 1px solid var(--border-weak-base);\n position: relative;\n z-index: 0;\n border-radius: 12px;\n overflow: clip;\n}\n\n[data-dock-surface=\"tray\"][data-dock-attach=\"top\"] {\n margin-top: -0.875rem;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n",
19
+ "/* Synced from Mux frontend/src/ui/components/markdown.css @ 37d6096b450cb33dfe9d7112e9d4ff75975d20b2. Do not edit; run npm run sync-styles. */\n[data-component=\"markdown\"] {\n /* Reset & Base Typography */\n min-width: 0;\n max-width: 100%;\n overflow-wrap: break-word;\n color: var(--text-strong);\n font-family: var(--font-family-sans);\n font-size: var(--markdown-font-size, var(--font-size-base));\n line-height: 160%;\n /* Contain outer margins, but let margins collapse across streaming wrappers. */\n display: flow-root;\n\n /* Spacing for flow */\n > *:first-child,\n > [data-markdown-block]:first-child > *:first-child {\n margin-top: 0;\n }\n > *:last-child,\n > [data-markdown-block]:last-child > *:last-child {\n margin-bottom: 0;\n }\n\n /* Headings: Same size, distinguished by color and spacing */\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-size: var(--markdown-font-size, var(--font-size-base));\n color: var(--text-strong);\n font-weight: var(--font-weight-medium);\n margin-top: 1.5rem;\n margin-bottom: 0.5rem;\n line-height: var(--line-height-large);\n }\n\n /* Emphasis & Strong: Neutral strong color */\n strong,\n b {\n color: var(--text-strong);\n font-weight: var(--font-weight-medium);\n }\n\n /* Paragraphs */\n p {\n margin-bottom: 0.75rem;\n }\n\n /* Links */\n a {\n color: var(--text-interactive-base);\n text-decoration: none;\n font-weight: inherit;\n }\n\n a:hover {\n text-decoration: underline;\n text-underline-offset: 2px;\n }\n\n /* Lists */\n ul,\n ol {\n margin-top: 0.5rem;\n margin-bottom: 0.75rem;\n margin-left: 0;\n padding-left: 1.5rem;\n list-style-position: outside;\n }\n\n ul {\n list-style-type: disc;\n }\n\n ol {\n list-style-type: decimal;\n padding-left: 2.25rem;\n }\n\n li {\n margin-bottom: 0.5rem;\n }\n\n li > p:first-child {\n display: inline;\n margin: 0;\n }\n\n li > p + p {\n display: block;\n margin-top: 0.5rem;\n }\n\n li::marker {\n color: var(--text-weak);\n }\n\n /* Nested lists spacing */\n li > ul,\n li > ol {\n margin-top: 0.25rem;\n margin-bottom: 0.25rem;\n padding-left: 1rem; /* Minimal indent for nesting only */\n }\n\n li > ol {\n padding-left: 1.75rem;\n }\n\n /* Blockquotes */\n blockquote {\n border-left: 2px solid var(--border-weak-base);\n margin: 1rem 0;\n padding-left: 0.5rem;\n color: var(--text-weak);\n font-style: normal;\n }\n\n /* Horizontal Rule - Invisible spacing only */\n hr {\n border: none;\n height: 0;\n margin: 2rem 0;\n }\n\n .shiki,\n .markdown-code-pending {\n font-size: var(--markdown-font-size, 13px);\n line-height: 1.5;\n padding: 8px 12px;\n border-radius: 6px;\n border: 0.5px solid var(--border-weak-base);\n background: var(--surface-raised-base);\n }\n\n .markdown-code-pending code {\n font-family: var(--font-family-mono);\n font-feature-settings: var(--font-family-mono--font-feature-settings);\n }\n\n [data-component=\"markdown-code\"] {\n position: relative;\n\n [data-slot=\"markdown-copy-button\"] {\n position: absolute;\n right: 4px;\n z-index: 10;\n\n &[data-position=\"top\"] {\n top: 4px;\n }\n\n &[data-position=\"bottom\"] {\n bottom: 4px;\n }\n }\n }\n\n [data-slot=\"markdown-copy-button\"] {\n opacity: 0;\n transition: opacity 0.15s ease;\n\n &::after {\n content: attr(data-tooltip);\n position: absolute;\n left: 50%;\n bottom: calc(100% + 4px);\n transform: translateX(-50%);\n z-index: 1000;\n\n max-width: 320px;\n border-radius: var(--radius-sm);\n background: var(--surface-float-base);\n color: var(--text-invert-strong);\n padding: 2px 8px;\n border: 1px solid var(--border-weak-base, rgba(0, 0, 0, 0.07));\n box-shadow: var(--shadow-md);\n\n pointer-events: none;\n white-space: nowrap;\n\n font-family: var(--font-family-sans);\n font-size: var(--font-size-small);\n font-style: normal;\n font-weight: var(--font-weight-medium);\n line-height: var(--line-height-large);\n letter-spacing: var(--letter-spacing-normal);\n\n opacity: 0;\n transition: opacity 0.15s ease;\n }\n }\n\n [data-slot=\"markdown-copy-button\"]:hover::after,\n [data-slot=\"markdown-copy-button\"]:focus-visible::after {\n opacity: 1;\n }\n\n [data-slot=\"markdown-copy-button\"][data-variant=\"secondary\"] {\n box-shadow: none;\n border: 1px solid var(--border-weak-base);\n }\n\n [data-slot=\"markdown-copy-button\"][data-variant=\"secondary\"] [data-slot=\"icon-svg\"] {\n color: var(--icon-base);\n }\n\n [data-component=\"markdown-code\"]:hover [data-slot=\"markdown-copy-button\"],\n [data-component=\"file-viewer\"]:hover [data-slot=\"markdown-copy-button\"] {\n opacity: 1;\n }\n\n [data-slot=\"markdown-copy-button\"] [data-slot=\"check-icon\"] {\n display: none;\n }\n\n [data-slot=\"markdown-copy-button\"][data-copied=\"true\"] [data-slot=\"copy-icon\"] {\n display: none;\n }\n\n [data-slot=\"markdown-copy-button\"][data-copied=\"true\"] [data-slot=\"check-icon\"] {\n display: inline-flex;\n }\n\n pre {\n margin-top: 0.75rem;\n margin-bottom: 1.5rem;\n overflow: auto;\n\n &[data-wrap=\"true\"] {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n overflow-x: hidden;\n }\n\n &[data-wrap=\"true\"] code,\n &[data-wrap=\"true\"] .line {\n white-space: inherit;\n }\n\n scrollbar-width: none;\n &::-webkit-scrollbar {\n display: none;\n }\n }\n\n :not(pre) > code {\n font-family: var(--font-family-mono);\n font-feature-settings: var(--font-family-mono--font-feature-settings);\n color: var(--syntax-string);\n font-weight: var(--font-weight-medium);\n /* font-size: 13px; */\n\n /* padding: 2px 2px; */\n /* margin: 0 1.5px; */\n /* border-radius: 2px; */\n /* background: var(--surface-base); */\n /* box-shadow: 0 0 0 0.5px var(--border-weak-base); */\n }\n\n /* Tables */\n table {\n width: 100%;\n border-collapse: collapse;\n margin: 1.5rem 0;\n font-size: var(--markdown-font-size, var(--font-size-base));\n display: block;\n overflow-x: auto;\n }\n\n th,\n td {\n /* Minimal borders for structure, matching TUI \"lines\" roughly but keeping it web-clean */\n border-bottom: 1px solid var(--border-weaker-base);\n padding: 0.75rem 0.5rem;\n text-align: left;\n vertical-align: top;\n }\n\n th {\n color: var(--text-strong);\n font-weight: var(--font-weight-medium);\n border-bottom: 1px solid var(--border-weak-base);\n }\n\n /* Images */\n img {\n max-width: 100%;\n height: auto;\n border-radius: 4px;\n margin: 1.5rem 0;\n display: block;\n }\n\n [data-component=\"mermaid\"] {\n margin: 2rem 0;\n overflow: auto;\n border: 0.5px solid var(--border-weak-base);\n border-radius: 6px;\n background: var(--surface-raised-base);\n padding: 16px;\n\n svg {\n display: block;\n width: 100%;\n min-width: 320px;\n height: auto;\n margin: 0 auto;\n }\n }\n\n pre[data-mermaid-status=\"error\"]::after {\n content: attr(data-mermaid-error);\n display: block;\n margin-top: 8px;\n color: var(--text-weak);\n font-family: var(--font-family-sans);\n font-size: 12px;\n white-space: normal;\n }\n}\n\n[data-component=\"markdown\"] a.external-link:hover > code {\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n",
20
+ "/* Synced from Mux frontend/src/pages/session/transcript/renderers/message-part.css @ 37d6096b450cb33dfe9d7112e9d4ff75975d20b2. Do not edit; run npm run sync-styles. */\n/* [data-component=\"assistant-message\"] {\n content-visibility: auto;\n} */\n[data-component=\"assistant-message\"] {\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n\n [data-slot=\"assistant-message-actions\"] {\n min-height: 24px;\n display: flex;\n align-items: center;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease;\n will-change: opacity;\n }\n\n &:hover [data-slot=\"assistant-message-actions\"],\n &:focus-within [data-slot=\"assistant-message-actions\"] {\n opacity: 1;\n pointer-events: auto;\n }\n}\n\n[data-component=\"user-message\"] {\n font-family: var(--font-family-sans);\n font-size: var(--font-size-base);\n font-style: normal;\n font-weight: var(--font-weight-regular);\n line-height: var(--line-height-large);\n letter-spacing: var(--letter-spacing-normal);\n color: var(--text-strong);\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n align-self: stretch;\n width: 100%;\n max-width: 100%;\n gap: 0;\n\n [data-slot=\"user-message-attachments\"] {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: 8px;\n width: fit-content;\n max-width: min(82%, 64ch);\n margin-left: auto;\n }\n\n [data-slot=\"user-message-attachment\"] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-width: 0;\n border-radius: 6px;\n overflow: hidden;\n background: var(--surface-weak);\n border: 1px solid var(--border-weak-base);\n cursor: default;\n transition:\n border-color 0.15s ease,\n opacity 0.3s ease;\n\n &:hover {\n border-color: var(--border-strong-base);\n }\n\n &[data-clickable] {\n cursor: pointer;\n }\n\n &[data-type=\"image\"] {\n width: 48px;\n height: 48px;\n }\n\n &[data-type=\"file\"] {\n width: min(220px, 100%);\n height: 48px;\n padding: 0 10px;\n }\n }\n\n [data-slot=\"user-message-attachment-image\"] {\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n\n [data-slot=\"user-message-attachment-file\"] {\n width: 100%;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n\n [data-component=\"file-icon\"] {\n width: 20px;\n height: 20px;\n flex: none;\n }\n }\n\n [data-slot=\"user-message-attachment-name\"] {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--text-base);\n font-size: var(--font-size-small);\n line-height: var(--line-height-large);\n }\n\n [data-slot=\"user-message-body\"] {\n width: fit-content;\n max-width: min(82%, 64ch);\n margin-left: auto;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n }\n\n [data-slot=\"user-message-attachments\"] + [data-slot=\"user-message-body\"] {\n margin-top: 8px;\n }\n\n [data-slot=\"user-message-text\"] {\n display: inline-block;\n white-space: pre-wrap;\n word-break: break-word;\n overflow: hidden;\n background: color-mix(in srgb, var(--surface-weak) 65%, transparent);\n border: 1px solid transparent;\n padding: 8px 12px;\n border-radius: 12px;\n\n [data-highlight=\"file\"] {\n color: var(--syntax-property);\n }\n\n [data-highlight=\"agent\"] {\n color: var(--syntax-type);\n }\n\n max-width: 100%;\n }\n\n [data-slot=\"user-message-copy-wrapper\"] {\n min-height: 24px;\n margin-top: 4px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 10px;\n width: 100%;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease;\n will-change: opacity;\n\n [data-component=\"tooltip-trigger\"] {\n display: inline-flex;\n width: fit-content;\n }\n }\n\n [data-slot=\"user-message-meta\"] {\n user-select: none;\n text-align: right;\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n [data-slot=\"user-message-meta-wrap\"] {\n flex: 1 1 auto;\n min-width: 0;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n overflow: hidden;\n gap: 0;\n }\n\n [data-slot=\"user-message-meta-tail\"] {\n user-select: none;\n flex: 0 0 auto;\n white-space: nowrap;\n text-align: right;\n }\n\n &:hover [data-slot=\"user-message-copy-wrapper\"],\n &:focus-within [data-slot=\"user-message-copy-wrapper\"] {\n opacity: 1;\n pointer-events: auto;\n }\n\n .text-text-strong {\n color: var(--text-strong);\n }\n\n .font-medium {\n font-weight: var(--font-weight-medium);\n }\n}\n\n[data-component=\"text-part\"] {\n width: 100%;\n margin-top: 24px;\n container-type: inline-size;\n container-name: text-part;\n\n [data-slot=\"text-part-body\"] {\n margin-top: 0;\n }\n\n [data-slot=\"text-part-copy-wrapper\"] {\n display: none;\n min-height: 24px;\n margin-top: 4px;\n align-items: center;\n justify-content: flex-start;\n gap: 10px;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease;\n will-change: opacity;\n\n &[data-active] {\n display: flex;\n }\n\n [data-component=\"tooltip-trigger\"] {\n display: inline-flex;\n width: fit-content;\n }\n }\n\n [data-slot=\"text-part-meta\"] {\n flex: 0 0 auto;\n white-space: nowrap;\n user-select: none;\n\n > span {\n flex: 0 0 auto;\n }\n }\n\n [data-slot=\"text-part-copy-wrapper\"][data-interrupted] {\n width: 100%;\n justify-content: flex-end;\n gap: 12px;\n }\n\n &:hover [data-slot=\"text-part-copy-wrapper\"],\n &:focus-within [data-slot=\"text-part-copy-wrapper\"] {\n opacity: 1;\n pointer-events: auto;\n }\n\n [data-component=\"markdown\"] {\n margin-top: 0;\n }\n}\n\n@container text-part (max-width: 44rem) {\n [data-slot=\"text-part-copy-wrapper\"] {\n gap: 8px;\n }\n\n [data-slot=\"text-part-meta\"] {\n gap: 4px;\n font-size: calc(var(--font-size-base) * 11 / 14);\n }\n}\n\n@container text-part (max-width: 32rem) {\n [data-slot=\"text-part-copy-wrapper\"] {\n gap: 6px;\n }\n\n [data-slot=\"text-part-meta\"] {\n gap: 3px;\n font-size: calc(var(--font-size-base) * 10 / 14);\n }\n}\n\n[data-component=\"compaction-part\"] {\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n\n [data-slot=\"compaction-part-divider\"] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n width: 100%;\n }\n\n [data-slot=\"compaction-part-line\"] {\n flex: 1 1 auto;\n height: 1px;\n background: var(--border-weak-base);\n }\n\n [data-slot=\"compaction-part-label\"] {\n flex: 0 0 auto;\n white-space: nowrap;\n text-align: center;\n }\n\n [data-slot=\"compaction-part-toggle\"] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n min-height: 24px;\n padding: 0 6px;\n border-radius: var(--radius-md);\n color: inherit;\n cursor: pointer;\n user-select: none;\n\n &:hover,\n &:focus-visible {\n outline: none;\n background-color: var(--surface-raised-base-hover);\n color: var(--text-base);\n }\n }\n\n [data-slot=\"compaction-part-summary\"] {\n padding: 4px 0 8px;\n color: var(--text-weak);\n }\n}\n\n[data-component=\"reasoning-part\"] {\n width: 100%;\n color: var(--text-base);\n line-height: var(--line-height-normal);\n\n [data-component=\"markdown\"] {\n margin-top: 24px;\n font-style: normal;\n color: var(--text-weak);\n\n strong,\n b {\n color: var(--text-weak);\n }\n\n p:has(strong) {\n margin-top: 24px;\n margin-bottom: 0;\n\n &:first-child {\n margin-top: 0;\n }\n }\n }\n}\n\n@media (prefers-color-scheme: dark) {\n [data-component=\"reasoning-part\"]\n [data-component=\"markdown\"]\n :not(pre)\n > code {\n opacity: 0.6;\n }\n}\n\n[data-component=\"tool-output\"] {\n white-space: pre;\n padding: 0;\n margin-bottom: 24px;\n height: fit-content;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n justify-content: flex-start;\n\n [data-component=\"markdown\"] {\n width: 100%;\n min-width: 0;\n\n pre {\n margin: 0;\n padding: 0;\n background-color: transparent !important;\n border: none !important;\n }\n }\n\n pre {\n margin: 0;\n padding: 0;\n background: none;\n }\n\n &[data-scrollable] {\n height: auto;\n max-height: 240px;\n overflow-y: auto;\n scrollbar-width: none;\n -ms-overflow-style: none;\n\n &::-webkit-scrollbar {\n display: none;\n }\n\n [data-component=\"markdown\"] {\n overflow: visible;\n }\n }\n}\n\n[data-component=\"bash-output\"] {\n width: 100%;\n border: 1px solid var(--border-weak-base);\n border-radius: 6px;\n background: transparent;\n position: relative;\n overflow: hidden;\n\n [data-slot=\"bash-copy\"] {\n position: absolute;\n top: 4px;\n right: 4px;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease;\n }\n\n &:hover [data-slot=\"bash-copy\"],\n &:focus-within [data-slot=\"bash-copy\"] {\n opacity: 1;\n pointer-events: auto;\n }\n\n [data-slot=\"bash-copy\"]\n [data-component=\"icon-button\"][data-variant=\"secondary\"] {\n box-shadow: none;\n border: 1px solid var(--border-weak-base);\n }\n\n [data-slot=\"bash-copy\"]\n [data-component=\"icon-button\"][data-variant=\"secondary\"]\n [data-slot=\"icon-svg\"] {\n color: var(--icon-base);\n }\n\n [data-slot=\"bash-scroll\"] {\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n max-height: 240px;\n\n scrollbar-width: none;\n &::-webkit-scrollbar {\n display: none;\n }\n }\n\n [data-slot=\"bash-pre\"] {\n margin: 0;\n padding: 12px;\n }\n\n [data-slot=\"bash-pre\"] code {\n font-family: var(--font-family-mono);\n font-feature-settings: var(--font-family-mono--font-feature-settings);\n font-size: var(--font-size-small);\n line-height: var(--line-height-large);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n }\n}\n\n[data-component=\"tool-trigger\"][data-layout=\"activity-row\"]:has(\n [data-component=\"edit-trigger\"],\n [data-component=\"write-trigger\"]\n) > [data-slot=\"collapsible-arrow\"] {\n grid-column: 4;\n}\n\n[data-component=\"tool-trigger\"][data-layout=\"activity-row\"]:hover\n [data-slot=\"message-part-view-file\"],\n[data-component=\"tool-trigger\"][data-layout=\"activity-row\"]:focus-within\n [data-slot=\"message-part-view-file\"] {\n opacity: 1;\n}\n\n[data-component=\"edit-trigger\"],\n[data-component=\"write-trigger\"] {\n display: contents;\n\n [data-slot=\"message-part-title\"] {\n grid-column: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n font-family: var(--font-family-sans);\n font-size: var(--font-size-base);\n font-style: normal;\n font-weight: var(--font-weight-medium);\n line-height: var(--line-height-large);\n letter-spacing: var(--letter-spacing-normal);\n color: var(--text-base);\n }\n\n [data-slot=\"message-part-path\"] {\n grid-column: 2;\n display: flex;\n min-width: 0;\n overflow: hidden;\n font-weight: var(--font-weight-regular);\n }\n\n [data-slot=\"message-part-actions\"] {\n grid-column: 3;\n display: flex;\n gap: 4px;\n align-items: center;\n justify-content: flex-end;\n flex-shrink: 0;\n }\n\n [data-slot=\"message-part-actions\"] [data-component=\"diff-changes\"] {\n gap: 4px;\n\n [data-slot=\"diff-changes-additions\"],\n [data-slot=\"diff-changes-deletions\"] {\n min-width: 2ch;\n font-size: var(--font-size-small);\n }\n }\n\n [data-slot=\"message-part-view-file\"] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1px;\n border-radius: 4px;\n color: var(--text-base);\n cursor: pointer;\n opacity: 0;\n transition: opacity 0.15s ease;\n\n &:hover,\n &:focus-visible {\n color: var(--text-strong);\n background: var(--surface-base);\n outline: none;\n }\n }\n\n [data-slot=\"message-part-title-text\"] {\n flex-shrink: 0;\n text-transform: capitalize;\n color: var(--text-strong);\n }\n\n [data-slot=\"message-part-path\"] {\n display: flex;\n min-width: 0;\n overflow: hidden;\n font-weight: var(--font-weight-regular);\n }\n\n [data-slot=\"message-part-directory\"] {\n color: var(--text-weak);\n flex: 0 1 auto;\n min-width: 0;\n direction: rtl;\n text-align: left;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n }\n\n [data-slot=\"message-part-path-separator\"] {\n color: var(--text-weak);\n flex: 0 0 auto;\n }\n\n [data-slot=\"message-part-filename\"] {\n color: var(--text-strong);\n flex: 0 0 auto;\n white-space: nowrap;\n }\n}\n\n[data-component=\"edit-content\"],\n[data-component=\"write-content\"],\n[data-component=\"apply-patch-file-diff\"] {\n border-radius: inherit;\n max-height: calc(var(--session-viewport-height, 100dvh) * 0.6);\n overflow-x: hidden;\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: var(--border-weak-base) transparent;\n}\n\n[data-component=\"edit-content\"],\n[data-component=\"write-content\"] {\n border-top: 1px solid var(--border-weaker-base);\n}\n\n/* Expanded output belongs to the transcript's vertical scroll in the mobile\n layout, including landscape phones wider than 768px. clip, unlike hidden,\n does not create another scrolling container. */\n:where(html[data-mobile-layout]) [data-mobile-surface=\"session\"] {\n [data-component=\"edit-content\"],\n [data-component=\"write-content\"],\n [data-component=\"apply-patch-file-diff\"],\n [data-component=\"tool-output\"][data-scrollable],\n [data-slot=\"bash-scroll\"] {\n max-height: none;\n overflow-x: clip;\n overflow-y: visible;\n }\n}\n\n[data-component=\"tool-action\"] {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n[data-component=\"exa-tool-output\"] {\n width: 100%;\n padding-top: 8px;\n display: flex;\n flex-direction: column;\n}\n\n[data-slot=\"basic-tool-tool-subtitle\"].exa-tool-query {\n display: block;\n max-width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n[data-slot=\"exa-tool-links\"] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n[data-slot=\"exa-tool-link\"] {\n display: block;\n max-width: 100%;\n color: var(--text-interactive-base);\n text-decoration: underline;\n text-underline-offset: 2px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n &:hover {\n color: var(--text-interactive-base);\n }\n\n &:visited {\n color: var(--text-interactive-base);\n }\n}\n\n[data-slot=\"basic-tool-tool-title\"],\n[data-slot=\"context-tool-group-label\"] {\n min-width: 0;\n}\n\n:is([data-component=\"context-tool-group-trigger\"], [data-component=\"work-tool-group-trigger\"])[data-layout=\"activity-row\"] {\n width: fit-content;\n max-width: 100%;\n min-width: 0;\n min-height: 24px;\n display: grid;\n grid-template-columns: var(--activity-label-width) minmax(0, auto) auto auto;\n align-items: center;\n column-gap: 8px;\n cursor: default;\n\n [data-slot=\"context-tool-group-title\"] {\n display: contents;\n }\n\n [data-slot=\"context-tool-group-label\"] {\n grid-column: 1;\n }\n\n [data-slot=\"context-tool-group-summary\"] {\n grid-column: 2;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n [data-slot=\"context-tool-group-budget\"],\n > [data-component=\"diff-changes\"] {\n grid-column: 3;\n }\n\n > [data-component=\"diff-changes\"] {\n margin-inline-start: 8px;\n gap: 4px;\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n }\n\n > [data-slot=\"collapsible-arrow\"] {\n grid-column: 4;\n }\n\n &:not(:has([data-slot=\"context-tool-group-budget\"], [data-component=\"diff-changes\"]))\n > [data-slot=\"collapsible-arrow\"] {\n grid-column: 3;\n }\n\n [data-slot=\"collapsible-arrow\"] {\n color: var(--icon-weaker);\n cursor: pointer;\n }\n}\n\n[data-activity-group] > [data-slot=\"collapsible-content\"] > [data-component=\"context-tool-group-list\"] {\n --activity-label-width: calc(var(--font-size-base) * 72 / 14);\n padding: 4px 0 0 16px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n\n > [data-slot=\"context-tool-group-item\"] {\n min-width: 0;\n padding: 0;\n }\n\n > [data-slot=\"context-tool-group-item\"] > [data-component=\"tool-trigger\"] {\n min-height: 28px;\n align-items: center;\n }\n\n}\n\n[data-activity-group=\"single\"] > [data-slot=\"collapsible-content\"] > [data-component=\"context-tool-group-list\"] {\n --activity-label-width: max-content;\n padding: 0;\n gap: 0;\n}\n\n[data-component=\"diagnostics\"] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 8px 12px;\n background-color: var(--surface-critical-weak);\n border-top: 1px solid var(--border-critical-base);\n\n [data-slot=\"diagnostic\"] {\n display: flex;\n align-items: baseline;\n gap: 6px;\n font-family: var(--font-family-mono);\n font-size: var(--font-size-small);\n line-height: var(--line-height-large);\n }\n}\n\n[data-component=\"user-message\"] [data-slot=\"user-message-text\"],\n[data-component=\"text-part\"],\n[data-component=\"reasoning-part\"],\n[data-component=\"tool-output\"],\n[data-component=\"bash-output\"],\n[data-component=\"edit-content\"],\n[data-component=\"write-content\"],\n[data-component=\"diagnostics\"],\n.error-card {\n -webkit-user-select: text;\n user-select: text;\n}\n\n[data-component=\"tool-part-wrapper\"] {\n width: 100%;\n}\n\n[data-component=\"dock-prompt\"][data-kind=\"permission\"] {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 0;\n min-height: 0;\n max-height: 100dvh;\n\n [data-slot=\"permission-header\"] {\n padding: 0;\n }\n\n [data-slot=\"permission-row\"] {\n display: grid;\n grid-template-columns: 20px 1fr;\n column-gap: 8px;\n align-items: start;\n }\n\n [data-slot=\"permission-row\"][data-variant=\"header\"] {\n align-items: center;\n }\n\n [data-slot=\"permission-icon\"] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n [data-slot=\"permission-icon\"] [data-component=\"icon\"] {\n color: var(--icon-warning-base);\n }\n\n [data-slot=\"permission-header-title\"] {\n font-family: var(--font-family-sans);\n font-size: 14px;\n font-weight: var(--font-weight-medium);\n line-height: var(--line-height-large);\n color: var(--text-strong);\n min-width: 0;\n }\n\n [data-slot=\"permission-hint\"] {\n font-family: var(--font-family-sans);\n font-size: 14px;\n font-weight: var(--font-weight-regular);\n line-height: var(--line-height-large);\n color: var(--text-weak);\n padding: 0;\n }\n\n [data-slot=\"permission-patterns\"] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 8px;\n margin-bottom: 16px;\n padding: 1px 0 8px;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n scrollbar-width: none;\n -ms-overflow-style: none;\n\n &::-webkit-scrollbar {\n display: none;\n }\n\n code {\n font-size: 14px;\n line-height: var(--line-height-large);\n }\n }\n\n [data-slot=\"permission-footer\"] {\n display: flex;\n flex-shrink: 0;\n padding: 32px 8px 8px;\n margin-top: -24px;\n }\n\n [data-slot=\"permission-footer-actions\"] {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n gap: 8px;\n\n [data-component=\"button\"] {\n padding-left: 12px;\n padding-right: 12px;\n }\n }\n}\n\n[data-component=\"dock-prompt\"][data-kind=\"question\"] {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 0;\n min-height: 0;\n max-height: var(--question-prompt-max-height, 100dvh);\n\n [data-slot=\"question-header\"] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 0 10px;\n }\n\n [data-slot=\"question-header-title\"] {\n font-family: var(--font-family-sans);\n font-size: 14px;\n font-weight: var(--font-weight-medium);\n line-height: var(--line-height-large);\n color: var(--text-strong);\n min-width: 0;\n }\n\n [data-slot=\"question-progress\"] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n }\n\n [data-slot=\"question-progress-segment\"] {\n width: 16px;\n height: 16px;\n padding: 0;\n border: 0;\n background: transparent;\n border-radius: 999px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n touch-action: manipulation;\n\n &::after {\n content: \"\";\n width: 16px;\n height: 2px;\n border-radius: 999px;\n background-color: var(--icon-weak-base);\n transition: background-color 0.2s ease;\n }\n\n &[data-active=\"true\"]::after {\n background-color: var(--icon-strong-base);\n }\n\n &[data-answered=\"true\"]::after {\n background-color: var(--icon-interactive-base);\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n }\n\n [data-slot=\"question-text\"] {\n font-family: var(--font-family-sans);\n font-size: 14px;\n font-weight: var(--font-weight-medium);\n line-height: var(--line-height-large);\n color: var(--text-strong);\n padding: 0 10px;\n }\n\n [data-slot=\"question-hint\"] {\n font-family: var(--font-family-sans);\n font-size: 13px;\n font-weight: var(--font-weight-regular);\n line-height: var(--line-height-large);\n color: var(--text-weak);\n padding: 0 10px;\n }\n\n [data-slot=\"question-options\"] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 12px;\n padding: 1px 1px 8px;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n scrollbar-width: none;\n -ms-overflow-style: none;\n\n &::-webkit-scrollbar {\n display: none;\n }\n }\n\n [data-slot=\"question-option\"] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 8px 8px 8px 10px;\n background-color: var(--surface-raised-stronger-non-alpha);\n border: 1px solid var(--border-weak-base);\n border-radius: 6px;\n box-shadow: none;\n text-align: left;\n width: 100%;\n cursor: pointer;\n transition:\n background-color 0.15s ease,\n border-color 0.15s ease,\n box-shadow 0.15s ease;\n\n &:hover:not([data-picked=\"true\"]) {\n background-color: var(--background-base);\n }\n\n &[data-picked=\"true\"] {\n background-color: var(--surface-interactive-weak);\n border-color: transparent;\n box-shadow: var(--shadow-xs-border-hover);\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n }\n\n [data-slot=\"question-option-check\"] {\n display: inline-flex;\n transform: translateY(2px);\n }\n\n [data-slot=\"question-option-box\"] {\n width: 16px;\n height: 16px;\n padding: 2px;\n border-radius: var(--radius-sm);\n border: 1px solid var(--border-weak-base);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background-color: transparent;\n transition:\n background-color 0.15s ease,\n border-color 0.15s ease;\n\n [data-component=\"icon\"] {\n opacity: 0;\n color: var(--icon-base);\n }\n\n &[data-type=\"radio\"] {\n border-radius: 999px;\n }\n\n [data-slot=\"question-option-radio-dot\"] {\n width: 6px;\n height: 6px;\n border-radius: 999px;\n background-color: var(--background-stronger);\n opacity: 0;\n }\n\n &[data-picked=\"true\"] {\n border-color: var(--icon-interactive-base);\n\n [data-component=\"icon\"] {\n opacity: 1;\n color: var(--icon-invert-base);\n }\n\n &[data-type=\"checkbox\"] {\n background-color: var(--icon-interactive-base);\n }\n\n &[data-type=\"radio\"] {\n background-color: var(--icon-interactive-base);\n [data-slot=\"question-option-radio-dot\"] {\n opacity: 1;\n }\n }\n }\n }\n\n [data-slot=\"question-option-main\"] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n }\n\n [data-slot=\"option-label\"] {\n font-family: var(--font-family-sans);\n font-size: 14px;\n font-weight: var(--font-weight-medium);\n line-height: var(--line-height-large);\n color: var(--text-strong);\n }\n\n [data-slot=\"option-description\"] {\n font-family: var(--font-family-sans);\n font-size: 14px;\n font-weight: var(--font-weight-regular);\n line-height: var(--line-height-large);\n color: var(--text-base);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n [data-slot=\"question-option\"][data-custom=\"true\"] {\n [data-slot=\"option-description\"] {\n overflow: visible;\n text-overflow: clip;\n white-space: normal;\n overflow-wrap: anywhere;\n }\n }\n\n [data-slot=\"question-custom\"] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n [data-slot=\"question-custom-input\"] {\n width: 100%;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n box-shadow: none;\n outline: none;\n font-family: var(--font-family-sans);\n font-size: 14px;\n font-weight: var(--font-weight-regular);\n line-height: var(--line-height-large);\n color: var(--text-base);\n min-width: 0;\n cursor: text;\n resize: none;\n overflow: hidden;\n overflow-wrap: anywhere;\n\n &::placeholder {\n color: var(--text-weak);\n }\n\n &:focus-visible {\n outline: 1px solid var(--border-interactive-base);\n outline-offset: 2px;\n border-radius: var(--radius-xs);\n }\n\n &:disabled {\n opacity: 0.6;\n }\n }\n\n [data-slot=\"question-footer\"] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n padding: 32px 8px 8px;\n margin-top: -24px;\n }\n\n [data-slot=\"question-footer-actions\"] {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n}\n\n[data-component=\"question-answers\"] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 8px 0;\n\n [data-slot=\"question-answer-item\"] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n font-size: var(--font-size-small);\n\n [data-slot=\"question-text\"] {\n color: var(--text-weak);\n }\n\n [data-slot=\"answer-text\"] {\n color: var(--text-strong);\n }\n }\n}\n\n[data-component=\"edit-tool\"],\n[data-component=\"write-tool\"],\n[data-component=\"apply-patch-tool\"] {\n > [data-component=\"collapsible\"].tool-collapsible {\n gap: 0px;\n }\n\n > [data-component=\"collapsible\"] > [data-slot=\"collapsible-content\"] {\n border: none;\n background: transparent;\n }\n\n > [data-component=\"collapsible\"] > [data-slot=\"collapsible-trigger\"] {\n min-height: 28px;\n height: auto;\n padding-bottom: 0;\n }\n\n > [data-component=\"collapsible\"]\n > [data-slot=\"collapsible-trigger\"][aria-expanded=\"true\"] {\n z-index: 20;\n background-color: var(--background-stronger);\n }\n}\n\n[data-component=\"accordion\"][data-scope=\"apply-patch\"] {\n [data-slot=\"accordion-trigger\"] {\n background-color: var(--background-stronger) !important;\n }\n\n [data-slot=\"apply-patch-trigger-content\"] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n gap: 20px;\n }\n\n [data-slot=\"apply-patch-file-info\"] {\n flex-grow: 1;\n display: flex;\n align-items: center;\n gap: 20px;\n min-width: 0;\n }\n\n [data-slot=\"apply-patch-file-name-container\"] {\n display: flex;\n flex-grow: 1;\n min-width: 0;\n }\n\n [data-slot=\"apply-patch-directory\"] {\n color: var(--text-base);\n min-width: 0;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n }\n\n [data-slot=\"apply-patch-filename\"] {\n color: var(--text-strong);\n flex-shrink: 0;\n }\n\n [data-slot=\"apply-patch-trigger-actions\"] {\n flex-shrink: 0;\n display: flex;\n gap: 16px;\n align-items: center;\n justify-content: flex-end;\n }\n\n [data-slot=\"apply-patch-change\"] {\n font-family: var(--font-family-sans);\n font-size: var(--font-size-small);\n font-weight: var(--font-weight-medium);\n }\n\n [data-slot=\"apply-patch-change\"][data-type=\"added\"] {\n color: var(--icon-diff-add-base);\n }\n\n [data-slot=\"apply-patch-change\"][data-type=\"removed\"] {\n color: var(--icon-diff-delete-base);\n }\n\n [data-slot=\"apply-patch-change\"][data-type=\"modified\"] {\n color: var(--icon-diff-modified-base);\n }\n}\n\n[data-component=\"tool-loaded-file\"] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0 4px 28px;\n font-family: var(--font-family-sans);\n font-size: var(--font-size-small);\n font-weight: var(--font-weight-regular);\n line-height: var(--line-height-large);\n color: var(--text-weak);\n\n [data-component=\"icon\"] {\n flex-shrink: 0;\n color: var(--icon-weak);\n }\n}\n",
21
+ "/* Synced from Mux frontend/src/pages/session/transcript/renderers/session-turn.css @ 37d6096b450cb33dfe9d7112e9d4ff75975d20b2. Do not edit; run npm run sync-styles. */\n/* Scope the existing typography tokens to transcript rows, not the header,\n composer, file tabs, or portalled menus. Shared renderers inherit this scale. */\n[data-component=\"message-timeline\"] [data-component=\"session-turn\"] {\n --font-size-base: var(--chat-font-size, 14px);\n --font-size-small: calc(var(--font-size-base) * 13 / 14);\n --font-size-large: calc(var(--font-size-base) * 16 / 14);\n --font-size-x-large: calc(var(--font-size-base) * 20 / 14);\n --markdown-font-size: var(--font-size-base);\n --file-font-size: var(--font-size-base);\n font-size: var(--font-size-base);\n}\n\n[data-component=\"session-turn\"] {\n --sticky-header-height: calc(var(--session-title-height, 0px) + 24px);\n height: 100%;\n min-height: 0;\n min-width: 0;\n display: flex;\n align-items: flex-start;\n justify-content: flex-start;\n\n [data-slot=\"session-turn-message-container\"] {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n align-self: stretch;\n min-width: 0;\n gap: 18px;\n overflow-anchor: none;\n }\n\n [data-slot=\"session-turn-message-content\"] {\n margin-top: 0;\n width: 100%;\n min-width: 0;\n max-width: 100%;\n }\n\n [data-slot=\"session-turn-compaction\"] {\n width: 100%;\n min-width: 0;\n align-self: stretch;\n }\n\n [data-slot=\"session-turn-thinking\"][data-layout=\"activity-row\"] {\n display: grid;\n grid-template-columns: var(--activity-label-width) minmax(0, 1fr) auto auto;\n align-items: baseline;\n column-gap: 8px;\n width: 100%;\n min-width: 0;\n color: var(--text-weak);\n font-family: var(--font-family-sans);\n font-size: var(--font-size-base);\n font-weight: var(--font-weight-medium);\n line-height: var(--line-height-large);\n min-height: 20px;\n\n [data-slot=\"activity-row-label\"] {\n grid-column: 1;\n min-width: 0;\n }\n\n .session-turn-thinking-heading {\n grid-column: 2;\n }\n\n [data-component=\"spinner\"] {\n width: 16px;\n height: 16px;\n }\n }\n\n .session-turn-thinking-heading {\n min-width: 0;\n max-width: 100%;\n overflow: hidden;\n color: var(--text-weaker);\n font-weight: var(--font-weight-regular);\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n .error-card {\n color: var(--text-on-critical-base);\n max-height: 240px;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n word-break: break-word;\n overflow-y: auto;\n }\n\n [data-slot=\"session-turn-assistant-content\"] {\n width: 100%;\n min-width: 0;\n display: flex;\n flex-direction: column;\n align-self: stretch;\n gap: 12px;\n\n > :first-child > [data-component=\"markdown\"]:first-child {\n margin-top: 0;\n }\n }\n}\n",
22
+ "/* The embed's own layout, plus the timeline and composer rules Mux keeps in\n frontend/src/index.css or writes as Tailwind classes (composer-view.tsx).\n Values mirror Mux's; everything else comes from the synced stylesheets. */\n\n:host {\n display: block;\n height: 100%;\n min-height: 0;\n /* Mux ships Inter and IBM Plex Mono; fall back to system faces when the host page lacks them. */\n --font-family-sans: \"Inter\", ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n --font-family-mono: \"IBM Plex Mono\", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nbutton,\ninput,\nselect,\ntextarea {\n font: inherit;\n color: inherit;\n margin: 0;\n}\n\nbutton {\n background: none;\n border: 0;\n padding: 0;\n cursor: pointer;\n}\n\nbutton:disabled {\n cursor: default;\n}\n\n[data-component=\"icon\"] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n[data-component=\"mux-chat\"] {\n height: 100%;\n min-height: 0;\n display: flex;\n flex-direction: column;\n background: var(--background-stronger);\n color: var(--text-base);\n font-family: var(--font-family-sans);\n font-feature-settings: var(--font-family-sans--font-feature-settings);\n font-size: var(--font-size-base);\n line-height: var(--line-height-large);\n -webkit-font-smoothing: antialiased;\n}\n\n/* ---------------------------------------------------------------- header */\n\n[data-slot=\"mux-chat-header\"] {\n display: flex;\n align-items: center;\n gap: 8px;\n min-height: 44px;\n padding: 8px 10px 8px 18px;\n border-bottom: 1px solid var(--border-weaker-base);\n}\n\n[data-slot=\"mux-chat-heading\"] {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n}\n\n[data-slot=\"mux-chat-title\"] {\n color: var(--text-strong);\n font-weight: var(--font-weight-medium);\n line-height: 20px;\n}\n\n[data-slot=\"mux-chat-subtitle\"] {\n color: var(--text-weak);\n font-size: 12px;\n line-height: 16px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n[data-slot=\"mux-chat-status\"] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n flex: none;\n color: var(--text-weak);\n font-size: 12px;\n line-height: 16px;\n\n &::before {\n content: \"\";\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--icon-weak-base);\n }\n\n &[data-tone=\"ok\"]::before {\n background: var(--icon-success-base);\n }\n\n &[data-tone=\"bad\"]::before {\n background: var(--icon-critical-base);\n }\n\n &[data-tone=\"ok\"] [data-slot=\"mux-chat-status-text\"] {\n display: none;\n }\n}\n\n[data-action=\"new-chat\"] {\n width: 28px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n/* -------------------------------------------------------------- timeline */\n\n[data-component=\"message-timeline\"] {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n overflow-anchor: auto;\n display: flex;\n flex-direction: column;\n padding: 16px 0;\n scrollbar-width: thin;\n}\n\n[data-component=\"message-timeline\"] [data-slot=\"session-turn-message-container\"] {\n display: flex;\n flex-direction: column;\n gap: 14px;\n padding-inline: 18px;\n}\n\n[data-component=\"message-timeline\"] [data-component=\"assistant-message\"] {\n gap: 8px;\n}\n\n[data-component=\"message-timeline\"] [data-component=\"user-message\"] {\n line-height: var(--line-height-large);\n}\n\n[data-component=\"message-timeline\"] [data-slot=\"user-message-text\"] {\n padding: 6px 9px;\n white-space: pre-wrap;\n}\n\n[data-component=\"message-timeline\"] [data-component=\"text-part\"] {\n width: 100%;\n}\n\n[data-component=\"message-timeline\"] [data-component=\"text-part\"] [data-component=\"markdown\"] {\n line-height: 1.5625;\n}\n\n[data-component=\"message-timeline\"] [data-component=\"markdown\"] p {\n margin-bottom: 0.75rem;\n}\n\n[data-component=\"message-timeline\"] [data-component=\"markdown\"] :is(h1, h2, h3, h4, h5, h6) {\n margin-top: 1.5rem;\n margin-bottom: 0.5rem;\n}\n\n[data-component=\"message-timeline\"] [data-component=\"markdown\"] :is(ul, ol) {\n margin-top: 0.375rem;\n margin-bottom: 0.75rem;\n padding-left: 1.25rem;\n}\n\n[data-component=\"message-timeline\"] [data-component=\"markdown\"] ol {\n padding-left: 1.75rem;\n}\n\n[data-component=\"message-timeline\"] [data-component=\"markdown\"] li {\n margin-bottom: 0.25rem;\n}\n\n[data-component=\"message-timeline\"] [data-component=\"markdown\"] :is(blockquote, pre) {\n margin-top: 1rem;\n margin-bottom: 1rem;\n}\n\n[data-component=\"message-timeline\"] [data-component=\"markdown\"] hr {\n margin-block: 1.5rem;\n}\n\n[data-component=\"message-timeline\"] [data-component=\"markdown\"] > :last-child {\n margin-bottom: 0;\n}\n\n/* Tables scroll inside a narrow sidebar instead of overflowing it. */\n[data-component=\"message-timeline\"] [data-component=\"markdown\"] table {\n display: block;\n max-width: 100%;\n overflow-x: auto;\n}\n\n[data-slot=\"mux-tool-output\"] {\n padding: 8px 4px 4px;\n\n pre {\n margin: 0;\n max-height: 320px;\n overflow: auto;\n padding: 8px 12px;\n border: 1px solid var(--border-weak-base);\n border-radius: var(--radius-lg);\n background: var(--surface-raised-base);\n color: var(--text-base);\n font-family: var(--font-family-mono);\n font-size: 12px;\n line-height: 18px;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n }\n\n pre[data-status=\"error\"] {\n color: var(--text-critical-base, var(--icon-critical-base));\n }\n}\n\n[data-slot=\"mux-chat-error\"],\n[data-slot=\"mux-chat-notice\"] {\n color: var(--text-critical-base, var(--icon-critical-base));\n font-size: var(--font-size-small);\n line-height: var(--line-height-large);\n}\n\n[data-slot=\"mux-chat-notice\"] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 0 8px;\n\n > span {\n flex: 1;\n min-width: 0;\n }\n\n [data-action=\"retry\"] {\n flex: none;\n color: var(--text-strong);\n }\n}\n\n/* ----------------------------------------------------------- empty state */\n\n[data-slot=\"mux-chat-empty\"] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-block: auto;\n padding: 24px 18px;\n}\n\n[data-slot=\"mux-chat-empty-title\"] {\n color: var(--text-strong);\n font-size: var(--font-size-large);\n font-weight: var(--font-weight-medium);\n line-height: 24px;\n}\n\n[data-slot=\"mux-chat-empty-subtitle\"] {\n color: var(--text-weak);\n}\n\n[data-slot=\"mux-chat-suggestions\"] {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 6px;\n margin-top: 10px;\n}\n\n[data-slot=\"mux-chat-suggestion\"] {\n max-width: 100%;\n padding: 6px 12px;\n border: 1px solid var(--border-weak-base);\n border-radius: 9999px;\n background: var(--surface-raised-base);\n color: var(--text-base);\n font-size: var(--font-size-small);\n line-height: 20px;\n text-align: start;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n\n &:hover {\n background: var(--surface-raised-base-hover);\n border-color: var(--border-base);\n }\n}\n\n/* --------------------------------------------------------- dock/composer */\n\n[data-slot=\"mux-chat-dock\"] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 0 8px;\n}\n\n[data-component=\"prompt-composer-surface\"] {\n position: relative;\n display: flex;\n flex-direction: column;\n overflow: clip;\n border: 1px solid var(--border-weak-base);\n border-bottom-width: 0;\n border-radius: 16px 16px 0 0;\n --prompt-composer-fill: var(--surface-raised-stronger-non-alpha);\n background: var(--prompt-composer-fill);\n\n &:focus-within {\n border-color: var(--border-base);\n }\n\n &[aria-busy=\"true\"] {\n pointer-events: none;\n }\n\n > [data-dock-surface=\"shell\"] {\n border-radius: 0;\n box-shadow: none;\n background: transparent;\n }\n\n > [data-component=\"prompt-controls\"] {\n margin-top: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n }\n}\n\n[data-component=\"prompt-input-shell\"] {\n flex: none;\n min-height: 32px;\n}\n\n[data-component=\"prompt-input-scroll\"] {\n position: relative;\n max-height: 240px;\n overflow-y: auto;\n scrollbar-width: none;\n}\n\n[data-component=\"prompt-input\"] {\n display: block;\n width: 100%;\n min-height: 30px;\n resize: none;\n border: 0;\n outline: none;\n background: transparent;\n padding: 8px 16px var(--prompt-inset);\n color: var(--text-strong);\n font-size: 13px;\n line-height: 20px;\n\n &::placeholder {\n color: var(--text-weaker);\n }\n}\n\n[data-component=\"prompt-controls-inner\"] {\n padding: 1px 10px;\n}\n\n[data-component=\"prompt-control-row\"] {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n min-height: 36px;\n}\n\n[data-component=\"prompt-control-left\"] {\n display: flex;\n align-items: center;\n gap: 2px;\n flex: 1;\n min-width: 0;\n}\n\n[data-component=\"prompt-control-right\"] {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: none;\n margin-left: auto;\n}\n\n[data-component=\"prompt-model-control\"] {\n position: relative;\n min-width: 0;\n max-width: 14rem;\n display: flex;\n align-items: center;\n}\n\n[data-action=\"prompt-model\"] {\n appearance: none;\n field-sizing: content;\n height: 28px;\n min-width: 0;\n max-width: 100%;\n padding: 0 22px 0 8px;\n border: 0;\n border-radius: var(--radius-md);\n background: transparent;\n color: var(--text-base);\n font-size: var(--font-size-small);\n font-weight: var(--font-weight-medium);\n text-overflow: ellipsis;\n cursor: pointer;\n transition: background-color 0.15s ease;\n\n &:hover:not(:disabled) {\n background: var(--surface-base-hover);\n }\n\n &:focus-visible {\n outline: none;\n box-shadow: var(--shadow-xs-border-focus);\n }\n\n option,\n optgroup {\n background: var(--background-stronger);\n color: var(--text-base);\n }\n}\n\n[data-slot=\"prompt-model-chevron\"] {\n position: absolute;\n right: 6px;\n display: inline-flex;\n color: var(--icon-weak-base);\n pointer-events: none;\n}\n\n[data-component=\"prompt-submit-control\"] {\n display: flex;\n width: 28px;\n height: 28px;\n flex: none;\n align-items: center;\n justify-content: center;\n}\n\n[data-action=\"prompt-submit\"] {\n width: 24px;\n height: 24px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 9999px;\n}\n\n/* ---------------------------------------------------------- question dock */\n\n[data-component=\"mux-question\"],\n[data-component=\"mux-permission\"] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 12px;\n border: 1px solid var(--border-weak-base);\n border-radius: 12px;\n background: var(--surface-raised-stronger-non-alpha);\n}\n\n[data-component=\"mux-permission\"] {\n gap: 8px;\n}\n\n[data-slot=\"mux-permission-patterns\"] {\n max-height: 96px;\n overflow: auto;\n padding: 6px 8px;\n border-radius: var(--radius-md);\n background: var(--surface-inset-base);\n color: var(--text-base);\n font-family: var(--font-family-mono);\n font-size: 12px;\n line-height: 18px;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n[data-slot=\"mux-question-item\"] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n[data-slot=\"mux-question-header\"] {\n color: var(--text-weak);\n font-size: 12px;\n font-weight: var(--font-weight-medium);\n text-transform: uppercase;\n letter-spacing: 0.02em;\n}\n\n[data-slot=\"mux-question-text\"] {\n color: var(--text-strong);\n font-weight: var(--font-weight-medium);\n}\n\n[data-slot=\"mux-question-options\"] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n[data-slot=\"mux-question-option\"] {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n padding: 8px 10px;\n border: 1px solid var(--border-weak-base);\n border-radius: var(--radius-lg);\n text-align: start;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n\n &:hover {\n background: var(--surface-base-hover);\n }\n\n &[aria-checked=\"true\"] {\n border-color: var(--border-selected);\n background: var(--surface-base-interactive-active);\n }\n}\n\n[data-slot=\"mux-question-option-description\"] {\n color: var(--text-weak);\n font-size: var(--font-size-small);\n}\n\n[data-slot=\"mux-question-custom\"] {\n height: 34px;\n padding: 0 10px;\n border: 1px solid var(--border-weak-base);\n border-radius: var(--radius-lg);\n background: transparent;\n outline: none;\n\n &:focus {\n border-color: var(--border-base);\n }\n}\n\n[data-slot=\"mux-question-actions\"] {\n display: flex;\n justify-content: flex-end;\n gap: 6px;\n}\n\n[data-slot=\"mux-button\"] {\n height: 30px;\n padding: 0 12px;\n border-radius: var(--radius-md);\n font-size: var(--font-size-small);\n font-weight: var(--font-weight-medium);\n\n &[data-variant=\"ghost\"]:hover {\n background: var(--surface-base-hover);\n }\n\n &[data-variant=\"primary\"] {\n background: var(--icon-strong-base);\n color: var(--icon-invert-base);\n }\n\n &[data-variant=\"primary\"]:disabled {\n background: var(--icon-strong-disabled);\n }\n}\n"
23
+ ].join("\n");
24
+ //#endregion
25
+ //#region src/model.ts
26
+ /** Connected providers and their models, in runtime order. */
27
+ function modelGroups(inventory) {
28
+ return inventory.all.filter((provider) => inventory.connected.includes(provider.id)).map((provider) => ({
29
+ id: provider.id,
30
+ label: provider.name || provider.id,
31
+ models: Object.values(provider.models).map((model) => ({
32
+ value: `${provider.id}/${model.id}`,
33
+ label: model.name || model.id
34
+ }))
35
+ })).filter((group) => group.models.length > 0);
36
+ }
37
+ /**
38
+ * The model to use: the user's stored pick, else the app's preference, else a
39
+ * connected provider's default, else the first available. `undefined` when
40
+ * nothing is available.
41
+ */
42
+ function chooseModel(groups, inventory, stored, preferred) {
43
+ const available = new Set(groups.flatMap((group) => group.models.map((model) => model.value)));
44
+ return [
45
+ stored,
46
+ preferred,
47
+ ...inventory.connected.map((id) => inventory.default[id] ? `${id}/${inventory.default[id]}` : ""),
48
+ groups[0]?.models[0]?.value
49
+ ].find((value) => !!value && available.has(value));
50
+ }
51
+ function parseModel(value) {
52
+ const slash = value?.indexOf("/") ?? -1;
53
+ return value && slash > 0 ? {
54
+ providerID: value.slice(0, slash),
55
+ modelID: value.slice(slash + 1)
56
+ } : void 0;
57
+ }
58
+ /** Parts a reader sees, in order: text, non-empty reasoning, and tool calls. */
59
+ function visibleParts(parts) {
60
+ return parts.filter((part) => part.type === "text" && !part.synthetic && !part.ignored && part.text.trim() !== "" || part.type === "reasoning" && part.text.trim() !== "" || part.type === "tool");
61
+ }
62
+ var BUILTIN_TOOLS = {
63
+ websearch: "Searching the web",
64
+ webfetch: "Reading page",
65
+ question: "Question"
66
+ };
67
+ /** "add_to_watchlist" → "Add to watchlist". */
68
+ var humanize = (name) => {
69
+ const words = name.replace(/[_-]+/g, " ").trim();
70
+ return words ? words[0].toUpperCase() + words.slice(1) : name;
71
+ };
72
+ function toolTitle(tool, labels = {}) {
73
+ return labels[tool] ?? BUILTIN_TOOLS[tool] ?? humanize(tool);
74
+ }
75
+ var INPUT_KEYS = [
76
+ "description",
77
+ "query",
78
+ "url",
79
+ "name",
80
+ "symbol",
81
+ "watchlist",
82
+ "path",
83
+ "pattern"
84
+ ];
85
+ /** One line under the tool name: the tool's own title once it has one, else its most telling input. */
86
+ function toolSubtitle(state) {
87
+ if ((state.status === "completed" || state.status === "running") && state.title) return state.title;
88
+ const input = state.input ?? {};
89
+ for (const key of INPUT_KEYS) {
90
+ const value = input[key];
91
+ if (typeof value === "string" && value) return value;
92
+ }
93
+ for (const value of Object.values(input)) {
94
+ if (typeof value === "string" && value) return value;
95
+ if (Array.isArray(value) && value.length && value.every((item) => typeof item === "string")) return value.join(", ");
96
+ }
97
+ return "";
98
+ }
99
+ var toolActive = (part) => part.state.status === "pending" || part.state.status === "running";
100
+ function toolDetail(state) {
101
+ if (state.status === "error") return state.error;
102
+ if (state.status === "completed") return state.output;
103
+ if (state.status === "running") return state.output ?? "";
104
+ return "";
105
+ }
106
+ var seconds = (start, end) => `${Math.max(0, (end - start) / 1e3).toFixed(1)}s`;
107
+ var sameIDs = (a, b) => a.length === b.length && a.every((id, index) => id === b[index]);
108
+ //#endregion
109
+ //#region src/controller.ts
110
+ var idle = {
111
+ connected: false,
112
+ ready: false,
113
+ historyLoading: false,
114
+ historyError: "",
115
+ snapshotError: "",
116
+ error: "",
117
+ ended: false
118
+ };
119
+ var storage = {
120
+ get(key) {
121
+ try {
122
+ return localStorage.getItem(key) ?? void 0;
123
+ } catch {
124
+ return;
125
+ }
126
+ },
127
+ set(key, value) {
128
+ try {
129
+ if (value === void 0) localStorage.removeItem(key);
130
+ else localStorage.setItem(key, value);
131
+ } catch {}
132
+ }
133
+ };
134
+ function createChatController(options) {
135
+ let disposed = false;
136
+ const app = createAppClient({ url: options.url });
137
+ const { client } = app;
138
+ const store = createMemoryStore();
139
+ const [state, setState] = createSignal(store.state());
140
+ const [view, setView] = createSignal(idle);
141
+ const [sessionID, setSessionID] = createSignal();
142
+ const [notice, setNotice] = createSignal();
143
+ const [grantError, setGrantError] = createSignal();
144
+ const [tools, setTools] = createSignal(/* @__PURE__ */ new Map());
145
+ const [inventory, setInventory] = createSignal();
146
+ const [offline, setOffline] = createSignal(false);
147
+ const [delivering, setDelivering] = createSignal(false);
148
+ const describe = (error) => error instanceof Error ? error.message : String(error);
149
+ const report = (error) => setNotice(describe(error));
150
+ const connect = (workspaceID) => createChatSession({
151
+ store,
152
+ transport: createRuntimeTransport(client, { workspaceID })
153
+ });
154
+ let session;
155
+ let frame;
156
+ const publish = () => {
157
+ if (frame !== void 0 || disposed) return;
158
+ frame = requestAnimationFrame(() => {
159
+ frame = void 0;
160
+ batch(() => {
161
+ setState(store.state());
162
+ setView(session ? session.view() : idle);
163
+ });
164
+ });
165
+ };
166
+ const unsubscribe = store.subscribe(publish);
167
+ const timers = /* @__PURE__ */ new Map();
168
+ const schedule = (name, ms, run) => {
169
+ clearTimeout(timers.get(name));
170
+ timers.set(name, setTimeout(() => {
171
+ timers.delete(name);
172
+ if (!disposed) run();
173
+ }, ms));
174
+ };
175
+ onCleanup(() => {
176
+ disposed = true;
177
+ for (const timer of timers.values()) clearTimeout(timer);
178
+ if (frame !== void 0) cancelAnimationFrame(frame);
179
+ unsubscribe();
180
+ session?.dispose();
181
+ });
182
+ const fetchGrant = async () => {
183
+ const next = await app.refreshGrant();
184
+ if (!next?.token || !next.workspaceID) throw new Error("Chat is unavailable (invalid grant)");
185
+ setTools(new Map((next.tools ?? []).map((tool) => [tool.name, tool])));
186
+ setGrantError(void 0);
187
+ schedule("grant", Math.max(1e4, (next.expiresAt - Date.now()) * .8), () => void renew(0));
188
+ };
189
+ const renew = async (attempt) => {
190
+ try {
191
+ await fetchGrant();
192
+ } catch (error) {
193
+ setGrantError(describe(error));
194
+ schedule("grant", Math.min(6e4, 15e3 * 2 ** attempt), () => void renew(attempt + 1));
195
+ }
196
+ };
197
+ const sessionKey = () => `${options.storageKey}:session:${app.grant()?.workspaceID}`;
198
+ const modelKey = `${options.storageKey}:model`;
199
+ const open = async (resume) => {
200
+ const opened = await client.openSession({
201
+ workspaceID: app.grant().workspaceID,
202
+ sessionID: resume,
203
+ title: options.sessionTitle
204
+ });
205
+ if (disposed) return;
206
+ storage.set(sessionKey(), opened.session.id);
207
+ session?.dispose();
208
+ session = connect(opened.workspaceID);
209
+ session.subscribe(publish);
210
+ setSessionID(opened.session.id);
211
+ session.start(opened.session.id);
212
+ publish();
213
+ };
214
+ const loadModels = async () => {
215
+ try {
216
+ setInventory(await client.providers());
217
+ setOffline(false);
218
+ } catch (error) {
219
+ console.warn("[mux-chat]", error);
220
+ setOffline(true);
221
+ schedule("models", 15e3, () => void loadModels());
222
+ }
223
+ };
224
+ const boot = async () => {
225
+ try {
226
+ await fetchGrant();
227
+ } catch (error) {
228
+ setGrantError(describe(error));
229
+ schedule("boot", 15e3, () => void boot());
230
+ return;
231
+ }
232
+ try {
233
+ await open(storage.get(sessionKey()));
234
+ setNotice(void 0);
235
+ loadModels();
236
+ } catch (error) {
237
+ report(error);
238
+ schedule("boot", 15e3, () => void boot());
239
+ }
240
+ };
241
+ boot();
242
+ const turns = createMemo(() => {
243
+ const id = sessionID();
244
+ return id ? sessionTurns(state(), id) : [];
245
+ });
246
+ const turnsByID = createMemo(() => new Map(turns().map((turn) => [turn.message.id, turn])));
247
+ const messageIDs = createMemo(() => turns().map((turn) => turn.message.id), [], { equals: sameIDs });
248
+ const streaming = createMemo(() => {
249
+ const id = sessionID();
250
+ return !!id && isSessionStreaming(state(), id);
251
+ });
252
+ const questions = createMemo(() => {
253
+ const id = sessionID();
254
+ return id ? sessionQuestions(state(), id) : [];
255
+ });
256
+ const permissions = createMemo(() => {
257
+ const id = sessionID();
258
+ return id ? sessionPermissions(state(), id) : [];
259
+ });
260
+ const seen = /* @__PURE__ */ new Set();
261
+ let live = false;
262
+ createEffect(on(turns, (current) => {
263
+ for (const turn of current) for (const part of turn.parts) {
264
+ if (part.type !== "tool" || part.state.status !== "completed" || seen.has(part.id)) continue;
265
+ seen.add(part.id);
266
+ if (live) options.onToolResult?.({
267
+ tool: part.tool,
268
+ title: part.state.title,
269
+ input: part.state.input,
270
+ output: part.state.output,
271
+ sessionID: part.sessionID,
272
+ readOnly: tools().get(part.tool)?.readOnly ?? true
273
+ });
274
+ }
275
+ if (untrack(view).ready) live = true;
276
+ }));
277
+ const [modelValue, setModelValue] = createSignal(storage.get(modelKey) ?? "");
278
+ const selectModel = (value) => {
279
+ setModelValue(value);
280
+ storage.set(modelKey, value);
281
+ };
282
+ const groups = createMemo(() => {
283
+ const inv = inventory();
284
+ return inv ? modelGroups(inv) : [];
285
+ });
286
+ createEffect(on(groups, (current) => {
287
+ const inv = inventory();
288
+ if (!inv || !current.length) return;
289
+ const choice = chooseModel(current, inv, untrack(modelValue), options.preferredModel);
290
+ if (choice && choice !== untrack(modelValue)) selectModel(choice);
291
+ }));
292
+ const status = createMemo(() => {
293
+ if (offline()) return {
294
+ tone: "bad",
295
+ text: "Offline"
296
+ };
297
+ if (inventory() && !groups().length) return {
298
+ tone: "bad",
299
+ text: "No models available"
300
+ };
301
+ const current = view();
302
+ if (current.connected) return {
303
+ tone: "ok",
304
+ text: "Connected"
305
+ };
306
+ return current.ready ? {
307
+ tone: "bad",
308
+ text: "Reconnecting…"
309
+ } : {
310
+ tone: "busy",
311
+ text: "Connecting…"
312
+ };
313
+ });
314
+ const withSession = (action) => async () => {
315
+ const id = sessionID();
316
+ if (!id) return;
317
+ try {
318
+ await action(id);
319
+ } catch (error) {
320
+ report(error);
321
+ }
322
+ };
323
+ const deliver = async (target, submission) => {
324
+ setDelivering(true);
325
+ try {
326
+ return await target.send(submission);
327
+ } finally {
328
+ setDelivering(false);
329
+ }
330
+ };
331
+ return {
332
+ /** Changes once per rendered frame while the transcript updates. */
333
+ changes: state,
334
+ sessionID,
335
+ /** Labels from the app's tool definitions. */
336
+ toolLabels: createMemo(() => Object.fromEntries([...tools()].flatMap(([name, tool]) => tool.label ? [[name, tool.label]] : []))),
337
+ messageIDs,
338
+ turn: (id) => turnsByID().get(id),
339
+ questions,
340
+ permissions,
341
+ streaming,
342
+ ready: () => view().ready,
343
+ view,
344
+ status,
345
+ error: () => view().error || view().snapshotError || grantError() || notice() || "",
346
+ /** A message is shown but its delivery was not confirmed; `retry()` completes it. */
347
+ unconfirmed: () => !!view().pending && !delivering(),
348
+ modelGroups: groups,
349
+ modelValue,
350
+ selectModel,
351
+ async send(text) {
352
+ const target = session;
353
+ const id = sessionID();
354
+ const trimmed = text.trim();
355
+ if (!target || !id || !trimmed || !view().ready) return "failed";
356
+ setNotice(void 0);
357
+ const pending = target.view().pending;
358
+ if (pending && !await deliver(target, pending)) return "failed";
359
+ const submission = textSubmission({
360
+ sessionID: id,
361
+ text: trimmed,
362
+ agent: options.agent,
363
+ model: parseModel(modelValue())
364
+ });
365
+ if (await deliver(target, submission)) return "sent";
366
+ return target.view().pending === submission ? "unconfirmed" : "failed";
367
+ },
368
+ async retry() {
369
+ const target = session;
370
+ const pending = target?.view().pending;
371
+ if (target && pending && !delivering()) await deliver(target, pending);
372
+ },
373
+ abort: withSession((id) => client.abort(id)),
374
+ answer: (requestID, answers) => withSession(() => client.answerQuestion(requestID, answers))(),
375
+ reject: (requestID) => withSession(() => client.rejectQuestion(requestID))(),
376
+ replyPermission: (requestID, response) => withSession((id) => client.replyPermission(id, requestID, response))(),
377
+ /** Loads the next older page of history, if any. */
378
+ older: () => {
379
+ if (view().cursor && !view().historyLoading) session?.older();
380
+ },
381
+ async newChat() {
382
+ if (!app.grant()) return;
383
+ try {
384
+ session?.dispose();
385
+ session = void 0;
386
+ setSessionID(void 0);
387
+ setView(idle);
388
+ await open(void 0);
389
+ } catch (error) {
390
+ report(error);
391
+ }
392
+ }
393
+ };
394
+ }
395
+ //#endregion
396
+ //#region src/markdown.ts
397
+ var marked = new Marked({
398
+ gfm: true,
399
+ breaks: false
400
+ });
401
+ var purify;
402
+ function sanitizer() {
403
+ if (!purify) {
404
+ purify = createDOMPurify(window);
405
+ purify.addHook("afterSanitizeAttributes", (node) => {
406
+ if (node.tagName === "A" && node.getAttribute("href")) {
407
+ node.setAttribute("target", "_blank");
408
+ node.setAttribute("rel", "noopener noreferrer");
409
+ }
410
+ });
411
+ }
412
+ return purify;
413
+ }
414
+ /** Model output as sanitized HTML. */
415
+ function renderMarkdown(text) {
416
+ return sanitizer().sanitize(marked.parse(text, { async: false }));
417
+ }
418
+ //#endregion
419
+ //#region src/view/primitives.tsx
420
+ var _tmpl$$3 = /*#__PURE__*/ template(`<span data-component=text-shimmer style=--text-shimmer-swap:220ms><span data-slot=text-shimmer-char><span data-slot=text-shimmer-char-base aria-hidden=true></span><span data-slot=text-shimmer-char-shimmer aria-hidden=true>`);
421
+ var _tmpl$2$2 = /*#__PURE__*/ template(`<span data-component=icon data-size=small><svg data-slot=icon-svg width=16 height=16 viewBox="0 0 16 16"stroke-width=1.5 stroke-linecap=round stroke-linejoin=round aria-hidden=true><path>`);
422
+ var SWAP_MS = 220;
423
+ /** Mux's text shimmer (ui/components/text-shimmer): an animated sweep while `active`. */
424
+ function TextShimmer(props) {
425
+ const [run, setRun] = createSignal(props.active);
426
+ let timer;
427
+ createEffect(() => {
428
+ clearTimeout(timer);
429
+ if (props.active) setRun(true);
430
+ else timer = setTimeout(() => setRun(false), SWAP_MS);
431
+ });
432
+ onCleanup(() => clearTimeout(timer));
433
+ return (() => {
434
+ var _el$ = _tmpl$$3(), _el$3 = _el$.firstChild.firstChild, _el$4 = _el$3.nextSibling;
435
+ insert(_el$3, () => props.text);
436
+ insert(_el$4, () => props.text);
437
+ effect((_p$) => {
438
+ var _v$ = props.active ? "true" : "false", _v$2 = props.text, _v$3 = `${props.offset ?? 0}`, _v$4 = run() ? "true" : "false";
439
+ _v$ !== _p$.e && setAttribute(_el$, "data-active", _p$.e = _v$);
440
+ _v$2 !== _p$.t && setAttribute(_el$, "aria-label", _p$.t = _v$2);
441
+ _v$3 !== _p$.a && setStyleProperty(_el$, "--text-shimmer-index", _p$.a = _v$3);
442
+ _v$4 !== _p$.o && setAttribute(_el$4, "data-run", _p$.o = _v$4);
443
+ return _p$;
444
+ }, {
445
+ e: void 0,
446
+ t: void 0,
447
+ a: void 0,
448
+ o: void 0
449
+ });
450
+ return _el$;
451
+ })();
452
+ }
453
+ var svg = (path, filled = false) => () => (() => {
454
+ var _el$5 = _tmpl$2$2(), _el$6 = _el$5.firstChild, _el$7 = _el$6.firstChild;
455
+ setAttribute(_el$6, "fill", filled ? "currentColor" : "none");
456
+ setAttribute(_el$6, "stroke", filled ? "none" : "currentColor");
457
+ setAttribute(_el$7, "d", path);
458
+ return _el$5;
459
+ })();
460
+ var ChevronDown = svg("M4 6l4 4 4-4");
461
+ var ArrowUp = svg("M8 13V3.5M3.5 8 8 3.5 12.5 8");
462
+ var Stop = svg("M4.5 4.5h7v7h-7z", true);
463
+ var Plus = svg("M8 3v10M3 8h10");
464
+ //#endregion
465
+ //#region src/view/parts.tsx
466
+ var _tmpl$$2 = /*#__PURE__*/ template(`<div data-slot=collapsible-arrow data-size=compact><span data-slot=collapsible-arrow-icon>`);
467
+ var _tmpl$2$1 = /*#__PURE__*/ template(`<div data-slot=collapsible-content data-expanded>`);
468
+ var _tmpl$3$1 = /*#__PURE__*/ template(`<div data-component=collapsible data-variant=normal class=tool-collapsible><button type=button data-slot=collapsible-trigger><div data-component=tool-trigger data-layout=activity-row><div data-slot=basic-tool-tool-trigger-content><div data-slot=basic-tool-tool-info><div data-slot=basic-tool-tool-info-structured><div data-slot=basic-tool-tool-info-main><span data-slot=basic-tool-tool-title></span><span data-slot=basic-tool-tool-detail dir=ltr>`);
469
+ var _tmpl$4$1 = /*#__PURE__*/ template(`<span data-slot=basic-tool-tool-subtitle>`);
470
+ var _tmpl$5$1 = /*#__PURE__*/ template(`<div data-slot=mux-tool-output><pre>`);
471
+ var _tmpl$6$1 = /*#__PURE__*/ template(`<div data-component=reasoning-part><div data-component=markdown>`);
472
+ var _tmpl$7$1 = /*#__PURE__*/ template(`<div data-component=text-part><div data-component=markdown>`);
473
+ /** One collapsible activity row (Mux BasicTool). */
474
+ function ActivityRow(props) {
475
+ const [open, setOpen] = createSignal(false);
476
+ const expandable = () => props.children !== void 0;
477
+ return (() => {
478
+ var _el$ = _tmpl$3$1(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$8 = _el$3.firstChild.firstChild.firstChild.firstChild.firstChild, _el$9 = _el$8.nextSibling;
479
+ _el$2.$$click = () => setOpen(!open());
480
+ insert(_el$8, createComponent(TextShimmer, {
481
+ get text() {
482
+ return props.title;
483
+ },
484
+ get active() {
485
+ return props.active;
486
+ }
487
+ }));
488
+ insert(_el$9, createComponent(Show, {
489
+ get when() {
490
+ return props.subtitle;
491
+ },
492
+ children: (subtitle) => (() => {
493
+ var _el$11 = _tmpl$4$1();
494
+ insert(_el$11, subtitle);
495
+ return _el$11;
496
+ })()
497
+ }));
498
+ insert(_el$3, createComponent(Show, {
499
+ get when() {
500
+ return expandable();
501
+ },
502
+ get children() {
503
+ var _el$0 = _tmpl$$2(), _el$1 = _el$0.firstChild;
504
+ insert(_el$1, createComponent(ChevronDown, {}));
505
+ return _el$0;
506
+ }
507
+ }), null);
508
+ insert(_el$, createComponent(Show, {
509
+ get when() {
510
+ return memo(() => !!open())() && expandable();
511
+ },
512
+ get children() {
513
+ var _el$10 = _tmpl$2$1();
514
+ insert(_el$10, () => props.children);
515
+ return _el$10;
516
+ }
517
+ }), null);
518
+ effect((_p$) => {
519
+ var _v$ = props.name, _v$2 = props.status, _v$3 = open() ? "" : void 0, _v$4 = open() ? void 0 : "", _v$5 = open(), _v$6 = !expandable();
520
+ _v$ !== _p$.e && setAttribute(_el$, "data-tool", _p$.e = _v$);
521
+ _v$2 !== _p$.t && setAttribute(_el$, "data-status", _p$.t = _v$2);
522
+ _v$3 !== _p$.a && setAttribute(_el$, "data-expanded", _p$.a = _v$3);
523
+ _v$4 !== _p$.o && setAttribute(_el$, "data-closed", _p$.o = _v$4);
524
+ _v$5 !== _p$.i && setAttribute(_el$2, "aria-expanded", _p$.i = _v$5);
525
+ _v$6 !== _p$.n && (_el$2.disabled = _p$.n = _v$6);
526
+ return _p$;
527
+ }, {
528
+ e: void 0,
529
+ t: void 0,
530
+ a: void 0,
531
+ o: void 0,
532
+ i: void 0,
533
+ n: void 0
534
+ });
535
+ return _el$;
536
+ })();
537
+ }
538
+ function ToolRow(props) {
539
+ const detail = createMemo(() => toolDetail(props.part.state).slice(0, 2e4));
540
+ return createComponent(ActivityRow, {
541
+ get title() {
542
+ return toolTitle(props.part.tool, props.labels);
543
+ },
544
+ get subtitle() {
545
+ return toolSubtitle(props.part.state);
546
+ },
547
+ get active() {
548
+ return toolActive(props.part);
549
+ },
550
+ get name() {
551
+ return props.part.tool;
552
+ },
553
+ get status() {
554
+ return props.part.state.status;
555
+ },
556
+ get children() {
557
+ return memo(() => !!detail())() ? (() => {
558
+ var _el$12 = _tmpl$5$1(), _el$13 = _el$12.firstChild;
559
+ insert(_el$13, detail);
560
+ effect(() => setAttribute(_el$13, "data-status", props.part.state.status));
561
+ return _el$12;
562
+ })() : void 0;
563
+ }
564
+ });
565
+ }
566
+ function ReasoningRow(props) {
567
+ const active = () => props.live && props.part.time?.end === void 0;
568
+ const duration = () => props.part.time?.end ? seconds(props.part.time.start, props.part.time.end) : void 0;
569
+ return createComponent(ActivityRow, {
570
+ get title() {
571
+ return active() ? "Thinking" : "Thought";
572
+ },
573
+ get subtitle() {
574
+ return duration();
575
+ },
576
+ get active() {
577
+ return active();
578
+ },
579
+ name: "reasoning",
580
+ get children() {
581
+ var _el$14 = _tmpl$6$1(), _el$15 = _el$14.firstChild;
582
+ effect(() => _el$15.innerHTML = renderMarkdown(props.part.text));
583
+ return _el$14;
584
+ }
585
+ });
586
+ }
587
+ function TextPartView(props) {
588
+ return (() => {
589
+ var _el$16 = _tmpl$7$1(), _el$17 = _el$16.firstChild;
590
+ effect(() => _el$17.innerHTML = renderMarkdown(props.part.text));
591
+ return _el$16;
592
+ })();
593
+ }
594
+ function PartView(props) {
595
+ return createComponent(Switch, { get children() {
596
+ return [
597
+ createComponent(Match, {
598
+ get when() {
599
+ return memo(() => props.part.type === "text")() && props.part;
600
+ },
601
+ children: (part) => createComponent(TextPartView, { get part() {
602
+ return part();
603
+ } })
604
+ }),
605
+ createComponent(Match, {
606
+ get when() {
607
+ return memo(() => props.part.type === "reasoning")() && props.part;
608
+ },
609
+ children: (part) => createComponent(ReasoningRow, {
610
+ get part() {
611
+ return part();
612
+ },
613
+ get live() {
614
+ return props.live;
615
+ }
616
+ })
617
+ }),
618
+ createComponent(Match, {
619
+ get when() {
620
+ return memo(() => props.part.type === "tool")() && props.part;
621
+ },
622
+ children: (part) => createComponent(ToolRow, {
623
+ get part() {
624
+ return part();
625
+ },
626
+ get labels() {
627
+ return props.labels;
628
+ }
629
+ })
630
+ })
631
+ ];
632
+ } });
633
+ }
634
+ delegateEvents(["click"]);
635
+ //#endregion
636
+ //#region src/view/Chat.tsx
637
+ var _tmpl$$1 = /*#__PURE__*/ template(`<div data-component=assistant-message>`);
638
+ var _tmpl$2 = /*#__PURE__*/ template(`<div data-component=user-message><div data-slot=user-message-body><div data-slot=user-message-text>`);
639
+ var _tmpl$3 = /*#__PURE__*/ template(`<div data-slot=mux-chat-error role=alert>`);
640
+ var _tmpl$4 = /*#__PURE__*/ template(`<div data-component=mux-question data-dock-surface=shell role=group aria-label="Question from the assistant"><div data-slot=mux-question-actions><button type=button data-slot=mux-button data-variant=ghost>Skip</button><button type=button data-slot=mux-button data-variant=primary>Answer`);
641
+ var _tmpl$5 = /*#__PURE__*/ template(`<div data-slot=mux-question-header>`);
642
+ var _tmpl$6 = /*#__PURE__*/ template(`<input data-slot=mux-question-custom placeholder="Or type your own answer">`);
643
+ var _tmpl$7 = /*#__PURE__*/ template(`<div data-slot=mux-question-item><div data-slot=mux-question-text></div><div data-slot=mux-question-options>`);
644
+ var _tmpl$8 = /*#__PURE__*/ template(`<span data-slot=mux-question-option-description>`);
645
+ var _tmpl$9 = /*#__PURE__*/ template(`<button type=button data-slot=mux-question-option><span data-slot=mux-question-option-label>`);
646
+ var _tmpl$0 = /*#__PURE__*/ template(`<div data-slot=mux-permission-patterns>`);
647
+ var _tmpl$1 = /*#__PURE__*/ template(`<div data-component=mux-permission data-dock-surface=shell role=group aria-label="Permission request from the assistant"><div data-slot=mux-question-header>Permission</div><div data-slot=mux-question-text>The assistant wants to use <!>.</div><div data-slot=mux-question-actions><button type=button data-slot=mux-button data-variant=ghost data-reply=reject>Deny</button><button type=button data-slot=mux-button data-variant=ghost data-reply=always>Always allow</button><button type=button data-slot=mux-button data-variant=primary data-reply=once>Allow once`);
648
+ var _tmpl$10 = /*#__PURE__*/ template(`<span data-slot=mux-chat-subtitle>`);
649
+ var _tmpl$11 = /*#__PURE__*/ template(`<div data-slot=mux-chat-empty-subtitle>`);
650
+ var _tmpl$12 = /*#__PURE__*/ template(`<div data-slot=mux-chat-suggestions>`);
651
+ var _tmpl$13 = /*#__PURE__*/ template(`<div data-slot=mux-chat-empty><div data-slot=mux-chat-empty-title>`);
652
+ var _tmpl$14 = /*#__PURE__*/ template(`<div data-component=assistant-message data-live>`);
653
+ var _tmpl$15 = /*#__PURE__*/ template(`<button type=button data-slot=mux-button data-variant=ghost data-action=retry>Retry`);
654
+ var _tmpl$16 = /*#__PURE__*/ template(`<div data-slot=mux-chat-notice role=status><span>`);
655
+ var _tmpl$17 = /*#__PURE__*/ template(`<div data-component=mux-chat><header data-slot=mux-chat-header><div data-slot=mux-chat-heading><span data-slot=mux-chat-title></span></div><span data-slot=mux-chat-status><span data-slot=mux-chat-status-text></span></span><button type=button data-component=icon-button data-variant=ghost data-size=normal data-action=new-chat aria-label="New chat"title="New chat"></button></header><div data-component=message-timeline><div data-slot=session-turn-message-container></div></div><div data-slot=mux-chat-dock><div data-component=prompt-composer-surface><div data-dock-surface=shell data-component=prompt-input-shell style=--prompt-inset:2px><div data-component=prompt-input-scroll><textarea data-component=prompt-input rows=1></textarea></div></div><div data-dock-surface=tray data-dock-attach=top data-component=prompt-controls><div data-component=prompt-controls-inner><div data-component=prompt-control-row><div data-component=prompt-control-left><div data-component=prompt-model-control><select data-action=prompt-model aria-label=Model></select><span data-slot=prompt-model-chevron></span></div></div><div data-component=prompt-control-right><div data-component=prompt-submit-control><button type=button data-component=icon-button data-variant=primary data-size=normal data-icon-size=small data-action=prompt-submit>`);
656
+ var _tmpl$18 = /*#__PURE__*/ template(`<button type=button data-slot=mux-chat-suggestion>`);
657
+ var _tmpl$19 = /*#__PURE__*/ template(`<optgroup>`);
658
+ var _tmpl$20 = /*#__PURE__*/ template(`<option>`);
659
+ function TurnView(props) {
660
+ const message = () => props.turn()?.message;
661
+ const parts = createMemo(() => visibleParts(props.turn()?.parts ?? []));
662
+ const ids = createMemo(() => parts().map((part) => part.id), [], { equals: sameIDs });
663
+ const byID = createMemo(() => new Map(parts().map((part) => [part.id, part])));
664
+ const live = createMemo(() => {
665
+ const m = message();
666
+ return m?.role === "assistant" && m.time.completed === void 0 && props.streaming();
667
+ });
668
+ const error = () => {
669
+ const m = message();
670
+ const failure = m?.role === "assistant" ? m.error : void 0;
671
+ return failure && failure.name !== "MessageAbortedError" ? failure.data?.message ?? failure.name : void 0;
672
+ };
673
+ const userText = () => (props.turn()?.parts ?? []).flatMap((part) => part.type === "text" && !part.synthetic ? [part.text] : []).join("\n");
674
+ return createComponent(Show, {
675
+ get when() {
676
+ return message();
677
+ },
678
+ children: (m) => createComponent(Show, {
679
+ get when() {
680
+ return m().role === "assistant";
681
+ },
682
+ get fallback() {
683
+ return (() => {
684
+ var _el$2 = _tmpl$2(), _el$4 = _el$2.firstChild.firstChild;
685
+ insert(_el$4, userText);
686
+ effect(() => setAttribute(_el$2, "data-message-id", m().id));
687
+ return _el$2;
688
+ })();
689
+ },
690
+ get children() {
691
+ var _el$ = _tmpl$$1();
692
+ insert(_el$, createComponent(For, {
693
+ get each() {
694
+ return ids();
695
+ },
696
+ children: (id) => createComponent(Show, {
697
+ get when() {
698
+ return byID().get(id);
699
+ },
700
+ children: (part) => createComponent(PartView, {
701
+ get part() {
702
+ return part();
703
+ },
704
+ get live() {
705
+ return live();
706
+ },
707
+ get labels() {
708
+ return props.labels;
709
+ }
710
+ })
711
+ })
712
+ }), null);
713
+ insert(_el$, createComponent(Show, {
714
+ get when() {
715
+ return memo(() => !!live())() && !ids().length;
716
+ },
717
+ get children() {
718
+ return createComponent(ActivityRow, {
719
+ title: "Thinking",
720
+ active: true,
721
+ name: "thinking"
722
+ });
723
+ }
724
+ }), null);
725
+ insert(_el$, createComponent(Show, {
726
+ get when() {
727
+ return error();
728
+ },
729
+ children: (text) => (() => {
730
+ var _el$5 = _tmpl$3();
731
+ insert(_el$5, text);
732
+ return _el$5;
733
+ })()
734
+ }), null);
735
+ effect((_p$) => {
736
+ var _v$ = m().id, _v$2 = live() ? "" : void 0;
737
+ _v$ !== _p$.e && setAttribute(_el$, "data-message-id", _p$.e = _v$);
738
+ _v$2 !== _p$.t && setAttribute(_el$, "data-live", _p$.t = _v$2);
739
+ return _p$;
740
+ }, {
741
+ e: void 0,
742
+ t: void 0
743
+ });
744
+ return _el$;
745
+ }
746
+ })
747
+ });
748
+ }
749
+ function QuestionDock(props) {
750
+ const [answers, setAnswers] = createSignal(props.request.questions.map(() => []));
751
+ const set = (index, value) => setAnswers((previous) => previous.map((current, i) => i === index ? value : current));
752
+ const toggle = (index, label, multiple) => {
753
+ const current = answers()[index] ?? [];
754
+ set(index, multiple ? current.includes(label) ? current.filter((value) => value !== label) : [...current, label] : [label]);
755
+ };
756
+ return (() => {
757
+ var _el$6 = _tmpl$4(), _el$7 = _el$6.firstChild, _el$8 = _el$7.firstChild, _el$9 = _el$8.nextSibling;
758
+ insert(_el$6, createComponent(For, {
759
+ get each() {
760
+ return props.request.questions;
761
+ },
762
+ children: (question, index) => (() => {
763
+ var _el$0 = _tmpl$7(), _el$10 = _el$0.firstChild, _el$11 = _el$10.nextSibling;
764
+ insert(_el$0, createComponent(Show, {
765
+ get when() {
766
+ return question.header;
767
+ },
768
+ get children() {
769
+ var _el$1 = _tmpl$5();
770
+ insert(_el$1, () => question.header);
771
+ return _el$1;
772
+ }
773
+ }), _el$10);
774
+ insert(_el$10, () => question.question);
775
+ insert(_el$11, createComponent(For, {
776
+ get each() {
777
+ return question.options;
778
+ },
779
+ children: (option) => (() => {
780
+ var _el$13 = _tmpl$9(), _el$14 = _el$13.firstChild;
781
+ _el$13.$$click = () => toggle(index(), option.label, !!question.multiple);
782
+ insert(_el$14, () => option.label);
783
+ insert(_el$13, createComponent(Show, {
784
+ get when() {
785
+ return option.description;
786
+ },
787
+ get children() {
788
+ var _el$15 = _tmpl$8();
789
+ insert(_el$15, () => option.description);
790
+ return _el$15;
791
+ }
792
+ }), null);
793
+ effect((_p$) => {
794
+ var _v$3 = question.multiple ? "checkbox" : "radio", _v$4 = answers()[index()]?.includes(option.label) ?? false;
795
+ _v$3 !== _p$.e && setAttribute(_el$13, "role", _p$.e = _v$3);
796
+ _v$4 !== _p$.t && setAttribute(_el$13, "aria-checked", _p$.t = _v$4);
797
+ return _p$;
798
+ }, {
799
+ e: void 0,
800
+ t: void 0
801
+ });
802
+ return _el$13;
803
+ })()
804
+ }));
805
+ insert(_el$0, createComponent(Show, {
806
+ get when() {
807
+ return question.custom !== false;
808
+ },
809
+ get children() {
810
+ var _el$12 = _tmpl$6();
811
+ _el$12.$$input = (event) => set(index(), event.currentTarget.value.trim() ? [event.currentTarget.value.trim()] : []);
812
+ return _el$12;
813
+ }
814
+ }), null);
815
+ effect(() => setAttribute(_el$11, "role", question.multiple ? "group" : "radiogroup"));
816
+ return _el$0;
817
+ })()
818
+ }), _el$7);
819
+ _el$8.$$click = () => props.onSkip();
820
+ _el$9.$$click = () => props.onAnswer(answers());
821
+ effect(() => _el$9.disabled = !answers().every((answer) => answer.length > 0));
822
+ return _el$6;
823
+ })();
824
+ }
825
+ function PermissionDock(props) {
826
+ const patterns = () => (props.request.patterns ?? []).filter(Boolean);
827
+ const [replied, setReplied] = createSignal(false);
828
+ const reply = (response) => {
829
+ if (replied()) return;
830
+ setReplied(true);
831
+ props.onReply(response);
832
+ };
833
+ return (() => {
834
+ var _el$16 = _tmpl$1(), _el$18 = _el$16.firstChild.nextSibling, _el$21 = _el$18.firstChild.nextSibling;
835
+ _el$21.nextSibling;
836
+ var _el$23 = _el$18.nextSibling, _el$24 = _el$23.firstChild, _el$25 = _el$24.nextSibling, _el$26 = _el$25.nextSibling;
837
+ insert(_el$18, () => props.request.permission ?? "a tool", _el$21);
838
+ insert(_el$16, createComponent(Show, {
839
+ get when() {
840
+ return patterns().length;
841
+ },
842
+ get children() {
843
+ var _el$22 = _tmpl$0();
844
+ insert(_el$22, () => patterns().join("\n"));
845
+ return _el$22;
846
+ }
847
+ }), _el$23);
848
+ _el$24.$$click = () => reply("reject");
849
+ _el$25.$$click = () => reply("always");
850
+ _el$26.$$click = () => reply("once");
851
+ effect((_p$) => {
852
+ var _v$5 = replied(), _v$6 = replied(), _v$7 = replied();
853
+ _v$5 !== _p$.e && (_el$24.disabled = _p$.e = _v$5);
854
+ _v$6 !== _p$.t && (_el$25.disabled = _p$.t = _v$6);
855
+ _v$7 !== _p$.a && (_el$26.disabled = _p$.a = _v$7);
856
+ return _p$;
857
+ }, {
858
+ e: void 0,
859
+ t: void 0,
860
+ a: void 0
861
+ });
862
+ return _el$16;
863
+ })();
864
+ }
865
+ function Chat(props) {
866
+ const options = props.options;
867
+ const chat = createChatController({
868
+ url: options.url,
869
+ agent: options.agent,
870
+ sessionTitle: options.sessionTitle,
871
+ storageKey: options.storageKey,
872
+ preferredModel: options.preferredModel,
873
+ onToolResult: options.onToolResult
874
+ });
875
+ let timeline;
876
+ let input;
877
+ const [draft, setDraft] = createSignal("");
878
+ const labels = createMemo(() => ({
879
+ ...chat.toolLabels(),
880
+ ...options.toolLabels
881
+ }));
882
+ const grow = () => {
883
+ input.style.height = "auto";
884
+ input.style.height = `${Math.min(input.scrollHeight, 240)}px`;
885
+ };
886
+ const clear = () => {
887
+ input.value = "";
888
+ setDraft("");
889
+ grow();
890
+ };
891
+ const restore = (text) => {
892
+ input.value = text;
893
+ setDraft(text);
894
+ grow();
895
+ };
896
+ /** Sends `text`; text that was not delivered (and is not shown as pending) goes back into an empty composer. */
897
+ const sendText = async (text) => {
898
+ const result = await chat.send(text);
899
+ if (result === "failed" && !draft()) restore(text);
900
+ return result === "sent";
901
+ };
902
+ const submit = async () => {
903
+ const text = draft();
904
+ if (!text.trim() || !chat.ready()) return;
905
+ clear();
906
+ await sendText(text);
907
+ };
908
+ let waiting = [];
909
+ let queue = Promise.resolve();
910
+ const sendFromHost = (text) => new Promise((resolve) => {
911
+ waiting.push({
912
+ text,
913
+ resolve
914
+ });
915
+ if (chat.ready()) flush();
916
+ });
917
+ const flush = () => {
918
+ const batch = waiting;
919
+ waiting = [];
920
+ for (const { text, resolve } of batch) queue = queue.then(() => sendText(text).then(resolve, () => resolve(false)));
921
+ };
922
+ createEffect(on(chat.ready, (ready) => {
923
+ if (ready) flush();
924
+ }));
925
+ onCleanup(() => {
926
+ for (const { resolve } of waiting) resolve(false);
927
+ });
928
+ const working = () => chat.streaming() && !draft().trim();
929
+ const lastTurn = () => {
930
+ const ids = chat.messageIDs();
931
+ return ids.length ? chat.turn(ids[ids.length - 1]) : void 0;
932
+ };
933
+ const awaitingReply = () => chat.streaming() && lastTurn()?.message.role === "user";
934
+ let pinned = true;
935
+ const nearBottom = () => !timeline || timeline.scrollHeight - timeline.scrollTop - timeline.clientHeight < 80;
936
+ createComputed(on(chat.changes, () => {
937
+ pinned = nearBottom();
938
+ }, { defer: true }));
939
+ createEffect(on(chat.changes, () => {
940
+ if (pinned) timeline.scrollTop = timeline.scrollHeight;
941
+ if (timeline.scrollHeight <= timeline.clientHeight + 120) chat.older();
942
+ }, { defer: true }));
943
+ props.api({
944
+ send: sendFromHost,
945
+ focus: () => input?.focus(),
946
+ newChat: () => chat.newChat()
947
+ });
948
+ return (() => {
949
+ var _el$27 = _tmpl$17(), _el$28 = _el$27.firstChild, _el$29 = _el$28.firstChild, _el$30 = _el$29.firstChild, _el$32 = _el$29.nextSibling, _el$33 = _el$32.firstChild, _el$34 = _el$32.nextSibling, _el$35 = _el$28.nextSibling, _el$40 = _el$35.firstChild, _el$42 = _el$35.nextSibling, _el$46 = _el$42.firstChild, _el$47 = _el$46.firstChild, _el$49 = _el$47.firstChild.firstChild, _el$53 = _el$47.nextSibling.firstChild.firstChild.firstChild, _el$55 = _el$53.firstChild.firstChild, _el$56 = _el$55.nextSibling, _el$59 = _el$53.nextSibling.firstChild.firstChild;
950
+ insert(_el$30, () => options.title);
951
+ insert(_el$29, createComponent(Show, {
952
+ get when() {
953
+ return options.subtitle;
954
+ },
955
+ get children() {
956
+ var _el$31 = _tmpl$10();
957
+ insert(_el$31, () => options.subtitle);
958
+ return _el$31;
959
+ }
960
+ }), null);
961
+ insert(_el$33, () => chat.status().text);
962
+ _el$34.$$click = () => {
963
+ chat.newChat();
964
+ input.focus();
965
+ };
966
+ insert(_el$34, createComponent(Plus, {}));
967
+ _el$35.addEventListener("scroll", () => {
968
+ if (timeline.scrollTop < 200) chat.older();
969
+ });
970
+ var _ref$ = timeline;
971
+ typeof _ref$ === "function" ? use(_ref$, _el$35) : timeline = _el$35;
972
+ insert(_el$35, createComponent(Show, {
973
+ get when() {
974
+ return memo(() => chat.messageIDs().length === 0)() && chat.ready();
975
+ },
976
+ get children() {
977
+ var _el$36 = _tmpl$13(), _el$37 = _el$36.firstChild;
978
+ insert(_el$37, () => options.title);
979
+ insert(_el$36, createComponent(Show, {
980
+ get when() {
981
+ return options.subtitle;
982
+ },
983
+ get children() {
984
+ var _el$38 = _tmpl$11();
985
+ insert(_el$38, () => options.subtitle);
986
+ return _el$38;
987
+ }
988
+ }), null);
989
+ insert(_el$36, createComponent(Show, {
990
+ get when() {
991
+ return options.suggestions.length;
992
+ },
993
+ get children() {
994
+ var _el$39 = _tmpl$12();
995
+ insert(_el$39, createComponent(For, {
996
+ get each() {
997
+ return options.suggestions;
998
+ },
999
+ children: (suggestion) => (() => {
1000
+ var _el$60 = _tmpl$18();
1001
+ _el$60.$$click = () => void sendText(suggestion.prompt);
1002
+ insert(_el$60, () => suggestion.label);
1003
+ return _el$60;
1004
+ })()
1005
+ }));
1006
+ return _el$39;
1007
+ }
1008
+ }), null);
1009
+ return _el$36;
1010
+ }
1011
+ }), _el$40);
1012
+ insert(_el$40, createComponent(For, {
1013
+ get each() {
1014
+ return chat.messageIDs();
1015
+ },
1016
+ children: (id) => createComponent(TurnView, {
1017
+ turn: () => chat.turn(id),
1018
+ get streaming() {
1019
+ return chat.streaming;
1020
+ },
1021
+ get labels() {
1022
+ return labels();
1023
+ }
1024
+ })
1025
+ }), null);
1026
+ insert(_el$40, createComponent(Show, {
1027
+ get when() {
1028
+ return awaitingReply();
1029
+ },
1030
+ get children() {
1031
+ var _el$41 = _tmpl$14();
1032
+ insert(_el$41, createComponent(ActivityRow, {
1033
+ title: "Thinking",
1034
+ active: true,
1035
+ name: "thinking"
1036
+ }));
1037
+ return _el$41;
1038
+ }
1039
+ }), null);
1040
+ insert(_el$42, createComponent(Show, {
1041
+ get when() {
1042
+ return chat.permissions()[0];
1043
+ },
1044
+ keyed: true,
1045
+ children: (request) => createComponent(PermissionDock, {
1046
+ request,
1047
+ onReply: (response) => void chat.replyPermission(request.id, response)
1048
+ })
1049
+ }), _el$46);
1050
+ insert(_el$42, createComponent(Show, {
1051
+ get when() {
1052
+ return chat.questions()[0];
1053
+ },
1054
+ keyed: true,
1055
+ children: (request) => createComponent(QuestionDock, {
1056
+ request,
1057
+ onAnswer: (answers) => void chat.answer(request.id, answers),
1058
+ onSkip: () => void chat.reject(request.id)
1059
+ })
1060
+ }), _el$46);
1061
+ insert(_el$42, createComponent(Show, {
1062
+ get when() {
1063
+ return chat.error() || chat.unconfirmed();
1064
+ },
1065
+ get children() {
1066
+ var _el$43 = _tmpl$16(), _el$44 = _el$43.firstChild;
1067
+ insert(_el$44, () => chat.error() || "Your last message may not have been delivered.");
1068
+ insert(_el$43, createComponent(Show, {
1069
+ get when() {
1070
+ return chat.unconfirmed();
1071
+ },
1072
+ get children() {
1073
+ var _el$45 = _tmpl$15();
1074
+ _el$45.$$click = () => void chat.retry();
1075
+ return _el$45;
1076
+ }
1077
+ }), null);
1078
+ return _el$43;
1079
+ }
1080
+ }), _el$46);
1081
+ _el$49.$$keydown = (event) => {
1082
+ if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
1083
+ event.preventDefault();
1084
+ submit();
1085
+ }
1086
+ };
1087
+ _el$49.$$input = (event) => {
1088
+ setDraft(event.currentTarget.value);
1089
+ grow();
1090
+ };
1091
+ var _ref$2 = input;
1092
+ typeof _ref$2 === "function" ? use(_ref$2, _el$49) : input = _el$49;
1093
+ _el$55.addEventListener("change", (event) => chat.selectModel(event.currentTarget.value));
1094
+ insert(_el$55, createComponent(For, {
1095
+ get each() {
1096
+ return chat.modelGroups();
1097
+ },
1098
+ children: (group) => (() => {
1099
+ var _el$61 = _tmpl$19();
1100
+ insert(_el$61, createComponent(For, {
1101
+ get each() {
1102
+ return group.models;
1103
+ },
1104
+ children: (model) => (() => {
1105
+ var _el$62 = _tmpl$20();
1106
+ insert(_el$62, () => model.label);
1107
+ effect(() => _el$62.selected = model.value === chat.modelValue());
1108
+ effect(() => _el$62.value = model.value);
1109
+ return _el$62;
1110
+ })()
1111
+ }));
1112
+ effect(() => setAttribute(_el$61, "label", group.label));
1113
+ return _el$61;
1114
+ })()
1115
+ }));
1116
+ insert(_el$56, createComponent(ChevronDown, {}));
1117
+ _el$59.$$click = () => working() ? void chat.abort() : void submit();
1118
+ insert(_el$59, createComponent(Show, {
1119
+ get when() {
1120
+ return working();
1121
+ },
1122
+ get fallback() {
1123
+ return createComponent(ArrowUp, {});
1124
+ },
1125
+ get children() {
1126
+ return createComponent(Stop, {});
1127
+ }
1128
+ }));
1129
+ effect((_p$) => {
1130
+ var _v$8 = chat.sessionID() ?? "", _v$9 = chat.status().tone, _v$0 = chat.status().text, _v$1 = !chat.ready(), _v$10 = options.placeholder, _v$11 = options.placeholder, _v$12 = !chat.modelGroups().length, _v$13 = working() ? "" : void 0, _v$14 = working() ? "Stop" : "Send", _v$15 = working() ? false : !chat.ready() || !draft().trim();
1131
+ _v$8 !== _p$.e && setAttribute(_el$27, "data-session-id", _p$.e = _v$8);
1132
+ _v$9 !== _p$.t && setAttribute(_el$32, "data-tone", _p$.t = _v$9);
1133
+ _v$0 !== _p$.a && setAttribute(_el$32, "title", _p$.a = _v$0);
1134
+ _v$1 !== _p$.o && setAttribute(_el$46, "aria-busy", _p$.o = _v$1);
1135
+ _v$10 !== _p$.i && setAttribute(_el$49, "placeholder", _p$.i = _v$10);
1136
+ _v$11 !== _p$.n && setAttribute(_el$49, "aria-label", _p$.n = _v$11);
1137
+ _v$12 !== _p$.s && (_el$55.disabled = _p$.s = _v$12);
1138
+ _v$13 !== _p$.h && setAttribute(_el$59, "data-working", _p$.h = _v$13);
1139
+ _v$14 !== _p$.r && setAttribute(_el$59, "aria-label", _p$.r = _v$14);
1140
+ _v$15 !== _p$.d && (_el$59.disabled = _p$.d = _v$15);
1141
+ return _p$;
1142
+ }, {
1143
+ e: void 0,
1144
+ t: void 0,
1145
+ a: void 0,
1146
+ o: void 0,
1147
+ i: void 0,
1148
+ n: void 0,
1149
+ s: void 0,
1150
+ h: void 0,
1151
+ r: void 0,
1152
+ d: void 0
1153
+ });
1154
+ return _el$27;
1155
+ })();
1156
+ }
1157
+ delegateEvents([
1158
+ "click",
1159
+ "input",
1160
+ "keydown"
1161
+ ]);
1162
+ //#endregion
1163
+ //#region src/mount.tsx
1164
+ var _tmpl$ = /*#__PURE__*/ template(`<div>`);
1165
+ /**
1166
+ * Renders the Mux chat into `host` (inside its shadow root, with Mux's
1167
+ * styles). Give `host` a height, e.g. a sidebar column.
1168
+ */
1169
+ function mountMuxChat(host, options = {}) {
1170
+ const root = host.shadowRoot ?? host.attachShadow({ mode: "open" });
1171
+ root.replaceChildren();
1172
+ const style = document.createElement("style");
1173
+ style.textContent = styles;
1174
+ const container = document.createElement("div");
1175
+ container.style.height = "100%";
1176
+ root.append(style, container);
1177
+ if (options.theme === "light" || options.theme === "dark") host.setAttribute("data-theme", options.theme);
1178
+ else host.removeAttribute("data-theme");
1179
+ let api;
1180
+ const dispose = render(() => createComponent(Chat, {
1181
+ api: (value) => api = value,
1182
+ get options() {
1183
+ return {
1184
+ url: options.url ?? "/api/mux",
1185
+ title: options.title ?? "Assistant",
1186
+ subtitle: options.subtitle,
1187
+ placeholder: options.placeholder ?? "Ask anything…",
1188
+ suggestions: options.suggestions ?? [],
1189
+ toolLabels: options.toolLabels ?? {},
1190
+ agent: options.agent ?? "assistant",
1191
+ sessionTitle: options.sessionTitle ?? "Chat",
1192
+ storageKey: options.storageKey ?? "mux-chat",
1193
+ preferredModel: options.preferredModel,
1194
+ onToolResult: options.onToolResult
1195
+ };
1196
+ }
1197
+ }), container);
1198
+ return {
1199
+ send: (text) => api?.send(text) ?? Promise.resolve(false),
1200
+ focus: () => api?.focus(),
1201
+ newChat: () => api?.newChat() ?? Promise.resolve(),
1202
+ dispose: () => {
1203
+ dispose();
1204
+ root.replaceChildren();
1205
+ }
1206
+ };
1207
+ }
1208
+ /** Solid wrapper around `mountMuxChat`. Options are read once, at mount. */
1209
+ function MuxChat(props) {
1210
+ let host;
1211
+ onMount(() => {
1212
+ const handle = mountMuxChat(host, props);
1213
+ props.ref?.(handle);
1214
+ onCleanup(() => handle.dispose());
1215
+ });
1216
+ return (() => {
1217
+ var _el$ = _tmpl$();
1218
+ var _ref$ = host;
1219
+ typeof _ref$ === "function" ? use(_ref$, _el$) : host = _el$;
1220
+ effect((_p$) => {
1221
+ var _v$ = props.id, _v$2 = props.class, _v$3 = props.style;
1222
+ _v$ !== _p$.e && setAttribute(_el$, "id", _p$.e = _v$);
1223
+ _v$2 !== _p$.t && className(_el$, _p$.t = _v$2);
1224
+ _p$.a = style(_el$, _v$3, _p$.a);
1225
+ return _p$;
1226
+ }, {
1227
+ e: void 0,
1228
+ t: void 0,
1229
+ a: void 0
1230
+ });
1231
+ return _el$;
1232
+ })();
1233
+ }
1234
+ //#endregion
1235
+ export { MuxChat, mountMuxChat };
1236
+
1237
+ //# sourceMappingURL=index.js.map