diff --git a/README.md b/README.md
index 65ced05..60d88f3 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ The site has two streams of updates. The rule of thumb: **people write News, the
**Promotion is a human decision.** When a release or a batch of lecture changes deserves wider attention, someone writes a News post that links to it.
-These definitions decide which stream an item belongs to, not where it is shown. News posts are stored in `_posts/` and Activity entries in `_data/activity/` (schema below). Which pages display each stream is a design choice: today News appears on `/news/`, the home page and `feed.xml`, and Activity on `/activity/` and beside News on `/news/`.
+These definitions decide which stream an item belongs to, not where it is shown. News posts are stored in `_posts/` and Activity entries in `_data/activity/` (schema below). Which pages display each stream is a design choice: today News appears on `/news/`, the home page and `feed.xml`, and Activity on `/activity/`, beside News on `/news/` and, as its three newest rows, on the home page.
### Activity data
diff --git a/_layouts/home.html b/_layouts/home.html
index f45396e..e09e100 100755
--- a/_layouts/home.html
+++ b/_layouts/home.html
@@ -232,8 +232,7 @@
Latest News
diff --git a/assets/main.scss b/assets/main.scss
index 952e9c1..1a3fff3 100755
--- a/assets/main.scss
+++ b/assets/main.scss
@@ -2417,6 +2417,157 @@ body.sponsor-bar-visible.internal main {
}
}
+// The home page's "Latest activity" strip: the 3 newest rows, each one link. Below 1200px, a
+// stacked list with 44px rows; from 1200px, one line in which only titles are cut.
+.activity-strip {
+ margin-top: 24px;
+ padding: 14px 16px 0;
+ border: 1px solid #dbe8f5;
+ border-radius: 8px;
+ background: #eef4fb;
+ a:focus-visible {
+ outline: 2px solid $color-link;
+ outline-offset: 2px;
+ }
+}
+
+.activity-strip__label {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin: 0 0 6px;
+ font-size: 15.2px;
+ font-weight: 700;
+ color: $color-dark;
+ .bi {
+ color: $color-link;
+ }
+}
+
+.activity-strip__rows {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ li {
+ padding: 8px 0;
+ border-top: 1px solid #dbe8f5;
+ }
+}
+
+// The icon, date and tag on the first line and the title under them. In the HTML the title
+// comes before the tag: the order in which a screen reader reads the link. On hover only the
+// title changes.
+.activity-strip__link {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ column-gap: 6px;
+ min-height: 44px;
+ font-size: 13.6px;
+ line-height: 1.4;
+ &,
+ &:hover {
+ color: inherit;
+ text-decoration: none;
+ }
+ .activity-meta__icon {
+ color: $color-link;
+ }
+}
+
+.activity-strip__title {
+ order: 1;
+ flex-basis: 100%;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 2;
+ overflow: hidden;
+ margin-top: 3px;
+ font-size: 15.2px;
+ font-weight: 700;
+ color: $color-dark;
+ .activity-strip__link:hover & {
+ color: $color-visited;
+ text-decoration: underline;
+ }
+}
+
+.activity-strip__all {
+ display: flex;
+ align-items: center;
+ min-height: 48px;
+ border-top: 1px solid #dbe8f5;
+ font-size: 14.4px;
+ font-weight: 700;
+}
+
+// One line. Each row gets an equal share of it but no more than its content needs, so a short
+// title leaves its space to a long one. A row's minimum is its min-content: the icon, date and
+// tag, and one letter of the title, which can wrap anywhere and is clamped to one line. So only
+// titles are ever cut. (The handoff's min-width: 0 on each row and nowrap title keep a tag
+// whole only while the line has width to spare.)
+@media (min-width: 1200px) {
+ .activity-strip {
+ display: flex;
+ align-items: center;
+ gap: 20px;
+ min-height: 48px;
+ padding: 0 18px;
+ border-color: $color-border;
+ background: $color-light;
+ }
+ .activity-strip__label {
+ flex: none;
+ margin: 0;
+ font-size: 12px;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ color: #666;
+ .bi {
+ font-size: 14px;
+ }
+ }
+ .activity-strip__rows {
+ display: flex;
+ flex: 1 1 auto;
+ min-width: 0;
+ color: #666; // the row links inherit it
+ li {
+ flex: 1 1 0;
+ max-width: max-content;
+ padding: 0 20px;
+ border-top: 0;
+ border-left: 1px solid $color-border;
+ }
+ }
+ .activity-strip__link {
+ flex-wrap: nowrap;
+ align-items: baseline;
+ gap: 8px;
+ min-height: 0;
+ font-size: 13px;
+ white-space: nowrap;
+ .activity-meta__icon {
+ font-size: 12px;
+ }
+ }
+ .activity-strip__title {
+ order: 0;
+ flex: 0 1 auto;
+ margin: 0;
+ -webkit-line-clamp: 1;
+ white-space: normal;
+ word-break: break-all;
+ font-size: 14px;
+ }
+ .activity-strip__all {
+ flex: none;
+ min-height: 0;
+ border: 0;
+ font-size: 13.6px;
+ }
+}
+
/* Respect a reduced-motion preference for the card and button transitions */
@media (prefers-reduced-motion: reduce) {
.qe-card,