**The chat stops being a card at the bottom of the page and becomes a column beside it.** Modelled
on [VoiceDebrief](https://voicedebrief.ai/app/): a vertical tab on the right edge, a panel that
opens from it, and a drag handle to set the width. The distinction that mattered here is **column,
not overlay.** An overlay covers the page you were reading, and on this site the page you were
reading is the thing you are asking about — «em que fontes assenta isto» is not a question you can
answer while the answer is behind the question. So `<html>` takes a `padding-right` equal to the
panel and the article reflows beside it. The width, the open state, the materials you send, the
model and your key all live in `localStorage`, so the panel opens the way you left it.

**The engine was already here and was kept.** `assets/conversa.js` had the whole apparatus — the
level-0 comparator that runs in the browser with no key, the 18 GET tools, the OpenRouter call —
and it was checked for before anything was written, because this repository has already produced
two answers to one ask once this week. Only the presentation was replaced. What changed inside the
engine is that it now emits each tool call as it happens and asks OpenRouter for `usage`, so the
panel can show **which file was opened, with what argument, how many bytes came back, and what the
round cost** — inline, where it happened, rather than behind a spinner. On a publication whose
whole argument is that a claim walks back to bytes, hiding which bytes were read would be the
wrong thing to hide.

**Every tool is visible before you use one, and every one says `LER`.** Not as a safety claim but
as a consequence: the API of this site is files, so there is no write to offer. The panel also
lists what travels with your question, as checkboxes, because a reader should never have to guess
what left their browser.

**The panel shipped broken, and this is how it was caught.** `.painel { display: flex }` in the
component's own stylesheet silently beats the browser's `[hidden] { display: none }` — one class
selector against one attribute selector — so the panel that was supposed to be **closed** was
lying across the article on all 227 reader pages. It passed every gate: the component reached
`pronto`, nothing threw, nothing overflowed, nothing 404'd. It was found by taking a screenshot
and looking at it. **Gate: the browser check now reads the computed style of every element
carrying `hidden` inside a component's shadow root**, for every component, and fails when one is
on screen anyway.

**And the browser gate stopped sleeping.** It waited 400 ms after `networkidle` and then asserted
— which on `/grafo/`, where Cytoscape runs its layout on the main thread, found `pt-chat` with an
empty shadow root and reported a broken component that was fine at three seconds. A fixed sleep
measures the machine the gate runs on. It now waits for the `data-estado` the base class sets, up
to ten seconds, and a timeout is still a failure — a component that needs longer than that is one
the reader sees as an empty box.

*Three deliberate injections confirmed the gate fails: a selector that is not in the template, a
renamed `.tpl`, and the `[hidden]` rule taken back out. Sixteen pages, five gates, green.*
