v1.1
Polish pass on the public surface — accessibility, share-card metadata, source-map blocking, a Service Worker for /app/, and a wave of UX touch-ups caught by a continuous test/deploy loop across both Chromium and WebKit.
Accessibility
- aria-current="page" on the active nav link in the desktop header and the mobile drawer; brand-tinted active state so the route shows visually too.
- Mobile drawer dismisses on outside tap, Escape key, and route change. Drawer becomes inert + aria-hidden when closed so screen readers stop announcing the clipped links.
- Every tap target meets the 44×44 px minimum across header, footer, drawer, and download CTAs (WCAG 2.5.5).
- Skip-to-main-content link is the first Tab focus and visible when focused; tab order across 25 focusables has zero zig-zag.
- Inline SVG icons inside labelled controls now carry aria-hidden="true" + focusable="false" so VoiceOver / NVDA stop announcing them as images.
- Unique <h1> per ranking page — /about and /help/privacy-safety stopped duplicating other pages' h1s.
- Contrast bumps where copy was on the WCAG 2.0 AA edge (hero caption 2.82:1 → 5.0:1, butter status pill 4.47:1 → 6.1:1).
Security & privacy
- HSTS bumped to include preload directive — ready for hstspreload.org submission.
- CSP gains report-to + a /api/csp-report Pages Function that accepts both Reporting-API batched and legacy single-report shapes.
- /.well-known/security.txt (RFC 9116) with Contact, Expires, Canonical, Policy, and Preferred-Languages.
- Source maps blocked at the edge via a Pages Function middleware over /app/* — composeApp.<hash>.js.map no longer leaks Kotlin sources from prior deploys.
- 0 first-party cookies set on any landing page; /app/ only sets the namespaced database_version SDK key.
Performance & PWA
- Service Worker for /app/ — cache-first for content-hashed JS + WASM, network-first for the shell HTML. Repeat visits pull 100% of hashed assets from the SW cache (verified end-to-end). Chrome's PWA install prompt now fires.
- /app/ boot under 2.5 s on a desktop edge; LCP 1.0 s on the homepage.
- viewport-fit=cover so the indigo theme-color flows under the iPhone X+ notch.
- HTTP/3 (alt-svc h3) advertised and served from Cloudflare Pages.
Search & social
- Page-specific openGraph: og:url, og:image, and twitter:title now reflect the page instead of inheriting the brand tagline on /privacy, /terms, /account/delete, and the 8 help articles.
- Meta descriptions across 5 pages tightened into the SERP-snippet 130–160 char band; broken-up <strong>escrow</strong>by Friendly typography bug fixed.
- Organization JSON-LD now lists a verified GitHub sameAs so the Knowledge Graph can match the brand entity.
- 67 internal <Link>s codemoded to prefetch={false} — static-export RSC payload 404s gone from the console.
- Cloudflare Email Routing live on friendly.mobi: hello@, support@, security@ now forward to real mailboxes. MX (route1/2/3.mx.cloudflare.net), SPF (include:_spf.mx.cloudflare.net), and DKIM (cf2024-1._domainkey) all installed. Every mailto we publish (footer, /press, /contact, /.well-known/security.txt, /help/account-security/ phishing-recovery guide) actually reaches a human now.
Web app
- /app/?showcase=1&screen=<route> deep-link into any showcase screen (Tasks, Wallet, Events, Profile, …) so the design preview is shareable.
- Showcase data refreshed: India-rooted roster across Bengaluru / Pune / Mumbai / Hyderabad / Delhi with diverse roles; evergreen relative timestamps (today / 1d ago / last Wed) on bounties + wallet; Friendly Meet replaces competitor names in the events list.
- Contact form POSTs to /api/contact first, with the mailto link kept as an explicit fallback. Newsletter form respects busy-state — 5 rapid clicks fire exactly one POST.
In progress
- · LinkedIn company page verification → add to sameAs once the slug is live.