**The chrome stops moving when you cross between the paper and the back office, the spend gets a
page of its own, and a layout bug this session shipped two releases ago is fixed.** Three things
the editor asked for, and one he found by looking.

**The menu moved, and it moved a lot.** The paper had a dateline, a countdown and a run of utility
links, then a centred masthead and a section nav. The back office had a single row mixing its own
identity, its own eleven links and the version — different order, different place. Clicking «Back
office» rearranged every item in the chrome at once, which reads as arriving at a *different site*
rather than at the back of the same one. The utility run is now generated once, in
`build/paginas.py`, and both chromes emit it in the same slot with the same items in the same
order. Measured in a browser: on both pages it sits **18px from the top and 56px from the right,
18px tall**. Exactly one item differs, and it is the one that has to — on the paper it points into
the back office, in the back office it points back out at the paper. The console's own links become
a nav below it, wearing the paper's `.nav` with a single hairline instead of the broadsheet's
double rule, because the back office is not the publication and should not claim the publication's
furniture. It also now marks the page you are on, which the paper's nav always did and the back
office never did.

**A layout bug this session shipped in v0.9.0, and the editor caught it.** Capping `.std` at 29em
is right for the newspaper, where a paragraph sits inside a grid column about 758px wide. The back
office has **no grid**: it is one column of prose in a 1328px sheet, so the same cap put the text
in a 522px ribbon with 800px of empty paper beside it while every hairline went on spanning the
full width. Text at a third of the page with rules across all of it does not read as a narrow
measure — it reads as broken, and it was. The fix is the container, not the paragraph: the
console's content column is 58em, so a rule is **1.78×** the prose it divides instead of 2.5×.
The first attempt at this fix put the width on `.folha` and quietly undid the chrome work above —
the utility run ended up 312px from the window's right edge against 56px on the paper. Same slot
relative to its own sheet, different place on screen. The narrowing is on the content and
deliberately not on the sheet, and the stylesheet says so where somebody would be tempted to move
it back.

**The wallet stops being a popup.** The editor asked for the budget spend on a page of its own, and
the reason is not taste: the *ledger* is the interesting part of the demonstration, and a ledger
worth reading is worth an address. A panel that covers the masthead cannot be linked to, cannot be
read on a phone without covering what you were reading, and closes itself on the first click
elsewhere. `pt-wallet` gains two modes on one template — a badge that is now a **link** in the
chrome, and the ledger itself at [`/carteira/`](../carteira/) with a stat strip, the actions and
the last pages read. There is no second copy of the ledger: two copies would diverge the day
somebody changed the price in one of them. The badge still debits the page it is on, because the
debit *is* the demonstration and has to happen wherever the reader is. The wallet page carries both
instances, and that is not a double debit — `_charge()` records the page in `sessionStorage` before
returning, so the second one finds it already seen. The guard was written for the back button and
happens to cover this; the comment says so rather than relying on it by accident. This also settles
half of the design review's decision 4: the wallet is out of the reader's header as a panel, and
whether the badge itself belongs there at all is still the editor's call.

**The palette did not reach inside the components, and the design review found it.** The five
shipped components hardcoded `#0f766e`, `#f7f4ec` and most of the rest of the palette in their own
CSS — so the v0.9.0 contrast fixes landed everywhere **except** inside them, which is the half of
the site a reader spends longest looking at. Custom properties *do* cross the shadow boundary,
because they inherit: a component reading `var(--acento)` picks up a palette change for free. It
just needed a token to inherit, and there were none. **156 hardcoded colours across seven
component stylesheets** are now tokens, including eight near-misses — a paper that was not the
paper, a hairline that was not the hairline, an ink that was not the ink — which is exactly the
drift tokens exist to prevent. The one genuinely different colour, the purple that marks a JSON
key, becomes `--sintaxe-chave` in `:root`: not because it was failing (7.93:1, comfortably above
AA) but because a colour that is not in `:root` cannot be measured by the gate, and *measured* is
the property that matters. **Gate 33b** now fails the build on a hardcoded colour in component CSS,
with a `var(--token, #fallback)` still allowed — the token wins whenever it is defined, which here
is always. Injection-tested: it catches an accent put back by hand.


**Renumbered from v0.11.0, and the gate earned its keep on the way.** The other session shipped
its own v0.11.0 while this one was building — the third time today two sessions have reached for
the same number — so this release moved up, because the one that has not shipped is the one that
moves. Merging their work brought in a brand-new `pt-chat` component, and **gate 33b failed the
build on it immediately**: it hardcoded `#fff` for the tab label and dot. There is no pure white
in this palette; `--papel` is the house colour for light on ink, which is what `.escuro` already
uses over `--tinta`, and on the accent it gives the same 6.83:1 the accent gives on paper. A gate
written for one release catching the next release's component, on its first run, is the whole
argument for writing it as a gate instead of a note.

**And this release failed to deploy the first time, with all five gates green.** Worth writing
down, because the failure mode is the nastiest kind. `validate` passed, the five gates were green,
the push to `dev` succeeded — and `tag-release` failed with *"version.txt says v0.12.0 but the
newest release commit in this history is v0.11.0"*. CI does not read `version.txt` alone: it reads
the newest commit **subject** matching `^site vX.Y.Z:`, because the subject is what names the
commit to tag. This work went in under a merge subject — "integra o dev (v0.11.0) e renumera para
v0.12.0" — which carries the number but not in the form CI parses. So nothing was tagged, `deploy`
was skipped, and the live site stayed on the previous release while every local check said OK.
**A green build that does not deploy is the worst kind of green**, and rewriting the subject was
not an option: this repository does not force-push and does not rewrite history.

`build/tudo.py` now closes by running the same comparison CI runs and saying, in as many words,
what the release commit's subject has to be. It is a **warning and not a gate**, deliberately: on
a feature branch `version.txt` is legitimately ahead of the newest release subject for as long as
the work is unfinished, and a gate that failed every intermediate build would teach whoever hit it
to skip gates — which costs more than it saves.
