Skip to content

Draw an interface a Bot puts in a Card with one frame, not two - #1379

Merged
davidmckayv merged 3 commits into
mainfrom
david/fix-double-frame
Nov 9, 2026
Merged

davidmckayv merged 3 commits into
mainfrom
david/fix-double-frame

Conversation

@davidmckayv

Copy link
Copy Markdown
Contributor

What

An interface a Bot draws inside a Card, such as the "Build a trip budget" starter task, showed two frames in the conversation: CopilotKit's own frame around every interface in a chat (a border and 12px of padding) and the Card's border inside it, with a gap between them.

When the interface's top component is a Card that draws a box, the frame now gives up its border and padding, so the Card, drawn in the app's tokens, is the one card in the conversation. Anything else on top, including a Card drawn as a borderless section or a transparent one, keeps the frame as its only box.

How

One unlayered rule in app/src/styles.css, keyed on CopilotKit's data-generative-ui-chat-surface frame and the catalog's own data-a2ui-card="top" mark, including a Card wrapped in the display: contents span the SDK adds when it is given an accessible name. It covers both chat surfaces, since the frame is the SDK's in each.

Test

app/tests/a2ui-frame.test.tsx renders the real transcript in Chromium with four interfaces delivered as generative-ui-surface activities (a Card, a named Card, a bare Column, a section Card), under CopilotKit's stylesheet and the app's in main.tsx order, and checks which boxes around each interface draw a border, the inset and the frame's padding. It fails on main (frame and Card both bordered, 13px inset) and passes with the rule. Added to CI's real-browser step. OPENBOT_APP_SHOTS=<dir> saves light and dark screenshots at chat width.

Visual check, before and after, light and dark: the trip budget is one card edge to edge with the column; the bare Column keeps its frame. The bright frame border in the dark theme for interfaces that keep the frame is handled separately in #1375.

CopilotKit draws its own frame (a border and 12px of padding) around every
interface in a chat, and the catalog's Card draws a border too. A Card on top,
the shape most interfaces take, came out as a box inside a box with a gap
between them, as in the "Build a trip budget" starter task.

When the interface's top component is a Card that draws a box, the frame now
gives up its border and padding, so the Card, drawn in the app's tokens, is the
one card in the conversation. A bare Column, or a Card drawn as a borderless
section or a transparent one, keeps the frame as its only box.

A real-browser test renders the transcript with interfaces delivered as the
runtime's activities, under CopilotKit's stylesheet and the app's, and checks
which boxes around each interface draw a border. It runs in CI's browser job.
@davidmckayv
davidmckayv merged commit dd2a54f into main Nov 9, 2026
26 checks passed
@davidmckayv
davidmckayv deleted the david/fix-double-frame branch November 9, 2026 22:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant