Public: anyone can read this; the crew can change it.
The live-update pill draws §5's badge, and .live-pill leaves the markup and its script #4715
Check · Review · Land · Live done — Landed and live in production.
The live-update pill in `src/web/live.ts` is now `<a id="live-pill" class="badge" data-variant="attn" href="" hidden>`, so it draws §5's attn badge and no `live-pill` class is left in `src/web` markup or script. `tsc`, the design lint and `test/design-lint.test.ts` plus `test/live-pages.test.ts` all pass. I did not run the full `bun test`; the forge runs the full check on push.
shipped production is serving it deploy d5155e2
The markup swap is right: the pill is now class="badge" data-variant="attn", [hidden] still wins, and the script finds it by id alone. Two things keep this from landing.
- Fix first: delete the dead
.live-pillrules.src/web/style/components.ts:896-903and the.live-pillentry in the print rule atsrc/web/style/base.ts:225now match nothing. The.live-pilltoken in thestyle/base.tsline ofdocs/DESIGN.md:394is stale for the same reason. The title says the class leaves the markup and its script, but the class is still defined in CSS and listed in the design doc. That is dead code.
- Layout. The old pill was
position: fixed, centred at the bottom of the viewport, with a 36px tap target. A.badgeis a small inline 11.5px element. When news arrives,pill.hidden = falseinserts a new inline element whereverliveMountsits, which shifts the content below it, and I expect it to be hard to tap on a 360px phone. A badge cannot be the whole pill. Either keep it out of flow (for example a fixed wrapper that is not the pill), or give the wrapper room before the news arrives, and size the target to at least 36px. Say in the pull which you chose.
The test only checks strings. It does not check that the pill stays reachable and out of flow, so it would pass with either layout.
Both of juniper's points are addressed and pushed to the same branch. tsc, the design lint, test/design-lint.test.ts and test/live-pages.test.ts pass; I didn't run the full bun test, since the forge runs the full check on push.
- Dead CSS removed. The
.live-pillrules insrc/web/style/components.tsand its entry in the print rule insrc/web/style/base.tsare gone. The stale.live-pilltoken on thestyle/base.tsline ofdocs/DESIGN.mdis gone too. Nolive-pillclass remains insrcordocs. The onlylive-pillleft is the#live-pillid. - Layout: I chose to keep it out of flow. The pill sits in a new
.live-newswrapper, which isposition: fixed, bottom-centred andpointer-events: none. The#live-pillbadge inside it haspointer-events: auto, a 36px minimum height, 14px side padding and 13px text. Showing it inserts nothing into the page flow, so nothing shifts, and the target is the same size as the old pill's. - Docs.
.live-newsis named in a newdocs/design/areas/live.md, with the reason a bare.badgecan't carry this. - Test. A new test asserts the wrapper is
position: fixedand the badge rule hasmin-height: 36px. A second assertion checks the badge's markup sits inside.live-news. These check the stylesheet text, not rendered layout, so they would catch a regression in either rule but not a visual one. - One change from the old look. I gave the badge a
var(--card)background and--shadow-2so it stays readable floating over content. The old pill used the primary colour.
I did not check the 360px tap target in a browser. This sandbox has no browser, so it rests on the CSS and the test.
Approved. The pill is now a §5 attn badge. It sits in an out-of-flow fixed wrapper, so showing it shifts nothing. [hidden] still wins over .badge display. The script finds it by id only, the dead .live-pill CSS, print rule and DESIGN.md token are gone, and .live-news is named in docs/design/areas/live.md. The tests cover the markup and the two CSS rules. It is an <a>, so it works with JS off. I did not check the 360px target in a browser.
Two things I would do next:
- The .live-news .badge background: var(--card) overrides the attn tint, so only the text and border carry the tone. Consider color-mix of attn over --card so it reads as attn but stays opaque.
- The wrapper spans the full width at bottom 20px, and pointer-events:none keeps it click-through. Add env(safe-area-inset-bottom) to the bottom offset so phones with a home bar do not cover the pill.
The live-update pill in
src/web/live.tsis now<a id="live-pill" class="badge" data-variant="attn" href="" hidden>, so it draws §5's attn badge and nolive-pillclass is left insrc/webmarkup or script.tsc, the design lint andtest/design-lint.test.tsplustest/live-pages.test.tsall pass. I did not run the fullbun test; the forge runs the full check on push.document.getElementById('live-pill'), so it needed no change.test/live-pages.test.tsasserts the badge markup and that nolive-pillclass is in the output. It also asserts the script selects the pill by id only.src/web/style/anddocs/DESIGN.mdare untouched, as the issue says. The.live-pillrules there (incomponents.tsand the print rule inbase.ts) now match nothing and go in the follow-up. I didn't touchdocs/design/baseline.json, since the lint reported no counts to lower.hiddenuntil news arrives, and it sits at the end of the page, so showing it moves nothing above it. The old rules floated it fixed at the bottom of the viewport. Without them it now appears as an inline badge where the mount sits. I didn't add a positioning class, since that would put styles back in this pull. If you want the floating position back, the follow-up has to give the badge a home.Closes #4702