diff --git a/apps/web/public/images/bauhaus-echo.png b/apps/web/public/images/bauhaus-echo.png
new file mode 100644
index 0000000..81d9f77
Binary files /dev/null and b/apps/web/public/images/bauhaus-echo.png differ
diff --git a/apps/web/public/images/smirk-logo.svg b/apps/web/public/images/smirk-logo.svg
new file mode 100644
index 0000000..cbcf8fc
--- /dev/null
+++ b/apps/web/public/images/smirk-logo.svg
@@ -0,0 +1,60 @@
+
+
+
+
diff --git a/apps/web/public/images/smirk-wallet.png b/apps/web/public/images/smirk-wallet.png
index b97d645..6f78126 100644
Binary files a/apps/web/public/images/smirk-wallet.png and b/apps/web/public/images/smirk-wallet.png differ
diff --git a/apps/web/src/app/about/page.tsx b/apps/web/src/app/about/page.tsx
index 2fcfb2e..c18ecc4 100644
--- a/apps/web/src/app/about/page.tsx
+++ b/apps/web/src/app/about/page.tsx
@@ -1,5 +1,6 @@
import { FounderSignature } from "@/components/about/founder-signature";
import { Header } from "@/components/layout/header";
+import { MobileNav } from "@/components/layout/mobile-nav";
import { FaMapMarkerAlt, FaPhone, FaBuilding, FaExternalLinkAlt } from "react-icons/fa";
import { FaXTwitter, FaTelegram, FaDiscord } from "react-icons/fa6";
import type { Metadata } from "next";
@@ -22,7 +23,7 @@ export default function AboutPage() {
-
+
About Us
@@ -95,6 +96,7 @@ export default function AboutPage() {
+
);
}
diff --git a/apps/web/src/app/blog/bauhaus-echo-launch/page.tsx b/apps/web/src/app/blog/bauhaus-echo-launch/page.tsx
new file mode 100644
index 0000000..47beb38
--- /dev/null
+++ b/apps/web/src/app/blog/bauhaus-echo-launch/page.tsx
@@ -0,0 +1,71 @@
+import { Header } from "@/components/layout/header";
+import { MobileNav } from "@/components/layout/mobile-nav";
+import Link from "next/link";
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Bauhaus Echo is Live | Such Software Blog",
+ description: "Our first mobile game is available on Android and iOS. A visual memory puzzle inspired by Bauhaus design.",
+ alternates: { canonical: "/blog/bauhaus-echo-launch" },
+};
+
+export default function BauhausEchoLaunchPost() {
+ return (
+
+
+
+
+ ← Back to Blog
+
+
+
+
+
Bauhaus Echo is Live
+
+
+
+
+ Bauhaus Echo is now available on Google Play and the App Store. It is a visual memory game
+ where you memorize tile arrangements, watch them shuffle, and reconstruct the original pattern.
+
+
+
The Concept
+
+ The game shows you a grid of colorful geometric tiles inspired by Bauhaus design. You get a
+ few seconds to memorize their positions. Then the tiles spin, shrink, and scatter to the
+ bottom of the screen. Your job is to drag them back to where they belong.
+
+
+
Four Game Modes
+
+
Classic - The core experience. Memorize and reconstruct.
+
Speed - Tiles appear one at a time. Place each before the next drops.
+
Endless - Speed mode that loops forever. See how long you last.
+
Memory - Traditional card-matching pairs.
+
+
+
Tech Stack
+
+ Built with libGDX, a cross-platform Java game framework. The same codebase runs on Android,
+ iOS (via RoboVM), desktop, and web (via GWT). The tile assets are packed into a TextureAtlas
+ for efficient rendering.
+
+
+
+
+ );
+}
diff --git a/apps/web/src/app/blog/page.tsx b/apps/web/src/app/blog/page.tsx
new file mode 100644
index 0000000..242155a
--- /dev/null
+++ b/apps/web/src/app/blog/page.tsx
@@ -0,0 +1,69 @@
+import { Header } from "@/components/layout/header";
+import { MobileNav } from "@/components/layout/mobile-nav";
+import { Card } from "@repo/ui/components/card";
+import Link from "next/link";
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Blog | Such Software",
+ description: "News, updates, and technical articles from Such Software.",
+ alternates: { canonical: "/blog" },
+};
+
+// For now, hardcoded posts. Can migrate to MDX/CMS later.
+const posts = [
+ {
+ slug: "smirk-wallet-release",
+ title: "Smirk Wallet v0.1.6",
+ date: "2026-02-06",
+ excerpt: "Non-custodial browser extension for social tipping with BTC, LTC, XMR, WOW, and GRIN. Now on GitHub, Chrome Web Store pending.",
+ draft: false,
+ },
+ {
+ slug: "website-relaunch-2026",
+ title: "Website Relaunch",
+ date: "2026-02-06",
+ excerpt: "We rebuilt such.software from the ground up. Here is what we used and why.",
+ draft: false,
+ },
+ {
+ slug: "bauhaus-echo-launch",
+ title: "Bauhaus Echo is Live",
+ date: "2026-02-06",
+ excerpt: "Our first mobile game is available on Android and iOS. A visual memory puzzle inspired by Bauhaus design.",
+ draft: true,
+ },
+];
+
+const publishedPosts = posts.filter((p) => !p.draft);
+
+export default function BlogPage() {
+ return (
+
+
+
+
Blog
+
+ News, launches, and technical notes.
+
+
+ {publishedPosts.length === 0 ? (
+
No posts yet. Check back soon.
+ ) : (
+
+ {publishedPosts.map((post) => (
+
+
+
+
{post.title}
+
{post.excerpt}
+
+
+ ))}
+
+ )}
+
+
+
+ );
+}
diff --git a/apps/web/src/app/blog/smirk-wallet-release/page.tsx b/apps/web/src/app/blog/smirk-wallet-release/page.tsx
new file mode 100644
index 0000000..2e17c1e
--- /dev/null
+++ b/apps/web/src/app/blog/smirk-wallet-release/page.tsx
@@ -0,0 +1,114 @@
+import { Header } from "@/components/layout/header";
+import { MobileNav } from "@/components/layout/mobile-nav";
+import Link from "next/link";
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Smirk Wallet v0.1.6 | Such Software Blog",
+ description: "Announcing Smirk Wallet, a non-custodial browser extension for social tipping with BTC, LTC, XMR, WOW, and GRIN.",
+ alternates: { canonical: "/blog/smirk-wallet-release" },
+};
+
+export default function SmirkWalletReleasePost() {
+ return (
+
+
+
+
+ ← Back to Blog
+
+
+
+
+
Smirk Wallet v0.1.6
+
+
+
+
+ Smirk Wallet is a non-custodial browser extension that lets you tip people cryptocurrency
+ by their Telegram or Discord username. We have shipped six releases and the extension is
+ available now on GitHub.
+
+
+
What It Does
+
+ One 12-word seed phrase gives you addresses for five currencies: Bitcoin, Litecoin, Monero,
+ Wownero, and Grin. Link your Telegram or Discord account on smirk.cash, and anyone running
+ Smirk can send you crypto by username.
+
+
+ Tips are encrypted with the recipient's public key. Only they can claim. If a tip goes
+ unclaimed, the sender can claw it back. No funds get lost.
+
+
+
Non-Custodial by Design
+
+ Your private spend keys are generated locally and never leave your browser. They are
+ encrypted with your password. We store only public keys and view keys (for Monero/Wownero
+ balance scanning). We cannot move your funds.
+
+
+
What We Built
+
+
Browser extension (TypeScript, Preact, Vite)
+
Backend API (Rust, Axum, PostgreSQL)
+
Light wallet servers for XMR and WOW
+
Grin wallet with client-side WASM
+
Telegram and Discord bots for tip notifications
+
User dashboard at smirk.cash
+
+
+
Chrome Web Store Status
+
+ Our initial submission was rejected for requesting an unused permission (activeTab).
+ We had included it for a planned feature that was not yet implemented. The fix is already
+ in v0.1.6. We have removed the permission and resubmitted.
+
+
+ In the meantime, you can install manually from{" "}
+
+ GitHub Releases
+
+ . Firefox support is also available.
+
+
+
Open Source
+
+ Everything is open source. The extension, backend, and WASM libraries are all on GitHub:
+
+
+
+
+ );
+}
diff --git a/apps/web/src/app/blog/website-relaunch-2026/page.tsx b/apps/web/src/app/blog/website-relaunch-2026/page.tsx
new file mode 100644
index 0000000..d0634d9
--- /dev/null
+++ b/apps/web/src/app/blog/website-relaunch-2026/page.tsx
@@ -0,0 +1,76 @@
+import { Header } from "@/components/layout/header";
+import { MobileNav } from "@/components/layout/mobile-nav";
+import Link from "next/link";
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Website Relaunch | Such Software Blog",
+ description: "We rebuilt such.software from the ground up. Here is what we used and why.",
+ alternates: { canonical: "/blog/website-relaunch-2026" },
+};
+
+export default function WebsiteRelaunchPost() {
+ return (
+
+
+
+
+ ← Back to Blog
+
+
+
+
+
Website Relaunch
+
+
+
+
+ We rebuilt such.software. New design, new infrastructure, same focus on performance and accessibility.
+
+
+
Stack
+
+
Framework: Next.js 15 (App Router)
+
Language: TypeScript
+
Styling: Tailwind CSS with CSS variables for theming
+
Animation: Framer Motion
+
Monorepo: Turborepo + pnpm workspaces
+
Testing: Playwright with axe-core for accessibility
+
Bot Protection: Cloudflare Turnstile
+
Email: Resend
+
+
+
Procedural Graphics
+
+ The homepage features two custom procedural animations: NebulaField and DataGrid. Both are
+ SVG-based, theme-aware, and respect prefers-reduced-motion. NebulaField renders animated
+ data streams flowing toward a central icon using quadratic Bezier curves. DataGrid draws
+ a pulsing grid with traveling data packets.
+
+
+
Accessibility
+
+ We run 42 automated accessibility tests across Chromium, Firefox, and WebKit on every build.
+ Tests cover WCAG 2.2 AA compliance, heading hierarchy, color contrast, keyboard navigation,
+ and form accessibility. Lighthouse scores are 99-100 across all pages.
+
+
+
Performance
+
+ The NebulaField component is lazy loaded with next/dynamic and requestIdleCallback. Canvas
+ rendering is throttled. Fonts are loaded via next/font for zero layout shift. Images use
+ next/image for automatic optimization.
+
+
+
Structure
+
+ The site now has Products, Services, Blog, and About sections. Products showcases our
+ standalone offerings: Webshops, Custom Websites, Smirk Wallet, and Bauhaus Echo. Services
+ covers our partnership model and consulting work. Mobile users get a bottom navigation bar.
+
+
+
+
+
+ );
+}
diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx
index c9b9d2a..ee3be83 100644
--- a/apps/web/src/app/page.tsx
+++ b/apps/web/src/app/page.tsx
@@ -5,6 +5,7 @@ import { ContactForm } from "@/components/contact/contact-form";
import { FounderSignature } from "@/components/about/founder-signature";
import { ServicesPreview } from "@/components/landing/services-preview";
import { Header } from "@/components/layout/header";
+import { MobileNav } from "@/components/layout/mobile-nav";
import { DynamicBackground } from "@/components/landing/dynamic-background";
import Link from "next/link";
import { Button } from "@repo/ui/components/button";
@@ -103,7 +104,7 @@ export default function Home() {
-
+
Start a Project
@@ -114,6 +115,7 @@ export default function Home() {
+
);
}
\ No newline at end of file
diff --git a/apps/web/src/app/products/bauhaus-echo/page.tsx b/apps/web/src/app/products/bauhaus-echo/page.tsx
new file mode 100644
index 0000000..199f421
--- /dev/null
+++ b/apps/web/src/app/products/bauhaus-echo/page.tsx
@@ -0,0 +1,97 @@
+import { Header } from "@/components/layout/header";
+import { MobileNav } from "@/components/layout/mobile-nav";
+import { Card } from "@repo/ui/components/card";
+import { Button } from "@repo/ui/components/button";
+import Link from "next/link";
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Bauhaus Echo | Such Software",
+ description: "Visual memory puzzle game inspired by Bauhaus design. Memorize, shuffle, reconstruct. Android, iOS, Web, Desktop.",
+ alternates: { canonical: "/products/bauhaus-echo" },
+};
+
+const gameModes = [
+ { name: "Classic", description: "Memorize tile positions, reconstruct after shuffle" },
+ { name: "Speed", description: "Tiles drop one at a time, place each before the next appears" },
+ { name: "Endless", description: "Speed mode with tile cycling, play forever" },
+ { name: "Memory", description: "Traditional card-matching pairs game" },
+];
+
+export default function BauhausEchoPage() {
+ return (
+
+
+
+
+ ← Back to Products
+
+
+
+ Bauhaus Echo
+
+
+
+
+ A visual memory puzzle game inspired by Bauhaus design aesthetics.
+ Memorize arrangements of geometric tiles, watch them shuffle, then reconstruct the pattern.
+
+
+
+ );
+}
diff --git a/apps/web/src/app/products/bauhaus-echo/privacy/page.tsx b/apps/web/src/app/products/bauhaus-echo/privacy/page.tsx
new file mode 100644
index 0000000..ab83af7
--- /dev/null
+++ b/apps/web/src/app/products/bauhaus-echo/privacy/page.tsx
@@ -0,0 +1,147 @@
+import { Header } from "@/components/layout/header";
+import { MobileNav } from "@/components/layout/mobile-nav";
+import Link from "next/link";
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Privacy Policy | Bauhaus Echo | Such Software",
+ description: "Privacy policy for Bauhaus Echo mobile game.",
+ alternates: { canonical: "/products/bauhaus-echo/privacy" },
+};
+
+export default function BauhausEchoPrivacyPage() {
+ return (
+
+
+
+
+ ← Back to Bauhaus Echo
+
+
+
Privacy Policy for Bauhaus Echo
+
Last Updated: January 31, 2026
+
+
+
+ Such Software LLC ("we," "us," or "our") operates the Bauhaus Echo mobile
+ application (the "App"). This page informs you of our policies regarding the collection,
+ use, and disclosure of personal data when you use our App.
+
+
+
Information We Collect
+
+
Advertising Data
+
+ We use Google AdMob to display advertisements. AdMob may collect and use
+ data to show you personalized ads. This data may include:
+
+ iOS Users: We will ask for your permission via App Tracking Transparency (ATT)
+ before collecting data for personalized advertising. You can deny this request and still use
+ the app with non-personalized ads.
+
+
+
In-App Purchases
+
+ If you purchase the "Remove Ads" upgrade, your transaction is processed by Google Play (Android)
+ or the Apple App Store (iOS). We do not have access to your payment information. We only receive
+ confirmation of your purchase status.
+
+
+
High Scores & Leaderboards
+
If you submit scores to our online leaderboards, we collect:
+
+
Your chosen display name (anonymous by default)
+
Your game scores and statistics
+
A randomly generated anonymous player ID
+
+
+ We do not require or collect your real name, email, or any other personal
+ information to use leaderboards.
+
+
+
Locally Stored Data
+
The App stores the following data locally on your device:
+
+
Game progress and high scores
+
Settings preferences (sound, music, grid size)
+
Premium purchase status
+
+
This data is not transmitted to our servers unless you use the online leaderboard feature.
+
+
How We Use Your Information
+
We use collected data to:
+
+
Display advertisements (unless you purchase "Remove Ads")
+
Process in-app purchases
+
Maintain online leaderboards
+
Improve the App experience
+
+
+
Third-Party Services
+
The App uses the following third-party services that may collect information:
+
+
Google AdMob — Advertising
+
Google Play Services — Android platform and billing
+
Apple StoreKit — iOS platform and billing
+
+
+
Children's Privacy
+
+ The App is intended for general audiences and does not knowingly collect personal information
+ from children under 13. If you believe we have collected data from a child under 13, please
+ contact us immediately.
+
+
+
Data Retention
+
+
Advertising data is managed by Google per their retention policies
+
Leaderboard data is retained indefinitely but can be deleted upon request
+
Local data is stored on your device until you uninstall the App
+
+
+
Your Rights
+
You may:
+
+
+ Opt out of personalized ads via your device settings (Android: Settings → Google → Ads;
+ iOS: Settings → Privacy → Tracking)
+
+
Request deletion of your leaderboard data by contacting us
+
Remove local data by uninstalling the App
+
+
+
Changes to This Policy
+
+ We may update this Privacy Policy from time to time. We will notify you of any changes by
+ posting the new Privacy Policy on this page and updating the "Last Updated" date.
+
+
+
Contact Us
+
If you have any questions about this Privacy Policy, please contact us:
+ Your private keys are generated locally and encrypted with your password.
+ We never see your spend keys. Your funds are always yours.
+
+
+
+
Social Tipping
+
+ Link your Telegram or Discord account. Anyone with Smirk can send you
+ crypto by username. No wallet address needed.
+
+
+
+
Encrypted Tips
+
+ Tips are encrypted with the recipient's public key. Only they can claim.
+ Senders can reclaim unclaimed tips (no lost funds).
+
+
+
+
One Seed, Five Chains
+
+ A single 12-word seed phrase derives addresses for all supported currencies.
+ Restore your entire wallet with one backup.
+
+
+
+
+
Supported Currencies
+
+
+
+
+
Currency
+
Symbol
+
Key Type
+
+
+
+ {currencies.map((c) => (
+
+
{c.name}
+
{c.symbol}
+
{c.type}
+
+ ))}
+
+
+
+
+
+
Why These Coins?
+
+ BTC is the most widely used. LTC is fast and cheap (MWEB support coming).
+ XMR is the gold standard for privacy. WOW has a great community.
+ GRIN is lightweight, private, and has the fairest emission schedule of any coin.
+
+
+
+ );
+}
diff --git a/apps/web/src/app/products/webshops/page.tsx b/apps/web/src/app/products/webshops/page.tsx
new file mode 100644
index 0000000..1cabee5
--- /dev/null
+++ b/apps/web/src/app/products/webshops/page.tsx
@@ -0,0 +1,84 @@
+import { Header } from "@/components/layout/header";
+import { MobileNav } from "@/components/layout/mobile-nav";
+import { Card } from "@repo/ui/components/card";
+import { Button } from "@repo/ui/components/button";
+import Link from "next/link";
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Webshops | Such Software",
+ description: "Headless Medusa commerce engines with revenue-share pricing. No upfront costs, aligned incentives.",
+ alternates: { canonical: "/products/webshops" },
+};
+
+export default function WebshopsPage() {
+ return (
+
+
+
+
+ ← Back to Products
+
+
+
+ Webshops
+
+
+
+
+ We build headless commerce platforms on Medusa v2 with a revenue-share model.
+ No massive setup fees, no monthly retainers. We only win when you make sales.
+
+
+
+
+
+
Zero Upfront Cost
+
+ We invest our development time and infrastructure. You focus on your brand and products.
+ We take a small percentage of sales once you are live.
+
+
+
+
Own Your Data
+
+ Unlike Shopify, you own your customer data, product catalog, and order history.
+ No platform lock-in, ever.
+
+
+
+
Flexible Architecture
+
+ Subscriptions, bundles, B2B pricing, multi-warehouse inventory.
+ Model your exact business logic without platform constraints.
+
+
+
+
Performance First
+
+ Next.js storefronts optimized for Core Web Vitals. 100/100 Lighthouse scores,
+ fast load times, high conversion rates.
+
+
+
+
+
+
Tech Stack
+
+
Backend: Medusa v2 (Node.js, PostgreSQL)
+
Frontend: Next.js 15, React 18, Tailwind CSS
+
Payments: Stripe, PayPal, crypto (optional)
+
Hosting: Vercel, Railway, or your infrastructure
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/web/src/app/services/page.tsx b/apps/web/src/app/services/page.tsx
index 3c47432..7d5e522 100644
--- a/apps/web/src/app/services/page.tsx
+++ b/apps/web/src/app/services/page.tsx
@@ -1,6 +1,7 @@
import { DataGrid } from "@repo/ui/procedural/data-grid";
import { Button } from "@repo/ui/components/button";
import { Header } from "@/components/layout/header";
+import { MobileNav } from "@/components/layout/mobile-nav";
import Link from "next/link";
import { Card } from "@repo/ui/components/card";
import type { Metadata } from "next";
@@ -150,7 +151,7 @@ export default function ServicesPage() {
-
+
);
}
\ No newline at end of file
diff --git a/apps/web/src/components/layout/header.tsx b/apps/web/src/components/layout/header.tsx
index 47c9f4f..523d6df 100644
--- a/apps/web/src/components/layout/header.tsx
+++ b/apps/web/src/components/layout/header.tsx
@@ -20,12 +20,24 @@ export function Header() {