diff --git a/frontend/src/app/pages/AgentChat/tool-ui/LinksWidget.tsx b/frontend/src/app/pages/AgentChat/tool-ui/LinksWidget.tsx index 309a5fe0..7f90d538 100644 --- a/frontend/src/app/pages/AgentChat/tool-ui/LinksWidget.tsx +++ b/frontend/src/app/pages/AgentChat/tool-ui/LinksWidget.tsx @@ -16,7 +16,7 @@ function hostOf(url: string): string { function LinksWidget({ props }: { props: LinksProps }): React.ReactElement { const c = useClaudeTokens(); return ( - + {props.links.map((l, i) => ( + {props.title && ( {props.title} diff --git a/frontend/src/app/pages/AgentChat/tool-ui/WeatherWidget.tsx b/frontend/src/app/pages/AgentChat/tool-ui/WeatherWidget.tsx index 541410ba..32652503 100644 --- a/frontend/src/app/pages/AgentChat/tool-ui/WeatherWidget.tsx +++ b/frontend/src/app/pages/AgentChat/tool-ui/WeatherWidget.tsx @@ -33,8 +33,7 @@ function WeatherWidget({ props, ambient }: { props: WeatherProps; ambient?: bool })); return ( - // 4:3 card; the vendored strip reveals at 245px height and its day icons at 280px, so width must be >= 374 for the full frame look. -
+
= ({ name }) => ( style={{ height: skeletonHeightFor(name), width: '100%', - maxWidth: 520, borderRadius: 12, background: 'rgba(127,127,127,0.12)', animation: 'toolui-skeleton-pulse 1.4s ease-in-out infinite', diff --git a/frontend/src/toolui/toolui.css b/frontend/src/toolui/toolui.css index c4412f47..2d134d44 100644 --- a/frontend/src/toolui/toolui.css +++ b/frontend/src/toolui/toolui.css @@ -85,6 +85,13 @@ display: block; } } +/* Vendored roots cap themselves at 448-576px, which reads half-sized in the chat column; unlayered + beats the utilities layer, so the scope's direct child always fills the bubble. */ +.tool-ui-scope > * { + width: 100%; + max-width: none; + min-width: 0; +} .tool-ui-scope { color: var(--foreground); /* The app's chat voice is a serif at a 19.2px root; generated UI needs the crisp product-sans