Add homepage wall of love, FAQ, blog post, footer redesign, and SEO improvements

## Summary
- Add Community (testimonials) section to homepage with inline avatars
- Add FAQ section sourced from HN discussion questions
- Add hero screenshot with next/image optimization
- Add Show HN blog post with react-tweet embeds, star history chart, and HN quotes
- Redesign footer with 4-column grid layout (Product, Resources, Legal, Social)
- Add Download/GitHub CTA buttons at bottom of homepage and blog post
- Add dev spacing controls for features, FAQ, and community sections
- Fix hydration error (JSON-LD moved to head)
- SEO: full metadata on blog posts, robots.txt, blog pages in sitemap, canonical URLs
- Replace em dashes site-wide, fix notification descriptions

## Testing
- `bun tsc --noEmit` passes clean
- Dev server verified on port 3001

## Related
- Task: Add wall of love to main web page + landing screenshot
This commit is contained in:
Lawrence Chen 2026-02-21 06:16:38 -08:00 committed by GitHub
parent 8ac554fb06
commit be9b994a79
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 8219 additions and 192 deletions

View file

@ -10,7 +10,10 @@ type DevValues = {
downloadAbove: number;
downloadBelow: number;
featuresLh: number;
featuresMb: number;
featuresPt: number;
featuresPb: number;
communityGap: number;
faqPt: number;
docsPt: number;
};
@ -20,9 +23,12 @@ const defaults: DevValues = {
cursorBlink: true,
subtitleLh: 1.5,
downloadAbove: 21,
downloadBelow: 33,
downloadBelow: 16,
featuresLh: 1.275,
featuresMb: 23,
featuresPt: 12,
featuresPb: 15,
communityGap: 6,
faqPt: 0,
docsPt: 8,
};
@ -67,8 +73,21 @@ function applyToDOM(v: DevValues) {
const featuresUl = el("features-ul");
if (featuresUl) featuresUl.style.lineHeight = `${v.featuresLh}`;
const featuresSpacer = el("features-spacer");
if (featuresSpacer) featuresSpacer.style.height = `${v.featuresMb}px`;
const features = el("features");
if (features) {
features.style.paddingTop = `${v.featuresPt}px`;
features.style.paddingBottom = `${v.featuresPb}px`;
}
const communityUl = el("community-ul");
if (communityUl) {
communityUl.style.display = "flex";
communityUl.style.flexDirection = "column";
communityUl.style.gap = `${v.communityGap}px`;
}
const faqTopSpacer = el("faq-top-spacer");
if (faqTopSpacer) faqTopSpacer.style.height = `${v.faqPt}px`;
const docsContent = el("docs-content");
if (docsContent) docsContent.style.paddingTop = `${v.docsPt}px`;
@ -156,7 +175,16 @@ export function DevPanel() {
<Section label="Features">
<Row label="line-h" value={vals.featuresLh} onChange={(v) => update({ featuresLh: v })} min={1} max={2.5} step={0.025} unit="" w={16} />
<Row label="mb" value={vals.featuresMb} onChange={(v) => update({ featuresMb: v })} />
<Row label="pt" value={vals.featuresPt} onChange={(v) => update({ featuresPt: v })} />
<Row label="pb" value={vals.featuresPb} onChange={(v) => update({ featuresPb: v })} />
</Section>
<Section label="Community">
<Row label="gap" value={vals.communityGap} onChange={(v) => update({ communityGap: v })} />
</Section>
<Section label="FAQ">
<Row label="pt" value={vals.faqPt} onChange={(v) => update({ faqPt: v })} />
</Section>
<Section label="Docs">
@ -173,7 +201,10 @@ export function DevPanel() {
`download-above: ${vals.downloadAbove}px`,
`download-below: ${vals.downloadBelow}px`,
`features-lh: ${vals.featuresLh}`,
`features-mb: ${vals.featuresMb}px`,
`features-pt: ${vals.featuresPt}px`,
`features-pb: ${vals.featuresPb}px`,
`community-gap: ${vals.communityGap}px`,
`faq-pt: ${vals.faqPt}px`,
`docs-pt: ${vals.docsPt}px`,
].join(", ");
navigator.clipboard.writeText(text);