- Add skip-to-main-content link and main content ID target
- Add prefers-reduced-motion media queries for all animations
- Enhance visible focus indicators (2px offset, high-contrast ring)
- Replace ~160 text-surface-500 instances with text-surface-600/dark:text-surface-400
for 4.5:1+ contrast ratio compliance
- Add aria-hidden="true" to ~30+ decorative SVG icons across sidebars/widgets
- Convert facepile containers from div to semantic ul/li with role="list"
- Add aria-label to icon-only buttons (share, sort controls)
- Add sr-only labels to form inputs (webmention, search)
- Add aria-live="polite" to dynamically loaded webmentions
- Add aria-label with relative+absolute date to time-difference component
- Add keyboard handlers (Enter/Space) to custom interactive elements
- Add aria-label to nav landmarks (table of contents)
- Fix modal focus trap and dialog accessibility
- Fix lightbox keyboard navigation and screen reader announcements
Confab-Link: http://localhost:8080/sessions/edb1b7b0-da66-4486-bd9c-d1cfa7553b88
Compact widget showing AI transparency stats (total, AI-involved,
human-only, ratio), level breakdown pills, and a 1-year post-graph
highlighting AI-involved posts. Links to /ai/ for full report.
Confab-Link: http://localhost:8080/sessions/edb1b7b0-da66-4486-bd9c-d1cfa7553b88
PagefindUI in the ~300px sidebar caused 218+ results to expand inline,
pushing content down with poor readability. Replace with a simple GET
form that redirects to /search/?q=query in all four sidebars.
Confab-Link: http://localhost:8080/sessions/4d40ef89-a713-48c1-b4ed-0ffafca25677
Replace the entire color system with a design-driven warm palette:
- Surface tokens: cold zinc grays → warm stone (#faf8f5 to #0f0e0d)
- Accent tokens: cold teal → warm amber (#fffbeb to #451a03)
- All bg-white → bg-surface-50 across templates (warm cream instead of pure white)
- Critical CSS: all hardcoded hex values updated to warm palette
- Prism code blocks: cold gray backgrounds → warm stone
- Pagefind search UI: blue buttons/links → amber interactive colors
- Dark mode: warm dark surfaces with amber accents throughout
Design system documented in .interface-design/system.md
Confab-Link: http://localhost:8080/sessions/bd3f7012-c703-47e9-bfe2-2ad04ce1842d
- Add teal accent color scale and activate Inter font via @font-face
- Neutralize nav/footer hovers from primary blue to surface neutrals
- Apply accent color to hero subtitle, FAB, CTA buttons, card hovers
- Fix reply post-type color from generic primary to distinctive sky blue
- Create centralized icon macro (icon.njk) with 24 reusable SVG icons
- Add per-widget-type icons and colored left-accent borders to all sidebars
- Update .p-category tags from blue to neutral surface with border
- Diversify color vocabulary: red (likes), amber (bookmarks/blogroll),
green (reposts), purple (funkwhale), sky (replies), orange (subscribe)
Confab-Link: http://localhost:8080/sessions/bd3f7012-c703-47e9-bfe2-2ad04ce1842d
Add color-coded left borders to post cards on all blog listing and
category pages, and make sidebar widgets collapsible with localStorage
persistence on both listing and single-post sidebars.
Reuses the existing fediverseInteract Alpine.js component to let
visitors follow the site author from their own fediverse instance.
Registered in all three sidebar routers (homepage, blog listing,
blog post) as widget type "fediverse-follow".
Add <is-land on:visible> lazy-loading wrapper to every widget template
and the comments section for consistent deferred rendering. Widgets
that already had it (social-activity, github-repos, blogroll, feedland,
webmentions) are unchanged. Also wraps inline search and custom-html
widgets in all sidebar container files.
The search and custom-html widget types were using a non-existent
sidebar-widget class instead of the standard .widget class, causing
them to lack the spacing, border, and background styling that all
other widgets get. Updated all 4 sidebar containers.
Add recent-comments widget case to data-driven routers in sidebar.njk
and homepage-sidebar.njk (was missing). Add to fallback defaults in
both sidebar.njk and blog-sidebar.njk so it shows without homepage
builder configuration.
- Comment area on post pages (IndieAuth sign-in, submit, display)
- Alpine.js client-side component for auth flow and comment CRUD
- Recent comments sidebar widget with build-time data fetching
- Include comments.js in base layout, comments.njk before webmentions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replicates Dave Winer's blogroll.js visual rendering (240px bordered
container, Ubuntu/Rancho fonts, Title/When sort, caret wedges, truncated
titles, relative timestamps, "Powered by FeedLand" footer) using Alpine.js
and the blogroll API instead of jQuery + external scripts.
Registered in all three sidebar types (homepage, blog listing, blog post)
and in the fallback sidebar.
Pagefind CSS/JS is now loaded once in base.njk <head> with defer.
A tiny initPagefind() helper queues widget inits until DOMContentLoaded
when PagefindUI is available. Removes duplicate <link>/<script> tags
from all sidebar widgets, search page, and 404 page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Post navigation (prev/next) now renders below the syndication block
in the main content flow, matching how listing pages work. Removed
from sidebar widget system.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix recentPosts collection glob (content/posts/ → content/) so the
widget actually finds posts. Extract blog-sidebar widgets into reusable
partials. Make both sidebar.njk (listing pages) and blog-sidebar.njk
(post pages) configurable via homepageConfig.blogListingSidebar and
homepageConfig.blogPostSidebar, with fallback to current hardcoded
widgets for backward compatibility.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Recent Posts widget and Previous/Next navigation now show colored
icons and descriptive labels for likes, bookmarks, reposts, and
replies instead of "Untitled".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
HTML entities in href and value attributes don't decode properly -
browsers treat them as literal strings. Only obfuscate display text.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add obfuscateEmail Eleventy filter that converts email to HTML entities
- Apply to h-card.njk (both mailto: href and display text)
- Apply to blog-sidebar.njk hidden data element
- HTML entities block ~95% of spam harvesters while remaining valid
for IndieWeb microformat parsers (u-email for rel="me" auth)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add social links nav with rel="me" to sidebar h-card (was only in
standalone h-card.njk component, never included by sidebar)
- Add hidden <data class="u-photo"> for reliable microformat parsing
(some parsers struggle with img nested inside links)
- Fix social links fallback in site.js: auto-generate from feed config
(GITHUB_USERNAME, BLUESKY_HANDLE, etc.) when SITE_SOCIAL is not set
- Add hidden email/org data elements to blog-sidebar compact h-card
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This reverts commit d6640d5 and 70c6622 which broke the sidebar rendering.
Restoring the working 3-implementation approach.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- h-card.njk is now the single source of truth
- sidebar.njk includes h-card with variant='full'
- blog-sidebar.njk includes h-card with variant='compact'
- Removed duplicate h-card code from both sidebars