diff --git a/.gitignore b/.gitignore index ce437e4..27d7fe5 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,6 @@ test-results/ # Private strategy / internal notes (never publish) STRATEGY.md docs/internal/ + +# Private working notes +TODO.md diff --git a/TODO.md b/TODO.md deleted file mode 100644 index b7b09ea..0000000 --- a/TODO.md +++ /dev/null @@ -1,111 +0,0 @@ -# Such Software - TODO - -## 🔥 Priority: Website Updates (March 2026) - -- [ ] **Publish Bauhaus Echo Launch blog post** (currently draft) -- [ ] **Update Bauhaus Echo product page** — latest screenshots, itch.io link, embedded trailer -- [ ] **Write dev journey / post-mortem blog post** for Bauhaus Echo -- [ ] **Verify all store links** — App Store, Google Play, itch.io, web demo -- [ ] **Add itch.io link** to Bauhaus Echo product page and footer where relevant - -## Nice to Have - -- [ ] **Rate limiting** - Turnstile handles bots; add rate limiting only if abuse observed -- [ ] Manual screen reader testing (NVDA, VoiceOver) -- [ ] Further canvas performance optimization -- [ ] **Blog migration** - Move to MDX/Contentlayer when post count grows - -## Future Projects - -- [ ] Decision making app (mobile app with web demo) - ---- - -## Architecture Notes (Feb 2026) - -### Blog Options - -| Option | Pros | Cons | Best For | -|--------|------|------|----------| -| **MDX in repo** | Simple, version controlled, no deps | Dev-only editing, rebuild to publish | Tech blog, infrequent posts | -| **Contentlayer** | Type-safe MDX, great DX with Next.js | Learning curve, config overhead | Structured content, many posts | -| **Headless CMS** (Sanity/Payload) | Non-dev editing, media management | External dependency, cost at scale | Team editing, media-heavy | - -Recommendation: Start with MDX in `apps/web/src/content/blog/`, add Contentlayer if it grows. - -### New App Architecture - -**Option A: Monorepo (web demos)** -``` -apps/ - web/ # such.software - puzzle-demo/ # Vite or Next.js - decision-demo/ # Vite or Next.js -packages/ - ui/ # Shared (already exists) -``` -- ✅ Share `@repo/ui`, unified CI/CD, easy cross-linking -- ❌ Coupled deploys, heavier repo - -**Option B: Separate repos + subdomains** -- `puzzle.such.software` → own repo -- `decide.such.software` → own repo -- ✅ Independent deploys, clean separation -- ❌ No shared packages, more repos to manage - -**Option C: Hybrid (recommended)** -- Web demos in this monorepo (lightweight, share UI) -- Mobile apps in separate repos (React Native/Expo needs own tooling) -- Link from such.software portfolio to demos - -### Mobile Considerations -- React Native/Expo likely needs separate repo due to tooling differences -- Web demos can use same game logic via shared `packages/` if extracted -- Consider Expo Web for code sharing between mobile and web demo - -## Completed - -### Products & Blog (February 2026) -- [x] **Products section** - Landing page + 4 product pages (Webshops, Custom Websites, Smirk Wallet, Bauhaus Echo) -- [x] **Bauhaus Echo** - Full product page with game modes, features, app store links, privacy policy -- [x] **Smirk Wallet** - Full product page with features, supported currencies, community links -- [x] **Blog infrastructure** - Blog listing with draft system, individual post pages -- [x] **Blog posts** - Website Relaunch (published), Smirk Wallet v0.1.6 (published), Bauhaus Echo Launch (draft) -- [x] **Mobile bottom navigation** - Fixed nav bar for mobile with 5 items (Home, Products, Services, Blog, About) -- [x] **Header updates** - Desktop nav now includes Products and Blog links -- [x] **Portfolio bento grid** - Added Smirk Wallet card (1x2 tall) -- [x] **Footer/About** - Replaced Reddit with Discord, added jwinterm.com link - -### Lighthouse Scores (January 2026) - -| Page | Performance | Accessibility | SEO | Best Practices | -|------|-------------|---------------|-----|----------------| -| Home | 99% | 100% | 100% | 77%* | -| Services | 98% | 100% | 100% | 100% | -| About | 99% | 100% | 100% | 100% | - -*Home 77% Best Practices due to Cloudflare Turnstile third-party cookies. - -### Accessibility & Compliance -- [x] WCAG 2.2 AA compliance (100% Lighthouse) -- [x] Section 508 & ADA compliance -- [x] Semantic HTML5 architecture -- [x] Playwright a11y automation (42 tests, chromium/firefox/webkit) -- [x] Color contrast fixes (emerald-600 → emerald-700) -- [x] Heading hierarchy (h1 → h2 → h3 → h4) -- [x] `prefers-reduced-motion` support in NebulaField -- [x] Skip-to-main link, ARIA labels, form accessibility - -### SEO -- [x] Meta descriptions and OpenGraph on all pages -- [x] Structured data (JSON-LD Organization schema) -- [x] Canonical URLs on all pages - -### Performance -- [x] Lazy loaded NebulaField with `next/dynamic` + `requestIdleCallback` -- [x] Removed debug console.log statements - -### Infrastructure -- [x] Cloudflare Turnstile bot protection -- [x] `.env.example` template -- [x] `pnpm start` script diff --git a/apps/web/src/app/apps/page.tsx b/apps/web/src/app/apps/page.tsx index 80b1f05..db26541 100644 --- a/apps/web/src/app/apps/page.tsx +++ b/apps/web/src/app/apps/page.tsx @@ -7,11 +7,11 @@ import Link from "next/link"; import type { Metadata } from "next"; export const metadata: Metadata = { - title: "Our Apps: Games & Tools for iOS, Android & Web | Such Software", + title: "Apps: Games & Tools for iOS, Android & Web | Such Software", description: "Download Such Software's apps and games: Bauhaus Echo, Suchoice, Vegan IQ, Such Moon Launch, and more. Free on the App Store, Google Play, and the web.", alternates: { canonical: "/apps" }, openGraph: { - title: "Our Apps: Games & Tools for iOS, Android & Web | Such Software", + title: "Apps: Games & Tools for iOS, Android & Web | Such Software", description: "Download Such Software's apps and games: Bauhaus Echo, Suchoice, Vegan IQ, Such Moon Launch, and more. Free on the App Store, Google Play, and the web.", type: "website", images: [{ url: "/images/branding/OG_banner_v2_light.png", width: 1200, height: 630, alt: "Such Software" }], diff --git a/apps/web/src/app/products/barns-and-neutrons/page.tsx b/apps/web/src/app/products/barns-and-neutrons/page.tsx index eb35a82..f6dcdea 100644 --- a/apps/web/src/app/products/barns-and-neutrons/page.tsx +++ b/apps/web/src/app/products/barns-and-neutrons/page.tsx @@ -7,7 +7,7 @@ import { JsonLd, breadcrumbLd, faqLd } from "@/components/seo/json-ld"; import type { Metadata } from "next"; export const metadata: Metadata = { - title: "Barns & Neutrons: A Game About the Table of Nuclides | Such Software", + title: "Barns & Neutrons: Table of Nuclides Game | Such Software", description: "Barns & Neutrons is a cozy exploration-puzzle game across the real Table of Nuclides. Capture neutrons, coax decays, and learn honest, cited nuclear physics. In development.", alternates: { canonical: "/products/barns-and-neutrons" }, keywords: [ diff --git a/apps/web/src/app/products/neroswap/page.tsx b/apps/web/src/app/products/neroswap/page.tsx index 97275e6..95450a1 100644 --- a/apps/web/src/app/products/neroswap/page.tsx +++ b/apps/web/src/app/products/neroswap/page.tsx @@ -7,7 +7,7 @@ import { JsonLd, breadcrumbLd, softwareAppLd, faqLd } from "@/components/seo/jso import type { Metadata } from "next"; export const metadata: Metadata = { - title: "Neroswap: No-KYC Monero & Bitcoin Price Aggregator | Such Software", + title: "Neroswap: No-KYC Crypto Price Aggregator | Such Software", description: "Compare live Monero, Wownero, and Bitcoin prices across 6 DEX and no-KYC CEX orderbooks in real time. No accounts, no custody, no tracking.", alternates: { canonical: "/products/neroswap" }, diff --git a/apps/web/src/app/products/page.tsx b/apps/web/src/app/products/page.tsx index 355e9e7..5198c8b 100644 --- a/apps/web/src/app/products/page.tsx +++ b/apps/web/src/app/products/page.tsx @@ -4,11 +4,11 @@ import { ProductsGrid, type Product } from "@/components/portfolio/products-grid import type { Metadata } from "next"; export const metadata: Metadata = { - title: "Our Products & Apps: Crypto Tools, Nuclear Games & Commerce | Such Software", + title: "Products: Crypto Tools, Games & Commerce | Such Software", description: "Explore Such Software's products: Wownerogue Monero roguelike, Neroswap crypto aggregator, Smirk wallet, headless Webshops, our mobile games, and nuclear games in development.", alternates: { canonical: "/products" }, openGraph: { - title: "Our Products & Apps: Crypto Tools, Nuclear Games & Commerce | Such Software", + title: "Products: Crypto Tools, Games & Commerce | Such Software", description: "Explore Such Software's products: Wownerogue Monero roguelike, Neroswap crypto aggregator, Smirk wallet, headless Webshops, our mobile games, and nuclear games in development.", type: "website", }, diff --git a/apps/web/src/app/products/smirk-wallet/page.tsx b/apps/web/src/app/products/smirk-wallet/page.tsx index 8a663ad..78bdfc6 100644 --- a/apps/web/src/app/products/smirk-wallet/page.tsx +++ b/apps/web/src/app/products/smirk-wallet/page.tsx @@ -7,7 +7,7 @@ import { JsonLd, breadcrumbLd, softwareAppLd } from "@/components/seo/json-ld"; import type { Metadata } from "next"; export const metadata: Metadata = { - title: "Smirk Wallet: Non-Custodial Crypto Tipping by Username | Such Software", + title: "Smirk Wallet: Non-Custodial Crypto Tipping | Such Software", description: "Tip BTC, LTC, XMR, WOW, and GRIN on Telegram or Discord by username. A non-custodial browser wallet: your keys never leave your device.", alternates: { canonical: "/products/smirk-wallet" }, openGraph: { diff --git a/apps/web/src/app/products/suchoice/page.tsx b/apps/web/src/app/products/suchoice/page.tsx index 617b419..03511f7 100644 --- a/apps/web/src/app/products/suchoice/page.tsx +++ b/apps/web/src/app/products/suchoice/page.tsx @@ -8,11 +8,11 @@ import Link from "next/link"; import type { Metadata } from "next"; export const metadata: Metadata = { - title: "Suchoice: Spin the Wheel & AI Decision Maker App | Such Software", + title: "Suchoice: AI Decision Maker & Spin Wheel | Such Software", description: "Can't decide? Snap a photo and let AI read your options, spin the wheel, flip a coin, or roll 3D dice. The fun decision-maker app for iOS and Android.", alternates: { canonical: "/products/suchoice" }, openGraph: { - title: "Suchoice: Spin the Wheel & AI Decision Maker App | Such Software", + title: "Suchoice: AI Decision Maker & Spin Wheel | Such Software", description: "Can't decide? Snap a photo and let AI read your options, spin the wheel, flip a coin, or roll 3D dice. The fun decision-maker app for iOS and Android.", type: "website", images: ["/images/og/suchoice.png"], diff --git a/apps/web/src/app/products/webshops/page.tsx b/apps/web/src/app/products/webshops/page.tsx index 6a4a4cd..b58929f 100644 --- a/apps/web/src/app/products/webshops/page.tsx +++ b/apps/web/src/app/products/webshops/page.tsx @@ -7,11 +7,11 @@ import Link from "next/link"; import type { Metadata } from "next"; export const metadata: Metadata = { - title: "Custom Online Stores & E-Commerce Development | Such Software", + title: "Custom Online Stores & E-Commerce | Such Software", description: "Custom online stores with no upfront cost and revenue-share pricing. Own your data, escape template limits, and hit 100/100 Lighthouse. Built on Medusa.", alternates: { canonical: "/products/webshops" }, openGraph: { - title: "Custom Online Stores & E-Commerce Development | Such Software", + title: "Custom Online Stores & E-Commerce | Such Software", description: "Custom online stores with no upfront cost and revenue-share pricing. Own your data and escape template limits. Built on Medusa.", type: "website", images: ["/images/og/webshops.png"], diff --git a/apps/web/src/app/products/wownerogue/page.tsx b/apps/web/src/app/products/wownerogue/page.tsx index a33466f..54db809 100644 --- a/apps/web/src/app/products/wownerogue/page.tsx +++ b/apps/web/src/app/products/wownerogue/page.tsx @@ -7,7 +7,7 @@ import { JsonLd, breadcrumbLd, faqLd } from "@/components/seo/json-ld"; import type { Metadata } from "next"; export const metadata: Metadata = { - title: "Wownerogue: Provably-Fair Monero Multiplayer Roguelike | Such Software", + title: "Wownerogue: Provably-Fair Monero Roguelike | Such Software", description: "Play Wownerogue: a provably-fair, blockchain-synced multiplayer roguelike. Every run is verifiable, every round ends on a new block. Free in-browser, no download.", alternates: { canonical: "/products/wownerogue" }, keywords: [