Skip to content

Site improvements: SEO, accessibility, decoupling & design tokens#5

Merged
HumbleBee14 merged 6 commits into
mainfrom
feature/ui-audit-batch-1
Jul 12, 2026
Merged

Site improvements: SEO, accessibility, decoupling & design tokens#5
HumbleBee14 merged 6 commits into
mainfrom
feature/ui-audit-batch-1

Conversation

@HumbleBee14

Copy link
Copy Markdown
Member

Site-wide improvements from a four-part audit (SEO, accessibility, code decoupling, design consistency). Everything is committed in reviewable chunks; type-check, 47 unit tests, and a production build all pass, and the changes were spot-verified in a preview build in both light and dark themes.

The site was already well-built — these are refinements, not rebuilds. Weighted toward SEO (the stated priority) and decoupling/export-readiness (for a possible future host/backend migration).

1. Accessibility & the writer flow (9a4f8dc)

  • Dark-mode contrast fix (P0): white-on-accent was ~2.3:1 on the salmon dark accent. Active topic tab, .btn-primary:hover, and the playground live-tag now use var(--paper) (matching the convention other accent buttons already used). Verified in dark mode: dark text on salmon (~8:1).
  • Site-wide :focus-visible ring for links/buttons/form controls; restored a keyboard ring on the /write Title/Summary inputs; aria-labels on those inputs.
  • theme-color meta now tracks the resolved data-theme (it was keyed to prefers-color-scheme, but the site theme is data-theme + localStorage, so browser chrome could mismatch the page).
  • Writer onboarding: intro leads with email (the realistic path for non-coders) and no longer links "pull request" to /pulls (which can't accept a submission); a post-download panel now explains what the .zip is and how to send it. Empty drafts no longer trigger the restore banner.

2. Decoupling & taxonomy (31ffc1e)

  • Centralized GitHub identity: SITE.org/repo/repoUrl/issuesUrl/pullsUrl/discussionsUrl derived from one constant; replaced ~10 hardcoded github.com/MLSysDev URLs across the site; deduped SITE.github/SOCIALS.github and the two Twitter encodings. (The /write repoUrl also now points at the repo, not the org — fixing the guide link and the ZIP "fork" instruction.)
  • Taxonomy single source of truth: post topicId is validated with z.enum(TOPIC_IDS) (a typo now fails the build); display names derive from topicName(id) everywhere instead of the denormalized topic frontmatter string, which had drifted (e.g. "Inference" vs canonical "Inference & Serving").
  • Added an optional updated date to the post schema (feeds dateModified + sitemap lastmod).

3. SEO (dfa0cdf)

  • URL consistency: trailingSlash: 'never' so canonicals, internal links, and the sitemap all agree (they were split before). /search is now noindex + excluded from the sitemap.
  • New indexable surface: /tags/[tag] archive pages for every post tag (keyword-targeted titles, CollectionPage + BreadcrumbList JSON-LD) plus a /tags index; article-byline tags link to them; footer surfaces /tags.
  • Structured data: BreadcrumbList on posts/topics/tags/authors/tools; ProfilePage + Person on author pages; Article authors gained a url.
  • Metadata: retargeted homepage + topic titles/descriptions to core ML-systems keywords (dropped the doubled phrasing); trimmed over-long descriptions and enriched thin ones (about/contact/authors); og:image:alt + twitter:site sitewide; article:modified_time/section/tag on posts; added the missing about/search/authors OG page images.

4. Performance & IA (f8148a1)

  • Global prefers-reduced-motion block (was only on /about).
  • HeroFigure hydrates client:visible instead of client:load.
  • KaTeX CSS scoped to the article page + /write editor instead of the global sheet — non-math pages drop ~23KB (verified: 0 KaTeX font refs on the homepage, present on articles).
  • Zero-article topics hidden and no longer generated (no thin pages in the sitemap); footer "Most read" (a duplicate of /blog) → "Tags"; "Read the style guide" anchors to #style-guide; blog empty-state copy is correct under the all-view.

5. Design tokens (5a7a4df)

  • Added --radius-* and --shadow-hover scales (pure additions; the /tags pages use the pill token).

Deliberately deferred (recommended follow-ups)

These are real audit findings I did not land here because they carry visual-regression risk best reviewed with diffs, or are larger features:

  • Design-system consolidation — the card recipe is hand-copied ~5× (about/contact/authors/community/playground) and the mono-pill "chip" pattern exists in ~7 variants under 4 names; About/Contact use blog-h1 while other pages use page-h1. Extract shared .card/.card--interactive, a .chip base, and PageHeader/IconLinkCard, then adopt the new --radius-* tokens. Low-risk but touches many pages — worth reviewing visually.
  • Article table of contents — feasible with the headings already returned by render(); a strong lever for a learning site.
  • Self-host fonts (drop the Google Fonts third-party round-trip; @fontsource already installed for OG) + fallback-metric CLS tuning.
  • Centralized content-access layer (getPublishedPosts/getPostsWithAuthors + a COLLECTIONS const) — the draft filter is duplicated across ~12 pages; consolidating it is the seam you'd re-point at a backend/API on a future migration.
  • SearchModal focus-trap + listbox/aria-activedescendant semantics.

Notes

  • The trailing-slash change makes all emitted signals consistent (no-slash). If the host (Cloudflare Pages) serves a different canonical form, a redirect rule may be worth confirming — but the signals now agree, which is the important part.
  • License: separately, LICENSE/README were updated (all content © respective author; MIT/code split removed) per your call.

Contrast (P0): white-on-accent was unreadable on the dark salmon accent —
switch active topic tab, .btn-primary:hover, and playground live-tag from
#fff to var(--paper) (matching the convention other accent buttons use).

Accessibility:
- Add a site-wide :focus-visible ring for links, buttons, and form controls
- Restore a keyboard focus ring on the Title/Summary inputs (they hard-
  stripped outline)
- Give Title/Summary accessible names via aria-label

theme-color meta: drove browser chrome off prefers-color-scheme, but the
site theme is data-theme (default light, manual toggle, no OS-follow).
Set it from the resolved theme in the pre-paint script and update it on
toggle so chrome always matches the page.

Writer onboarding:
- Lead the intro with email (the realistic path for non-coders); stop
  linking 'pull request' to /pulls, which can't accept a submission
- Add a post-download panel explaining what the .zip is and the two ways
  to send it (email-first, PR for GitHub users); auto-dismiss on next edit
- Skip saving/offering an effectively empty draft
Decoupling (for future host/backend migration):
- Add SITE.org/repo/repoUrl/issuesUrl/pullsUrl/discussionsUrl derived
  from one org+repo constant; dedupe SITE.github vs SOCIALS.github and
  the two Twitter encodings into single sources
- Replace ~10 hardcoded github.com/MLSysDev URLs across Footer, Comments,
  contact, community, contribute, index, authors, write, ArticleActions
  with SITE helpers; use SITE.pitchEmail in about
- write portal repoUrl now points at the repo (was the org URL), fixing
  the guide link and the ZIP 'fork' instruction
- Organization sameAs now uses SOCIALS (adds LinkedIn)

Taxonomy single source of truth:
- Add TOPIC_IDS + topicName() to data.ts; validate post topicId with
  z.enum(TOPIC_IDS) so an unknown/typo topic fails the build
- Derive the display name from topicId everywhere (home, blog index,
  article, author page, RSS, OG image, pagefind meta) instead of the
  denormalized frontmatter 'topic' string, which had drifted (e.g.
  'Inference' vs canonical 'Inference & Serving'); 'topic' is now
  optional and unused
- Add optional 'updated' date to the posts schema (for dateModified)
Indexing & canonicals:
- trailingSlash: 'never' so canonicals, internal links, and the sitemap
  all agree on the no-trailing-slash form (was split, canonical vs sitemap)
- noindex the /search page and exclude it from the sitemap (thin content)

New indexable surface:
- /tags/[tag] archive pages for every post tag (keyword-targeted titles,
  CollectionPage + BreadcrumbList JSON-LD) + a /tags index; article-byline
  tags now link to them; /tags/* added to sitemap priorities

Structured data:
- BreadcrumbList JSON-LD on posts, topics, tags, authors, tools
- ProfilePage + Person schema on author pages; Article authors now carry
  a url; BaseLayout jsonLd accepts an array

Metadata:
- Retarget homepage + topic-page titles/descriptions to core ML-systems
  keywords (drop the doubled topic phrasing); trim SITE.description;
  enrich thin about/contact/authors descriptions
- og:image:alt + twitter:site sitewide; article:modified_time/section/tag
  on posts; dateModified + sitemap lastmod now honor an optional 'updated'
  date; add missing about/search/authors OG page images
Accessibility:
- Global prefers-reduced-motion block (was honored only on /about) —
  neutralizes hover lifts, search-modal pop, hero fade, anchor pop, etc.
- Accessible names on Figure/Gallery remove buttons (aria-label + the
  glyph marked aria-hidden)
- Wrap the top nav in a <header> landmark

Information architecture:
- Hide zero-article topics on /topics and stop generating empty topic
  pages (no thin pages in the sitemap); consistent with the homepage
- Footer 'Most read' (duplicate of /blog) → 'Tags' (also surfaces the
  new /tags index)
- Homepage 'Read the style guide' now anchors to #style-guide
- Blog empty-state copy is correct under the all-view vs a topic filter

Performance:
- HeroFigure hydrates client:visible instead of client:load (homepage
  main-thread win)
- KaTeX CSS scoped to the article page + /write editor instead of the
  global sheet — non-math pages drop ~23KB (verified: 0 KaTeX font refs
  on home, present on articles)
Introduces a border-radius scale (xs/sm/md/lg/pill/circle) and a shared
card hover-elevation token. Pure additions — the /tags pages use the pill
token now; adopting them across existing components and consolidating the
duplicated card/chip/page-header patterns is a deliberate follow-up (see
PR notes) to keep visual-regression risk reviewable.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 12, 2026

Copy link
Copy Markdown

Deploying mlsystems with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8af2fab
Status: ✅  Deploy successful!
Preview URL: https://37944ff1.mlsystems.pages.dev
Branch Preview URL: https://feature-ui-audit-batch-1.mlsystems.pages.dev

View logs

The Table item was the only slash-menu entry without an icon; add a
grid-with-header glyph so it matches the others.
@HumbleBee14 HumbleBee14 merged commit 38a6221 into main Jul 12, 2026
2 checks passed
@HumbleBee14 HumbleBee14 deleted the feature/ui-audit-batch-1 branch July 12, 2026 22:41
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