Skip to content

feat(blog): brand-polish landing + Recent articles home section#543

Merged
blove merged 15 commits into
mainfrom
claude/lucid-moore-c390f9
May 25, 2026
Merged

feat(blog): brand-polish landing + Recent articles home section#543
blove merged 15 commits into
mainfrom
claude/lucid-moore-c390f9

Conversation

@blove
Copy link
Copy Markdown
Contributor

@blove blove commented May 25, 2026

Summary

This branch is the second wave of blog work on top of the brand-polish landing PR. Two shipments stacked into one PR:

1. Blog landing + article-page polish (commit 96e57b8d):

  • /blog H1 → "Articles from ThreadPlane"
  • All [data-ui="card"][data-hoverable] cards now show cursor: pointer site-wide (was default)
  • New compact formatCardDate ("May 17" when same year) on landing cards; long form stays on the article page
  • BlogTagFilter chips get cursor:pointer (active "All" stays default)
  • Article-page TagChips are now real <Link>s back to /blog?tag=<tag>
  • List rendering fix: Lightning CSS was silently rewriting list-style: disc shorthand to list-style: outside, dropping the bullet type and letting Tailwind preflight's list-style: none win. Switched to list-style-type longhand. Bullets now appear in MDX articles.
  • Screenshot frames: figure:has(> img) gets a tinted backdrop + soft shadow + clean italic centered caption, scoped to image figures so it doesn't touch code blocks or component figures.

2. Recent articles home section (commits 159f3b80 + 588b1a12):

  • New <RecentArticles /> server component sits between <FinalCTA /> and the footer on /
  • Reuses the existing <PostCard> in a 3-column auto-fill grid
  • Server filters via new getRecentNonFeatured(limit = 3) helper so the featured post from /blog doesn't get duplicated
  • Hides itself when no eligible posts exist (current state: 1 card, since both extant posts are featured: true so only the non-chosen one ends up here)
  • 3 new unit tests for the helper, 3 new Playwright assertions on the home page
  • Spec + plan committed under docs/superpowers/

Test plan

  • nx lint website clean
  • nx test website green (12 unit tests in blog.spec.ts, including 3 new)
  • nx e2e website green (existing + 3 new home + 3 existing blog landing)
  • Manual: /blog shows new title, cursor pointer on chips + cards, short dates ("May 17"), tag chips on article page navigate to /blog?tag=, MDX lists show bullets, screenshot in the AG-UI article has the new frame
  • Manual: bottom of / shows "BLOG / Recent articles" with one card and "View all articles →" link

🤖 Generated with Claude Code

blove and others added 14 commits May 23, 2026 07:33
Reusable infrastructure changes ahead of publishing the AG-UI tutorial post.

- MdxRenderer is now layout-agnostic: docs and blog each own their outer
  chrome (sidebar padding lived in MdxRenderer and was fighting the blog
  page's article wrapper). Docs page absorbs the chrome it relied on;
  root element switched from <article> to <div> to avoid nested-article
  hydration mismatches.
- Tabs body wrapper no longer paints its own border/background — the inner
  rehype-pretty-code <figure> already owns its surface, and the wrapper
  was creating a visible "extending border" below short code blocks.
- global.css: restore disc/decimal list markers + padding on .docs-prose
  ul/ol (Tailwind preflight had stripped them), drop the duplicate inset
  box-shadow ring on code-block <pre>, and add responsive rules for the
  new arch diagram so it collapses to a single column under 720px.
- New AgUiArchDiagram component: three brand-styled boxes (Backend →
  @ngaf/ag-ui adapter → @ngaf/chat UI) with labeled SSE / Agent-contract
  arrows. Replaces hand-drawn ASCII art that drifted out of alignment
  due to rehype-pretty-code line padding + JetBrains Mono fallbacks for
  box-drawing glyphs.
- Blog post template (apps/website/src/app/blog/[slug]/page.tsx): proper
  paddingTop offset so the date no longer clips behind the fixed nav,
  brand <Eyebrow> with category/date/reading-time, large Garamond H1
  matching the homepage hero, description as bodyLg subhead, tag chips
  driven by frontmatter.tags, and a right-column DocsTOC at ≥xl widths.
  Adds a UTC-anchored formatDate to avoid "2026-05-21" rendering as
  "May 20" west of UTC.
- .claude/launch.json: add ag-ui-streaming entry pointing at the AG-UI
  cockpit demo for an upcoming follow-up that will swap in a real hero
  screenshot once libs/render tsconfig is unblocked.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New long-form tutorial post (~2,700 words) targeted at Angular devs new
to the agent stack, covering the AG-UI protocol, the @ngaf/ag-ui adapter,
and a worked example using @ngaf/chat.

- Personal proof-of-source in the lede (Head of Ecosystem and
  Partnerships at CopilotKit; AG-UI protocol contributor) so readers
  know the recommendations come from inside the work.
- Featured-post frontmatter (featured: true) so it surfaces on /blog.
- Hero screenshot deferred — libs/render tsconfig is blocking the AG-UI
  cockpit demo build; tracked as a follow-up that will swap in a real
  streaming-mid-frame shot once unblocked.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ESLint no-useless-escape flagged \- inside a character class. Moving the
hyphen to the end of the class drops the escape without changing the
matched set.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The MdxRenderer refactor (root <article> → <div> to avoid nested-article
hydration mismatch on blog) inadvertently dropped the <article> tag from
docs pages too, breaking the docs e2e selectors (page.locator('article'),
page.locator('article h2')).

Restore the <article> on the docs page wrapper instead of inside
MdxRenderer. The blog page keeps its own outer <article>; both surfaces
now have exactly one <article>, satisfying semantic HTML and the existing
e2e contracts without re-introducing the hydration warning.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Spec for matching /blog to the brand standard already shipped on
/blog/[slug] and adding a server-rendered ?tag= filter. Covers component
breakdown, data flow, accessibility, testing, and risks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move the two formatting utilities from the slug page into lib/blog.ts so
the upcoming /blog landing page can share them without duplication.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ing time)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rewrites blog/page.tsx as an async Server Component: awaits searchParams
for tag filtering, shows FeaturedPostCard only when no filter is active,
excludes featured slug from the grid, and renders a token-styled empty
state when no posts match the active tag.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Landing H1: "Notes from ThreadPlane" → "Articles from ThreadPlane".
- PostCard + FeaturedPostCard: cursor:pointer on the Link (and flip the
  global `[data-ui=card][data-hoverable]` cursor from default to pointer
  so every hoverable card on the site stops faking non-interactivity).
- formatCardDate: short month + day, drop year when current; landing
  cards switch to it so "MAY 17, 2026" stops repeating across cards.
- BlogTagFilter: cursor:pointer on chips; active "All" stays default.
- TagChips on the article page: now real <Link>s to /blog?tag=<tag>.
- docs-prose list rendering: Lightning CSS was rewriting
  `list-style: disc` shorthand to `list-style: outside`, which lets
  Tailwind preflight's `list-style: none` win and drops bullets.
  Switched to `list-style-type` longhand. Tightened li spacing.
- docs-prose figure: tinted backdrop + soft shadow + clean caption
  for screenshots, scoped via :has(> img) so it doesn't touch code
  blocks or component figures.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New canvas-surface section between FinalCTA and the footer that shows the
three most recent non-featured posts using the existing PostCard. Hides
itself when no eligible posts exist, so the home page stays clean while
the blog catalog is small.

- New helper getRecentNonFeatured(limit = 3) in lib/blog.ts filters the
  featured post out of getAllPosts (avoids duplicating /blog's hero).
- New RecentArticles server component composes Section + Container +
  Eyebrow + h2 + grid + "View all articles →" tail link.
- Three new unit tests for getRecentNonFeatured + three Playwright
  assertions on the home page (header id, card link, tail href).

Plan: docs/superpowers/plans/2026-05-25-recent-articles-home-section.md
Spec: docs/superpowers/specs/2026-05-25-recent-articles-home-section-design.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…cles

Captures the brainstorm outputs and implementation plans for the two
blog-area shipments on this branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
threadplane Ready Ready Preview, Comment May 25, 2026 8:38pm

Request Review

@blove blove enabled auto-merge (squash) May 25, 2026 20:12
…90f9

# Conflicts:
#	apps/website/content/blog/2026-05-21-build-fullstack-agentic-angular-apps-using-ag-ui.mdx
#	apps/website/src/app/blog/[slug]/page.tsx
#	apps/website/src/app/blog/page.tsx
#	apps/website/src/app/global.css
#	apps/website/src/app/page.tsx
#	apps/website/src/components/blog/TagChips.tsx
#	apps/website/src/components/docs/AgUiArchDiagram.tsx
@blove blove merged commit d642416 into main May 25, 2026
20 checks passed
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.

1 participant