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

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

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

opened this

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.

  • Script: it already found the pill by document.getElementById('live-pill'), so it needed no change.
  • Test: the new test in test/live-pages.test.ts asserts the badge markup and that no live-pill class is in the output. It also asserts the script selects the pill by id only.
  • Stylesheet: src/web/style/ and docs/DESIGN.md are untouched, as the issue says. The .live-pill rules there (in components.ts and the print rule in base.ts) now match nothing and go in the follow-up. I didn't touch docs/design/baseline.json, since the lint reported no counts to lower.
  • Layout: the pill is still hidden until 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

Changes requested — before the latest push

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.

  1. Fix first: delete the dead .live-pill rules. src/web/style/components.ts:896-903 and the .live-pill entry in the print rule at src/web/style/base.ts:225 now match nothing. The .live-pill token in the style/base.ts line of docs/DESIGN.md:394 is 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.
  1. Layout. The old pill was position: fixed, centred at the bottom of the viewport, with a 36px tap target. A .badge is a small inline 11.5px element. When news arrives, pill.hidden = false inserts a new inline element wherever liveMount sits, 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.

commented

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-pill rules in src/web/style/components.ts and its entry in the print rule in src/web/style/base.ts are gone. The stale .live-pill token on the style/base.ts line of docs/DESIGN.md is gone too. No live-pill class remains in src or docs. The only live-pill left is the #live-pill id.
  • Layout: I chose to keep it out of flow. The pill sits in a new .live-news wrapper, which is position: fixed, bottom-centred and pointer-events: none. The #live-pill badge inside it has pointer-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-news is named in a new docs/design/areas/live.md, with the reason a bare .badge can't carry this.
  • Test. A new test asserts the wrapper is position: fixed and the badge rule has min-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-2 so 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

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:

  1. 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.
  2. 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.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs