mirror of
https://github.com/Such-Software/such.software.git
synced 2026-10-17 05:32:05 +02:00
Trim SEO titles to <=60 chars; stop tracking TODO.md
- Shorter, non-truncating <title>/OG titles for products, apps, wownerogue, smirk, neroswap, suchoice, barns-and-neutrons, webshops. - TODO.md removed from the repo and gitignored (internal working notes).
This commit is contained in:
@@ -60,3 +60,6 @@ test-results/
|
|||||||
# Private strategy / internal notes (never publish)
|
# Private strategy / internal notes (never publish)
|
||||||
STRATEGY.md
|
STRATEGY.md
|
||||||
docs/internal/
|
docs/internal/
|
||||||
|
|
||||||
|
# Private working notes
|
||||||
|
TODO.md
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -7,11 +7,11 @@ import Link from "next/link";
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
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.",
|
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" },
|
alternates: { canonical: "/apps" },
|
||||||
openGraph: {
|
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.",
|
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",
|
type: "website",
|
||||||
images: [{ url: "/images/branding/OG_banner_v2_light.png", width: 1200, height: 630, alt: "Such Software" }],
|
images: [{ url: "/images/branding/OG_banner_v2_light.png", width: 1200, height: 630, alt: "Such Software" }],
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { JsonLd, breadcrumbLd, faqLd } from "@/components/seo/json-ld";
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
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.",
|
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" },
|
alternates: { canonical: "/products/barns-and-neutrons" },
|
||||||
keywords: [
|
keywords: [
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { JsonLd, breadcrumbLd, softwareAppLd, faqLd } from "@/components/seo/jso
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Neroswap: No-KYC Monero & Bitcoin Price Aggregator | Such Software",
|
title: "Neroswap: No-KYC Crypto Price Aggregator | Such Software",
|
||||||
description:
|
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.",
|
"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" },
|
alternates: { canonical: "/products/neroswap" },
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import { ProductsGrid, type Product } from "@/components/portfolio/products-grid
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
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.",
|
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" },
|
alternates: { canonical: "/products" },
|
||||||
openGraph: {
|
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.",
|
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",
|
type: "website",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { JsonLd, breadcrumbLd, softwareAppLd } from "@/components/seo/json-ld";
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
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.",
|
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" },
|
alternates: { canonical: "/products/smirk-wallet" },
|
||||||
openGraph: {
|
openGraph: {
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import Link from "next/link";
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
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.",
|
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" },
|
alternates: { canonical: "/products/suchoice" },
|
||||||
openGraph: {
|
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.",
|
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",
|
type: "website",
|
||||||
images: ["/images/og/suchoice.png"],
|
images: ["/images/og/suchoice.png"],
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ import Link from "next/link";
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
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.",
|
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" },
|
alternates: { canonical: "/products/webshops" },
|
||||||
openGraph: {
|
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.",
|
description: "Custom online stores with no upfront cost and revenue-share pricing. Own your data and escape template limits. Built on Medusa.",
|
||||||
type: "website",
|
type: "website",
|
||||||
images: ["/images/og/webshops.png"],
|
images: ["/images/og/webshops.png"],
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { JsonLd, breadcrumbLd, faqLd } from "@/components/seo/json-ld";
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
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.",
|
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" },
|
alternates: { canonical: "/products/wownerogue" },
|
||||||
keywords: [
|
keywords: [
|
||||||
|
|||||||
Reference in New Issue
Block a user