Repository navigation
activity: restyle /activity/ with the shared rows, a type filter and day links - #290
Conversation
The groundwork the restyled /activity/ page needs first, on every page: - default.html sets a js class on <html> before first paint, so styles for states that need JavaScript (a collapsed list, a filter bar) apply from the start and nothing moves when scripts run. Nothing uses it yet. - main.js reads and writes sessionStorage inside try/catch. Where site data is blocked the read threw and stopped the rest of main.js: the mobile menu, the header state, back-to-top and the smooth scroll. - main.js's URL carries the same ?v= build stamp as the CSS, so a deploy doesn't pair new pages with a cached main.js. Part of #277. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…day links The log now reads site.data.activity_view instead of flattening the data files: months, newest first, each an <ol> of days whose ids (activity-2026-08-02) are the anchors that group and editions rows link to, each holding that day's rows in the view's order. - Row includes in _includes/activity/: meta.html (icon, hidden type word, date and tag; tag=false leaves the tag out), title.html and summary.html (escaped, backtick spans as <code>), to be shared with the /news/ rail and the home strip; log-row.html is the log's row. Every field is escaped, attributes included. - A type filter: All, Releases, Lectures, Translations and Books as text buttons with aria-pressed in a labelled group. It hides the days and months it leaves empty, shows an empty state for a type with no rows, and a polite live region announces the rows shown. - "N changes" disclosures: the PR lists are in the HTML, open. With JavaScript, CSS keyed on the head's js class collapses them from the first paint; without it, every PR link shows and the toggles are hidden. - Day and month anchors land below the header and the sponsor bar, with scroll padding scoped to this page, and following one on the page resets the filter to All first. - The behaviour is one inline script at the end of the layout. If it fails, it removes the js class, so every row and link shows. - mathjax_ignore on the log keeps MathJax from typesetting a "$" in a summary. - The intro's two links are underlined, as the release and PR links are: their colour alone is only 1.9:1 against the text. - The interim styles and the release and translation pills are removed. - README describes the page as it now is. AGENTS.md lists the includes and documents the js class pattern and mathjax_ignore for Activity views. Part of #277. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
✅ Deploy Preview for grand-swan-ca5201 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
It is a large UI/accessibility change spanning a rewritten layout, new JS behavior, ~300 lines of CSS, and a cross-page anchor contract whose correctness depends on browser/visual verification that cannot be performed here.
Review effort: Balanced
Findings: None
What changed in this PR
This PR restyles the /activity/ log to render from the build-time rows plugin (site.data.activity_view, added in #285) instead of flattening the raw data files in Liquid, and implements section 4 of the round-2 design handoff (#266). It introduces reusable Activity-row includes that the upcoming /news/ rail (#278) and home strip (#279) will share, a client-side type filter with an accessible live region, day/month anchors, and a "N changes" disclosure for PR links — all built to degrade gracefully without JavaScript. It also lays shared groundwork used site-wide: a js class set on <html> before first paint, a try/catch guard around main.js's sessionStorage access, and a ?v= cache-buster on the main.js URL. Closes #277.
Changes:
- Rewrite
_layouts/activity.htmlto read the view (months → days → rows), add a labelled type-filter button group, a polite live region, a day/month anchor script, and a no-JS-safe fallback. - Add shared includes
_includes/activity/{meta,title,summary,log-row}.htmlthat escape every field and prefix their Liquid variables withactivity_. - Replace the interim
.activity-*styles and therelease/translationpills inassets/main.scsswith the new log/filter styles; guardsessionStorageinmain.js; add the headjsclass and cache-buster in_layouts/default.html; update README and AGENTS.md.
| File | Description |
|---|---|
_layouts/activity.html |
Renders the view by month/day/row; filter, live region, "N changes" toggles, and anchor/scroll script |
_includes/activity/meta.html |
Row meta line: type icon, visually-hidden type word, date, optional tag |
_includes/activity/title.html |
Row title with optional single-release version span |
_includes/activity/summary.html |
Escaped summary with backtick spans turned into <code> |
_includes/activity/log-row.html |
One log row: release group, editions, single title, summary, per-edition/chips, and PRs |
assets/main.scss |
Removes interim styles and pills; adds shared filter + .activity-log styles, :has() scroll padding, reduced-motion rules |
assets/js/main.js |
Wraps sessionStorage get/set in try/catch so blocked storage no longer halts the script |
_layouts/default.html |
Adds head js class before first paint and a ?v= build stamp on the main.js URL |
README.md |
Describes the page as view-driven; removes the interim-page note |
AGENTS.md |
Documents the includes, the js/html:not(.js) pattern, and mathjax_ignore |
The implementation is consistent with the documented view contract (filter keys, row types, type_word, kind, editions/per_edition/changes), all referenced Sass variables and the visually-hidden/Bootstrap-icon classes exist, removed classes have no remaining references, and both sessionStorage call sites are guarded. I found no objective defects to flag.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
What changes
/activity/now reads the rows plugin's view (site.data.activity_view, from #285) instead of flattening the data files, and takes the design in section 4 of the round-2 handoff (#266).<section id="activity-2026-08">with an<h2>, holding an<ol>of days whose ids (activity-2026-08-02) are the anchors that group and editions rows link to. Each day holds its rows in the view's order. There is no visible day heading: every row shows its own date.<code>, and the PRs: one on a line, or two or more behind an "N changes" toggle._includes/activity/:meta.html,title.htmlandsummary.html, which the rail and the strip can use too, andlog-row.html. Every field is escaped, attributes included.<button aria-pressed>in a labelled group. It hides the days and months it leaves empty, shows an empty state for a type with no rows, and a polite live region, empty at load, announces the result.jsclass that<head>sets before first paint shows the filter and collapses the PR lists, so nothing moves when the scripts run.jsclass;main.js'ssessionStorageaccess wrapped in try/catch (where site data is blocked it threw and stopped the menu, the header state and back-to-top); and a?v=build stamp on themain.jsURL, like the CSS's..activity-*styles and thereleaseandtranslationpills, which only the old page used. README describes the page as it now is, and AGENTS.md lists the includes and documents thejsclass pattern andmathjax_ignore.Defaults to review on the preview
bi-bookon book rows. The decision reads: Add a fifth filter button, "Books", with a book icon. I read the icon as the book type's icon on book rows (bi-book, besidebi-box-seam,bi-journal-textandbi-translate), and kept all five buttons text-only, as the handoff draws them. Measured on phones (14.4px text, 14px gaps): text only needs 309.5px, one line from a 366px viewport;bi-bookon the Books button needs 329.9px, one line from 386px, or 403px before the web font arrives, so 390 and 393px phones would jump from two lines to one; icons on all four type buttons need 391.2px, one line only from 448px. Switching is a small change.#444text their colour alone is 1.9:1, short of the 3:1 that a link marked only by colour needs. Elsewhere on the site, links in text are underlined only on hover.<section>named by its heading, as the handoff has it, so screen readers list every month as a region landmark: four today, and one more each month. Droppingaria-labelledbywould keep the landmark list short and leave the<h2>headings as the way to move between months.mathjax_ignoreon the log. MathJax loads on every page and typesets a pair of$in a summary as mathematics (from $5 to $10came out as5to10). The class stops it;tex2jax_ignoredoes nothing with MathJax 3.html:has(.activity-log), rather than on barehtmlas the handoff has it: site-wide it would add to /team/'sscroll-margin-topand put its section links 133px lower. Browsers without:has()(Firefox before 121, Safari before 15.4) get no padding, so there a day link lands under the header._layouts/activity.html, as /team/'s is, rather than inmain.js, whose only change is thesessionStorageguard. It runs beforemain.js, and if it throws it removes thejsclass, so every row and PR link shows.How it was tested
_data/activity/is identical to the fixture, so it shows the fixture's 30 rows until main is merged in. The fixed numbers were checked on a fixture build (adata_dir: .github/scripts/fixturesconfig overlay): 30 rows in 4 months (6/8/11/5), 27 day anchors, Aug 2's "4 releases · same day", 23 PR links (8 on a line, 15 in 6 disclosures), the footer "The log begins on Jun 12, 2026.", and per filter Releases 16, Lectures 12, Translations 2 (August only) and Books 0 with its empty state.aria-controlspoints at its list, and nothing is renderedhiddenbut the empty state.<,&, quotes, backticks and$in titles, summaries, PR titles and URL query strings all render escaped, and MathJax typesets nothing. Also a book row, an editions row with differing summaries (one edition without), a two-release group, a row with no summary or PRs, long unbroken names (they wrap rather than being clipped), and no data at all ("No activity has been recorded yet.")./activity/#activity-2026-08-02lands 16 to 17px below the header with the sponsor bar shown and dismissed, after Translations was active (reset to All, announced), and when arriving from another page; a month anchor too; /team/#translators lands as it does on main;main.jsheld back, the page is already final (lists collapsed, filter shown), and nothing in the log moves when it runs;sessionStorageblocked, the menu, the header state, back-to-top and the bar work, where on main they don't;?v=stamps on every page, only/activity/,/README.md,main.css(and its map) andmain.jschange.Please look in iOS Safari and Firefox. Everything above ran in Chrome. The filter's fit at 390px depends on font metrics, VoiceOver should read the lists as lists (they carry
role="list"), and the scroll padding needs:has().Pre-existing, not changed here
main.jsruns, moving the page down by 33 to 82px, and its height is measured once, so it goes stale after a resize or a rotation.Notes for #278, #279 and #280
meta.htmltakesrow, andtag=falseleaves the tag out (for the strip);title.htmltakesrow, and the caller supplies the link;summary.htmltakestext. They escape everything, and they prefix their Liquid variables withactivity_, since assignments leak into the caller..activity-filtersand.activity-filtercarry the filter's shared states (colours, the bar, the focus ring, hidden without JavaScript), and the log's sizes sit under.activity-log, so the rail sets its own..activity-metaand.activity-row__versionare the other shared rules; everything else is scoped to.activity-log.jsclass and thehtml:not(.js)pattern, now in AGENTS.md: keep content in the HTML, collapse it with CSS under.js, and have the script remove the class if it fails.mathjax_ignorebelongs on the rail and the strip too, as AGENTS.md now says.activity-YYYY-MMandactivity-YYYY-MM-DD, which group and editions rows link to. Link to them as/activity/#…, never as a bare#…:main.js's smooth-scroll handler swallows those, and nohashchangefires.Closes #277.
Part of #271.
🤖 Generated with Claude Code