Skip to content

Final review pass: responsive, SEO, a11y, light mode, perf & cleanup#4

Merged
imnotannamaria merged 13 commits into
mainfrom
chore/final-review
Jul 19, 2026
Merged

Final review pass: responsive, SEO, a11y, light mode, perf & cleanup#4
imnotannamaria merged 13 commits into
mainfrom
chore/final-review

Conversation

@imnotannamaria

@imnotannamaria imnotannamaria commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Description

Pre-production final review pass before release. Makes the site presentable
on mobile, adds SEO/OG, makes light mode reachable, fixes accessibility, and
removes dead code — without changing the product (copy-paste, BYO Supabase,
zero telemetry).

Highlights

Responsive (the blocker)

  • Mobile hamburger nav (home + docs), fluid grids/padding/typography
  • e2e test guards against horizontal overflow at 390px

SEO

  • metadataBase, Open Graph, Twitter card, 1200×630 OG image
  • sitemap.ts, robots.ts, per-page canonical + OG on docs
  • Description/copy updated for the copy-paste flow (no CLI)

Performance

  • Self-hosted fonts via next/font (drops the render-blocking @import)
  • /shortcut is static (force-static), dynamicParams=false on docs
  • Rate limiter now bounds its bucket map (self-host)

Light mode — ThemeSwitcher mounted (dark/light toggle only), header and
code blocks fixed for light mode

Accessibility — nav landmarks, role="status" on the shipped loading
state, better micro-text contrast

Cleanup — delete packages/cli (dead after the pivot), 7 unused kit
components + 5 orphaned deps

Docs — iOS Shortcut setup screenshots, refreshed hero image

Validation

  • pnpm lint && pnpm test && pnpm typecheck && pnpm build all green
  • Verified in Chrome on desktop (1440px) and mobile

imnotannamaria and others added 4 commits July 18, 2026 12:19
The old da2cb73b... shortcut link was stale; docs and the dead CLI
still pointed at it instead of the current cb23e99a... link.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The product moved to a copy-paste flow but marketing/demo copy still
referenced the old CLI, the dead /api/healthkit endpoint, a removed
"partial" state, and an unpublished npm package link.

- demo cards: /api/healthkit -> /api/wristkit-sync, install-shortcut
  CTA now points at the docs instead of forcing a binary download
- home page: "7 states" -> "5 states" (partial was removed), footer
  copy no longer calls it a CLI, drop the dead npm link
- README: shortcut link label matches its actual href

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sharing a wristkit-web.vercel.app link on X/LinkedIn/WhatsApp rendered
no card, and the description still described the old CLI product.

- layout.tsx: metadataBase, openGraph, twitter card, title.template
- app/opengraph-image.tsx: 1200x630 OG image, same pattern as icon.tsx
- app/sitemap.ts + app/robots.ts
- docs page: per-page openGraph + alternates.canonical
- installation.mdx: translate leftover Portuguese paragraph to English,
  align the PASSWORD placeholder with the README

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The @import url(fonts.googleapis.com) in globals.css was a
render-blocking chain (page CSS -> Google's CSS -> 3 font families) and
the single biggest LCP cost on the site.

- layout.tsx: load Newsreader/JetBrains Mono/Inter via next/font/google,
  exposed as --font-newsreader/--font-jetbrains-mono/--font-inter
- globals.css: drop the @import, point the --font-serif/mono/sans
  tokens at the self-hosted variables
- next.config.mjs: drop fonts.googleapis.com/fonts.gstatic.com from the
  CSP now that nothing loads from there

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
wristkit-web Ready Ready Preview, Comment Jul 19, 2026 6:43pm

The site had no layout media queries: below 768px the nav links vanished
with no hamburger, fixed grids overflowed, and the 80px hero title blew
past the viewport. Converted the page-level layouts to responsive Tailwind
classes and fluid type; component internals stay inline-styled.

- top nav: add a mobile disclosure menu below md (desktop menu was
  hidden md:flex with no fallback); label both nav menus
- docs: single column below md with a collapsible sidebar (new
  DocsSidebar client wrapper), fixed 220px sidebar from md up
- home: hero, stats, registry cards, install, footer and section
  headers all stack/reflow at sm/md/lg instead of fixed multi-column
- globals.css: clamp() the display headings, responsive .container
  padding, .demo-split stacks the activity card below 480px
- docs metadata: use title.absolute so the root title.template no
  longer double-suffixes ("… · wristkit docs · wristkit")
- e2e: assert zero horizontal overflow at 390px on home + docs

Validated in Chrome at 592px (min window width) and 1440px, plus the
390px Playwright overflow checks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
imnotannamaria and others added 3 commits July 18, 2026 20:55
Accessibility pass on the remaining section-4 review items:

- top-nav: the outer TopNav rendered a second, unlabeled <nav> around
  the labeled menu <nav>. Make the outer bar a plain <div> so only the
  labeled Main/Mobile navs are landmarks.
- registry TodayActivityCardLoading: add role="status" + aria-label so
  the shipped loading state is announced (PROJECT.md contract). Panel now
  forwards role/aria-label; mirrored in the installation.mdx copy block.
- docs sidebar: section labels were 9px and the footer 10px in
  --fg-muted; bump to 11px --fg-secondary for legibility/contrast.

Validated in Chrome: only "Main" + "Mobile" nav landmarks remain, and
the sidebar micro-labels read clearly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The CLI was already private and unpublished after the pivot to a
copy-paste flow, but it stayed in the build/CI carrying stale
instructions (init.ts told users to run `npx wristkit add`, which is not
published anywhere). Keeping dead code in sync by hand is where doc bugs
come from, so remove it; git history keeps it for an eventual v2.

Nothing imports it, no changeset references it, and the release workflow
is a no-op with every package private. Lockfile regenerated (-33 deps).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Light mode CSS + the pre-paint ThemeScript already existed, but the
ThemeSwitcher was never mounted, so the user could never reach it — and
if they had, the hardcoded-dark header would have rendered black over a
white page.

- layout.tsx: mount ThemeSwitcher (ivy theme + dark/light toggle),
  matching the ThemeScript storageKey
- home header: swap the hardcoded rgba(9,9,11,.9) for
  color-mix(--bg-canvas 90%) so it follows the active mode
- code-block: keep code on a dark surface (data-surface="dark") in both
  modes — the vesper syntax theme is dark-tuned and was unreadable on
  the light-mode surface
- theme-switcher: the trigger claimed aria-haspopup="menu" but the popup
  holds toggle buttons, not menuitems — use aria-haspopup="true" +
  aria-controls to the popup id

Validated in Chrome: toggled light/dark on home + docs, header and code
blocks both read correctly, dark mode unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
imnotannamaria and others added 4 commits July 19, 2026 14:57
…deps

Robustness/perf cleanup from the review's non-blocking section:

- docs/[[...slug]]: export dynamicParams = false so unknown slugs 404 at
  the edge instead of rendering on-demand and touching the filesystem
- shortcut/route: export dynamic = "force-static" — the route now
  prerenders to a static asset (was ƒ Dynamic, now ○ Static in the build)
- wristkit-sync handler: sweep expired rate-limit buckets once the map
  passes 1000 entries, so a long-lived server can't be grown unbounded
  by spoofed x-forwarded-for IPs (mirrored in the installation.mdx copy)
- package.json: remove framer-motion and @mdx-js/react (zero imports;
  MDX runs through velite's runtime)
- delete apps/web/src/index.ts — a stray `export {}` referenced nowhere

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
These kit components were not imported by any page or reachable
component — dead code is bug surface on a public site. Removing them
drops five dependencies that nothing else uses.

- delete command-palette, dialog, dropdown, input, status-bar, toast,
  tooltip (dialog was only referenced by command-palette, itself dead)
- drop cmdk, sonner, @radix-ui/react-dialog,
  @radix-ui/react-dropdown-menu, @radix-ui/react-tooltip
  (react-tabs and react-slot stay — still used)

Note: agents/PROJECT.md and agents/RELEASE.md were also annotated to
flag the CLI->copy-paste pivot, but agents/ is gitignored so those
notes stay local only.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add the five setup screenshots to /docs/shortcut-setup: one on the
import step and a four-shot strip through the automation flow (tap +,
pick Time of Day, set daily time, pick the wristkit shortcut).

- new Screenshots component renders a horizontally-scrollable strip of
  portrait phone shots (next/image, fixed 588×1280 aspect), so the row
  scrolls sideways instead of overflowing the page on narrow screens
- registered in the MDX component map; images served from
  /public/screenshots/

Validated in Chrome at 1440px and ~536px: images load, captions read,
zero page-level horizontal overflow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New hero shot ("Your rings, your infra.") reflects the current
product: the iOS Shortcut → /api/wristkit-sync → Supabase → card
pipeline, no CLI.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Desktop:
- theme switcher: hide the theme picker when there's only one theme, so
  the popup shows just the dark/light toggle
- "Three pieces" cards: make the grid items fill the row height so all
  three cards match, with footers pinned to the bottom

Mobile:
- hero + CTA buttons stack full-width (equal size) below sm
- hero IDE preview: collapse the status bar to just the language on
  small screens instead of wrapping the endpoint onto several lines
- rings-only demo: wrap so the metrics drop below the ring instead of
  getting crushed next to it
- docs: add a sticky mobile site header (logo + hamburger) so switching
  pages no longer means scrolling back to the top. The hamburger nav is
  now a shared MobileNav component (path-aware active state), reused by
  the home top nav.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@imnotannamaria imnotannamaria changed the title Chore/final review Final review pass: responsive, SEO, a11y, light mode, perf & cleanup Jul 19, 2026
@imnotannamaria
imnotannamaria merged commit 74fba14 into main Jul 19, 2026
4 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