diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2db90cf..9d96a5a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -29,7 +29,7 @@ release PR may merge — and a section is closed at the commit that bumps it.
assistant reading through it. Like an attachment, what the eye sends goes to the AI
provider together with your message — hover it (or tap it) to read exactly what would
go out, click it to stop sharing; the choice is remembered on this device, and every
- message shows a chip with what it carried. Very long highlights are trimmed, with a
+ sent message keeps a faint eye in its corner that shows, on hover, what it carried. Very long highlights are trimmed, with a
note saying how much was left out — the assistant can still read the whole file itself.
On by default.
- Several conversations per source: open extra chats with `+`, and the tab bar you left
diff --git a/docs/view-context.md b/docs/view-context.md
index 2eb3589..2c3ad6a 100644
--- a/docs/view-context.md
+++ b/docs/view-context.md
@@ -12,7 +12,7 @@ Exactly one snapshot per message, covering whatever applies at that moment:
- **A highlighted passage** — if the user selected text in the viewer, the selected text itself, with its line numbers when they are looking at the source (a plain-text file, or the editor view of a Markdown file).
- **Which thing a detail page is about** — which project (and which of its tabs), which member, connector, plugin, conversation, tool call or LLM request; also the active section in Tasks or Models, the open agent in Background agents, and a search typed in the Marketplace.
-Hover the eye (or tap it, on a touch screen) to read exactly what would be sent with the next message. Every sent message shows a small chip with what it carried, which can be opened to read the actual values.
+Hover the eye (or tap it, on a touch screen) to read exactly what would be sent with the next message. Every sent message keeps a small eye in its corner; hovering it (or tapping it, on a touch screen) shows the actual values that message carried.
## Control and privacy
diff --git a/web/components/copilot-render.js b/web/components/copilot-render.js
index 3292ff2..50642aa 100644
--- a/web/components/copilot-render.js
+++ b/web/components/copilot-render.js
@@ -591,18 +591,22 @@ export function renderViewContextPill(host) {
* The proof, in the sent bubble: what this message actually carried. Rendered
* from the server's echo (and, after a reload, from the REST history), so it
* shows the sanitized pairs the model was given — never the browser's intent.
+ *
+ * A mark in the bubble's corner, not a row under the message: this is evidence
+ * about a message, not part of it, and a collapsed row still cost a line of
+ * height in every bubble that carried one. Deliberately **not** expandable —
+ * the pairs show on hover (on focus for keyboard and touch) and there is no
+ * state to leave open, so a conversation scrolled back through never grows a
+ * second layout.
+ *
+ * Written on one line on purpose: the bubble renders `white-space: pre-wrap`, so
+ * the newline and indent a formatted template would leave before the element are
+ * a text node the bubble actually shows — a blank line under the message.
*/
-function renderViewContextChip(host, msg) {
+function renderViewContextMark(host, msg) {
const items = msg.view_context;
if (!items?.length) return nothing;
- return html`
-
-
- ${t('chat.view_context.chip', { n: items.length })}
-
- ${renderViewContextItems(items)}
-