Skip to content

activity: add the Activity rail to /news/, with a collapsed panel below 1200px - #291

Merged
mmcky merged 1 commit into
mainfrom
news-activity-rail
Sep 30, 2026
Merged

mmcky merged 1 commit into
mainfrom
news-activity-rail

Conversation

@mmcky

@mmcky mmcky commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

Merge after the Activity feed's first live PR has merged (the decision on #278), so the rail doesn't launch showing 'latest Sep 27'.

Three calls for you on the preview

  1. The panel height. The rail is built full height, as designed: its tinted column runs the length of the news, and the list sticks inside it. See "The panel height, your call" below.
  2. The filter's gaps on phones. Below 576px the five filter buttons have 10px gaps, so they fit on one line from 390px; at 360 and 375px Books still wraps to a second line. The handoff's 18px wraps Books at every phone width up to 414px. It is one number in main.scss.
  3. The back-to-top button at 1200–1239px wide. While the list is stuck by its bottom edge (All, Releases and Lectures in a 720px-tall window), the site's round back-to-top button covers the right end of "View all activity": 13×36px at 1200×720, a few pixels at 1220px, and nothing from 1240px. The text and most of the button stay usable. Keyboard users aren't affected: a list with focus in it doesn't stick, so a focused "View all activity" is never under the button. If it matters, the remedy is one number: a bottom gap of about 90px instead of 24px in the sticky rule.

What changes

  • /news/ gets the Activity rail from the round-2 design. At 1200px and wider the news and the rail sit in a 2fr/1fr grid (832 + 416px at 1440, 712 + 356px at 1280); below that the same <aside> is a panel between the h1 and the news, collapsed from first paint.
  • The rail shows the latest 6 updates under Monday–Sunday week headings, a type filter (All, Releases, Lectures, Translations, Books) and "View all activity". Each filter shows that type's latest 6 rows; a type with none shows "No book updates yet" in a dashed box. A visually hidden live region announces each change ("Showing 6 lecture updates").
  • Stickiness: only the list sticks. It sticks 24px under the header when it fits in the window, and otherwise scrolls until its bottom is 24px above the window's bottom and sticks there, so every row and "View all activity" can be reached. The script keeps the list's height in --rail-h with one ResizeObserver; the sticky rule reads it.
  • Keyboard focus in the list: while a row or "View all activity" has keyboard focus, the list scrolls with the page instead of sticking (:has(:focus-visible), one rule). Stuck by its bottom edge, a tall list's top rows can't be scrolled into view, so without this a keyboard user who pages down and then tabs could focus a row that stays off-screen or under the header. Mouse clicks don't match :focus-visible, so nothing moves under the pointer. The cost is small: after a click in a stuck list, the next Tab scrolls the page back to the list's own place.
  • The panel reads "Activity · 6 updates in September · latest Sep 27" with "Library releases and lecture updates, from GitHub" under it. Opened, it shows the rail's content on the soft-blue surface. The toggle's focus ring is drawn 6px inside the button, because the second line is pulled 6px up into its box and an outside ring ran through that line. On phones the summary drops to its own line and each row's title link is stretched over the row.
  • Without JavaScript the rail shows the All view, the filter and toggle are hidden, the panel is open under a plain "Activity" heading, and the list doesn't stick. If the script fails, it removes the js class, which gives the same state.
  • What the handoff left out is in: the collapse rule is scoped to below 1200px, /news/ gets the scroll-padding-top that /activity/ has, section.inner-page gets overflow: clip on this page so sticky works, and a visually hidden "Latest news" h2 keeps the posts from being filed under "Activity".
  • The intro line under the News h1 is removed. README ("News and Activity") now says Activity also appears beside News on /news/, and AGENTS.md lists the rail with the other controls that follow the js-class pattern.
  • Files: _layouts/news.html (the markup and one inline script, like /activity/'s), assets/main.scss (one block at the end of the Activity section, plus one selector each on the overflow: clip and scroll-padding-top rules), pages/archives.md, README.md and AGENTS.md. No include, main.js, default.html or shared Activity rule changes.

The panel height, your call

The rail is built full height. With the fixture's data the list fills 16% (All) and 12% (Translations) of the tinted column, which is 3,515px tall at 1440 and 3,640px at 1280, so most of the column is empty tint below "View all activity". The fitted fallback makes the column transparent and moves the tint, border and radius onto the sticky list: three declarations. Please judge at 1280×720 and 1440×900 under All and Translations, and record the choice in #266's Decisions table. To see the fitted version on the preview, paste this into the browser console:

document.head.insertAdjacentHTML('beforeend', '<style>@media (min-width:1200px){.activity-rail__panel{border:0;background:none}.activity-rail__list{border:1px solid var(--rail-line);border-radius:8px;background:var(--rail-surface)}}</style>')

Defaults to review on the preview

  • The collapsed panel's second line is a paragraph under the toggle's heading, aligned with the label, shown only while collapsed; the open panel shows the longer subtitle instead. It sits outside the button, so the hover tint covers only the heading row.
  • The small "Activity" label at the top of the sticky list is CSS-generated, styled like the week headings, shown only in the rail, and hidden from screen readers. CSS can't tell when the list is stuck, so it always shows.
  • Five text-only filter buttons, Books last, as on /activity/. In the rail they need 318.5px with Roboto (334.3px before it loads) of 356 or 416px.
  • Books stays in the filter while there are no book updates, and shows the dashed "No book updates yet" box. The alternative is to hide it until a book row exists.
  • "View all activity" reuses the home page's outline button (.qe-btn--outline-dark, 46px tall), white-filled in the panel.
  • The panel's date is the view's text, so it isn't wrapped in <time>. text-wrap: balance keeps "latest Sep 27" together on phones.
  • No "Activity feed" link: /activity/feed.xml doesn't exist on main. Publish an Activity RSS feed at /activity/feed.xml #280 adds it.
  • With no Activity data there is no aside, and the news keeps its two-thirds column.

How it was tested

The preview builds this branch from 88beeef, whose _data/activity/ equals #276's fixture, so it shows the fixture's numbers. The exact numbers were also checked on a build with data_dir set to the fixture, and a hostile synthetic set was built for escaping, MathJax and overflow. Headless Chrome 154 at 320, 360, 375, 390, 414, 576, 768, 1024, 1199, 1200, 1280 and 1440px.

Check Result
Data check, both test suites, production build pass; the built site differs from main only in /news/, README.md and main.css
1: 390×844, bar shown, panel collapsed the newest post's title at 432–493px (bar 62px, panel 139px); 320×568: bottom 533
2: no horizontal scroll at 320px pass, collapsed and open under every filter, fixture and synthetic data
3: 1280×720 and 1200×720 with the bar every row and "View all activity" reachable under every filter; All, Releases and Lectures stick by the bottom edge, Translations and Books 24px under the header
4: rows and week headings per filter match the fixture: All 6 rows in Sep 21–27 and Sep 14–20; Releases 6 back to Aug 16; Lectures 6 back to Jul 23 in 4 weeks; Translations Aug 20 and Aug 3 (3 editions); Books empty
8: contrast and focus lowest contrast 4.59:1; every rail control shows the 2px ring (the panel's toggle inside its button, clear of the second line). Every focused control is fully visible: tabbing forward; Shift+Tab from the news cards at 1280×720 and 1200×720 under each filter from 4 scroll positions (worst case 16px below the header, under Lectures); and Tab or Shift+Tab from inside a list stuck by its bottom edge, after PageDown or after a click in the list, at 1280×720 and 1440×900
Pointer use of a stuck list a click on a row title lands on the link, and the list doesn't move (All, Lectures, Translations at 1280×720)
9: the panel's text "Activity · 6 updates in September · latest Sep 27" at 1024, 768 and 576px, the second line below; on phones the summary on its own line
Resizing across 1200px with the panel open stays open (aria-expanded="true")
JavaScript off, a failing script, no data the All view, open panel, static list; nothing moves when the script runs; no aside without data
Accessibility tree h1 News, h2 Activity (one per mode), h3 week headings, h2 Latest news, h2 Older Posts; the aside is named "Activity"; the CSS label isn't exposed
MathJax and escaping nothing typeset in the rail; every field escaped, attributes included

Please look in iOS Safari and Firefox

The testing was Chrome only. Sticky needs :has() and overflow: clip (Firefox 121+, Safari 16+; older browsers get a static list), and tabbing through a stuck list should bring each focused row into view. Font metrics decide where titles clamp and whether the filter fits, and VoiceOver should still read the rows and weeks as lists. Chrome reads the week headings in capitals ("SEP 21–27") because of text-transform: uppercase; worth a listen in VoiceOver.

Pre-existing, not changed here

  • The sponsor bar pops in by 33–82px when main.js runs, and its height is measured once.
  • .qe-btn's transition: all animates focus rings, so the ring on "View all activity" settles after 0.2s.
  • The site's phone gutters are 28px against the prototype's 12px, so the panel's label and the filter wrap sooner (the collapsed panel is 139px tall at 390px).

Notes for #279 and #280

Closes #278.
Part of #271.

🤖 Generated with Claude Code

…ow 1200px

/news/ gets the Activity rail from the round-2 design. At 1200px and
wider the news and the rail sit in a 2fr/1fr grid: the rail's tinted
panel runs the full height of the news column, and the list inside it
sticks 24px under the header when it fits, and otherwise by its bottom
edge, 24px above the window's. The inline script keeps the list's
height in --rail-h with one ResizeObserver for that rule. While
keyboard focus is in the list, it scrolls with the page, so the browser
can bring a focused row into view. Below 1200px the same <aside> is a
panel above the news, collapsed from first paint under the js class:
"Activity · 6 updates in September · latest Sep 27", with "Library
releases and lecture updates, from GitHub" under it.

- The rail reads site.data.activity_view: the latest 6 rows of each
  type in week groups, with the All view rendered as the state without
  JavaScript, through the shared meta, title and summary includes.
- A five-button type filter (All, Releases, Lectures, Translations,
  Books) with a live region, and "View all activity". Below 576px the
  filter's gaps are 10px, so it fits on one line from 390px.
- Four --rail-* custom properties on the aside hold the colours that
  differ between the panel and the rail. The panel's toggle draws its
  focus ring inside the button, clear of the second line.
- mathjax_ignore on the aside; overflow: clip and scroll-padding-top
  on this page; a visually hidden "Latest news" heading; on phones,
  each row's title link stretched over the row.
- The intro line under the News h1 goes. README and AGENTS.md say
  where the rail is and that it follows the js-class pattern.

Part of #278.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@netlify

netlify Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for grand-swan-ca5201 ready!

Name Link
🔨 Latest commit 5b5b656
🔍 Latest deploy log https://app.netlify.com/projects/grand-swan-ca5201/deploys/6abd2347ef8c0f00070b20f1
😎 Deploy Preview https://deploy-preview-291--grand-swan-ca5201.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@mmcky
mmcky marked this pull request as ready for review September 30, 2026 21:52
Copilot AI balanced review requested due to automatic review settings September 30, 2026 21:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

It is a large, accessibility- and layout-sensitive change relying on :has(), overflow: clip, and sticky behavior that the author explicitly flagged as untested outside Chrome, with merge-ordering dependencies best confirmed by a human on the preview.

Review effort: Balanced
Findings: None

What changed in this PR

This PR implements the Activity rail on /news/ (Phase 4 of #271, closing #278). At ≥1200px the news posts and an Activity rail sit in a 2fr/1fr grid; below that the same <aside> becomes a collapsed panel above the posts. The rail shows the latest 6 updates grouped by Monday–Sunday weeks with a type filter (All/Releases/Lectures/Translations/Books), a "View all activity" button, and a visually hidden live region. Only the rail's list sticks (by its bottom edge when taller than the viewport), driven by a --rail-h value maintained by a ResizeObserver; it degrades gracefully to a static All view without JavaScript. The rail reuses the existing site.data.activity_view data and the _includes/activity/{meta,title,summary}.html partials, mirroring the /activity/ layout's escaping, mathjax_ignore, and js-class conventions.

Changes:

  • Add the Activity rail/panel markup and one inline script to _layouts/news.html, gated on activity_view.panel.
  • Add the rail's styles to assets/main.scss (responsive grid, panel/rail color tokens, sticky list, focus rings) and extend the overflow: clip and scroll-padding-top :has() selectors to .activity-rail.
  • Remove the intro line under the News h1 and update README.md/AGENTS.md docs.
File Description
_layouts/​news.html Adds the rail/panel markup (week groups, filter, toggle, live region) and the inline filter/toggle/sticky-height script; wraps the posts in .news-main with a hidden "Latest news" h2.
assets/​main.scss Adds the .activity-rail block (responsive panel↔rail, timeline rows, sticky list keyed on --rail-h), and extends the shared overflow: clip and scroll-padding-top rules to .activity-rail.
pages/​archives.md Removes the intro paragraph under the # News heading.
README.md Notes that Activity now also appears beside News on /news/.
AGENTS.md Documents the /news/ rail's filter and panel as following the js-class pattern.

I reviewed the markup, the inline script, the SCSS, and the docs against the activity_view generator, the /activity/ layout, and the .team-toc sticky precedent. Class names are consistent across markup/CSS/JS, every field is escaped, the panel/rail/in_all/has_all/per_edition data shape matches the generator, the no-JS and no-data paths are handled, and the heading hierarchy and :has()/overflow: clip/scroll-padding-top context follow established patterns. I did not find concrete defects to flag.


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@mmcky
mmcky merged commit 2329aed into main Sep 30, 2026
6 checks passed
@mmcky
mmcky deleted the news-activity-rail branch September 30, 2026 22:36
mmcky added a commit that referenced this pull request Sep 30, 2026
Brings in the Activity rail on /news/ (#291) and the feed's first
lecture entry (#293). README's line on where Activity appears now names
both: /activity/, beside News on /news/ and, as its three newest rows,
on the home page.

Part of #279.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add the Activity rail and mobile panel to /news/

2 participants