From 0848fcabdefe055d166a22cc18cd1e8c36871f6b Mon Sep 17 00:00:00 2001 From: jwinterm Date: Mon, 17 Aug 2026 04:18:18 -0400 Subject: [PATCH] feat(site): the tagline takes the title, and the em dashes go The hero h1 is now "Precision Engineering for Everyone". The concrete offer moves into the supporting line, which keeps the search terms the h1 gives up and no longer restates the splash's opening sentence. The title's gradient drifts instead of sweeping: a 300% ramp over 18s with symmetric easing, so there is no hard turnaround at either end of the travel. Em dashes are gone from every tsx/ts file (87 lines, 104 occurrences), per AGENTS.md rule 9. Label lists and titles take a colon; appositives take commas; independent clauses take a semicolon or a period. A few sentences were restructured where no single mark read well. Metadata keeps "Crypto" deliberately: it is a real service line and a real search term, and it is no longer in the visible headline. --- apps/web/src/app/about/page.tsx | 2 +- apps/web/src/app/globals.css | 11 ++++--- apps/web/src/app/page.tsx | 7 +++-- .../products/alpha-doc/opengraph-image.tsx | 2 +- apps/web/src/app/products/alpha-doc/page.tsx | 14 ++++----- .../barns-and-neutrons/opengraph-image.tsx | 2 +- .../app/products/barns-and-neutrons/page.tsx | 14 ++++----- .../src/app/products/bauhaus-echo/page.tsx | 12 ++++---- .../products/bauhaus-echo/privacy/page.tsx | 4 +-- apps/web/src/app/products/bloomword/page.tsx | 2 +- .../products/decay-theory/opengraph-image.tsx | 2 +- .../src/app/products/decay-theory/page.tsx | 14 ++++----- apps/web/src/app/products/neroswap/page.tsx | 6 ++-- apps/web/src/app/products/page.tsx | 2 +- .../such-moon-launch/leaderboard/page.tsx | 10 +++---- .../app/products/such-moon-launch/page.tsx | 30 +++++++++---------- .../such-moon-launch/privacy/page.tsx | 4 +-- apps/web/src/app/products/suchoice/page.tsx | 4 +-- apps/web/src/app/products/vegan-iq/page.tsx | 8 ++--- apps/web/src/app/services/opengraph-image.tsx | 2 +- apps/web/src/app/support/page.tsx | 2 +- apps/web/src/components/UmamiAnalytics.tsx | 2 +- .../components/landing/dynamic-background.tsx | 2 +- .../web/src/components/landing/home-shell.tsx | 2 +- .../src/components/portfolio/bento-grid.tsx | 12 ++++---- .../src/components/products/demos-gallery.tsx | 2 +- .../components/showcase/hover-vignette.tsx | 10 +++---- .../components/showcase/showcase-video.tsx | 2 +- apps/web/src/components/store-buttons.tsx | 4 +-- apps/web/src/lib/services.ts | 2 +- 30 files changed, 98 insertions(+), 94 deletions(-) diff --git a/apps/web/src/app/about/page.tsx b/apps/web/src/app/about/page.tsx index 9fd39a1..86d455d 100644 --- a/apps/web/src/app/about/page.tsx +++ b/apps/web/src/app/about/page.tsx @@ -34,7 +34,7 @@ export default function AboutPage() {

Such Software is a software studio in Kennett Square, PA, founded by John Winter Murphy, whose background is in semiconductor and nuclear engineering: a Materials Engineering PhD from UT-Dallas and six years at Lawrence Livermore National Laboratory. - We build accessible e-commerce websites, crypto and payment integrations, and original mobile apps and games. We also consult on cryptocurrency and payment software and integration — the client or a licensed third party holds funds; we never take custody — and teach nuclear, radiation, and semiconductor modeling through open-source labs, training, and talks. + We build accessible e-commerce websites, crypto and payment integrations, and original mobile apps and games. We also consult on cryptocurrency and payment software and integration; the client or a licensed third party holds funds, and we never take custody. We teach nuclear, radiation, and semiconductor modeling through open-source labs, training, and talks.

diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css index 81841b6..7e6d5cc 100644 --- a/apps/web/src/app/globals.css +++ b/apps/web/src/app/globals.css @@ -283,19 +283,22 @@ @keyframes nebula-caret { 0%, 50% { border-color: currentColor; } 50.01%, 100% { border-color: transparent; } } @keyframes nebula-term-out { to { opacity: 0; } } -/* Hero title: an animated gradient sheen. LCP-safe — the text paints immediately with the +/* Hero title: an animated gradient sheen. LCP-safe: the text paints immediately with the gradient; only the gradient POSITION animates, which never delays the largest paint. The - global reduced-motion rule freezes it to the base gradient. */ + global reduced-motion rule freezes it to the base gradient. + The wider 300% ramp over an 18s cycle makes this a slow drift rather than a visible sweep, + and the symmetric cubic-bezier easing removes the hard turnaround the old ease-in-out had + at each end of the travel. */ /* The brand's four-colour system (S green, U magenta, C blue, H teal), one per glyph. Light theme uses the light palette; .dark swaps in the dark palette, which is the same hues lifted for contrast on near-black -- from packs/such-software/pack.json. */ .hero-title { background-image: linear-gradient(110deg, #1a5c38 0%, #b83670 30%, #176a92 55%, #12857e 80%, #1a5c38 100%); - background-size: 220% auto; + background-size: 300% auto; -webkit-background-clip: text; background-clip: text; color: transparent; - animation: hero-sheen 9s ease-in-out infinite; + animation: hero-sheen 18s cubic-bezier(0.37, 0, 0.63, 1) infinite; } .dark .hero-title { background-image: linear-gradient(110deg, #35925c 0%, #e8689e 30%, #4aade0 55%, #3ad4c6 80%, #35925c 100%); diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx index 64dbe6c..8929362 100644 --- a/apps/web/src/app/page.tsx +++ b/apps/web/src/app/page.tsx @@ -28,11 +28,12 @@ export default function Home() { className="hero-title text-4xl sm:text-5xl md:text-7xl font-bold mb-6 pb-2" style={{ maxWidth: "min(calc(90vw - 120px), 100%)" }} > - Custom E-commerce, - Apps & Crypto Tools + Precision Engineering + for Everyone

- Websites, games, payments, and consulting too — plus our own mobile apps. A software studio in Kennett Square, PA. Precision engineering for everyone. + Custom e-commerce, apps, games, and crypto payment tools, built to order in + Kennett Square, PA. Plus a shelf of mobile apps and games of our own.

diff --git a/apps/web/src/app/products/alpha-doc/opengraph-image.tsx b/apps/web/src/app/products/alpha-doc/opengraph-image.tsx index 725a6c4..3a69ae0 100644 --- a/apps/web/src/app/products/alpha-doc/opengraph-image.tsx +++ b/apps/web/src/app/products/alpha-doc/opengraph-image.tsx @@ -1,6 +1,6 @@ import { gameOgImage, OG_SIZE, OG_CONTENT_TYPE } from "@/lib/og"; -export const alt = "Alpha Doc — an academic-horror roguelike"; +export const alt = "Alpha Doc: an academic-horror roguelike"; export const size = OG_SIZE; export const contentType = OG_CONTENT_TYPE; diff --git a/apps/web/src/app/products/alpha-doc/page.tsx b/apps/web/src/app/products/alpha-doc/page.tsx index 8d3092f..8ea6fdb 100644 --- a/apps/web/src/app/products/alpha-doc/page.tsx +++ b/apps/web/src/app/products/alpha-doc/page.tsx @@ -27,11 +27,11 @@ export const metadata: Metadata = { }; const faqs = [ - { q: "What is Alpha Doc?", a: "A top-down roguelike set in a physics research facility warped by a containment breach. You play a doctoral candidate who caused the disaster the same night as their thesis defense — now irradiated, you descend through five department wings to face the Committee." }, - { q: "What are the four radiation types?", a: "Alpha, Beta, Gamma, and Neutron, each a distinct playstyle. Neutron is the standout: it's not a weapon but an environmental transmutation tool — you reshape the map itself, destroying cover and creating hazards before a fight even starts." }, - { q: "Is there a morality system?", a: "Yes, but it's never an explicit choice. The aggressive play that wins fights also destroys the evidence of your culpability. Your standing is inferred from the world and reflected in four different endings — you can't quite feel good about winning." }, + { q: "What is Alpha Doc?", a: "A top-down roguelike set in a physics research facility warped by a containment breach. You play a doctoral candidate who caused the disaster the same night as their thesis defense. Now irradiated, you descend through five department wings to face the Committee." }, + { q: "What are the four radiation types?", a: "Alpha, Beta, Gamma, and Neutron, each a distinct playstyle. Neutron is the standout: it's not a weapon but an environmental transmutation tool: you reshape the map itself, destroying cover and creating hazards before a fight even starts." }, + { q: "Is there a morality system?", a: "Yes, but it's never an explicit choice. The aggressive play that wins fights also destroys the evidence of your culpability. Your standing is inferred from the world and reflected in four different endings; you can't quite feel good about winning." }, { q: "How will it be sold?", a: "Modern shareware: a free, complete first sector (the Grant Office), then a single one-time purchase to unlock the rest. No ads, no microtransactions, no energy timers." }, - { q: "When is it out?", a: "It's in active development — a playable vertical slice exists. Follow Such Software for release news on Steam, itch.io, iOS, and Android." }, + { q: "When is it out?", a: "It's in active development: a playable vertical slice exists. Follow Such Software for release news on Steam, itch.io, iOS, and Android." }, ]; const jsonLd = { @@ -50,10 +50,10 @@ const jsonLd = { const features = [ { title: "Four-element combat", body: "Alpha, Beta, Gamma, and Neutron are four real playstyles, not reskins. Each rewards a different read of the room." }, - { title: "Neutron reshapes the map", body: "The Neutron element transmutes the environment — destroy cover, open paths, arm dormant hazards. You change the battlefield before the battle." }, + { title: "Neutron reshapes the map", body: "The Neutron element transmutes the environment: destroy cover, open paths, arm dormant hazards. You change the battlefield before the battle." }, { title: "Instability as a dial", body: "Push instability for harder-hitting shots at a slower fire rate, or dial it back and let it decay. Tension, not a punishment cliff." }, { title: "Emergent morality", body: "No morality meter. Burning evidence for power quietly shifts dialogue, companion reactions, and which of four endings you reach." }, - { title: "Academic horror", body: "Your enemies are colleagues with real grievances — the reviewer you ignored, the safety inspector you overruled, the adjuncts caught in the blast." }, + { title: "Academic horror", body: "Your enemies are colleagues with real grievances: the reviewer you ignored, the safety inspector you overruled, the adjuncts caught in the blast." }, { title: "Respectful premium design", body: "Free first sector, one-time unlock, no ads or timers. The systems are built for a complete experience, not a monetization funnel." }, ]; @@ -89,7 +89,7 @@ export default function AlphaDocPage() {

It is 2:07 AM. A fifth-year PhD student has just caused a catastrophic accelerator overload, - irradiating the building and everyone in it — and the thesis defense is at 8:00 AM. Descend + irradiating the building and everyone in it, and the thesis defense is at 8:00 AM. Descend through five warped department wings, master four types of radiation, and decide whether to bury the evidence or face the Committee. Alpha Doc is a systems-driven roguelike with dark academic teeth. diff --git a/apps/web/src/app/products/barns-and-neutrons/opengraph-image.tsx b/apps/web/src/app/products/barns-and-neutrons/opengraph-image.tsx index f31911d..3e0b179 100644 --- a/apps/web/src/app/products/barns-and-neutrons/opengraph-image.tsx +++ b/apps/web/src/app/products/barns-and-neutrons/opengraph-image.tsx @@ -1,6 +1,6 @@ import { gameOgImage, OG_SIZE, OG_CONTENT_TYPE } from "@/lib/og"; -export const alt = "Barns & Neutrons — a game about the Chart of Nuclides"; +export const alt = "Barns & Neutrons: a game about the Chart of Nuclides"; export const size = OG_SIZE; export const contentType = OG_CONTENT_TYPE; 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 0f2c740..3956763 100644 --- a/apps/web/src/app/products/barns-and-neutrons/page.tsx +++ b/apps/web/src/app/products/barns-and-neutrons/page.tsx @@ -21,16 +21,16 @@ export const metadata: Metadata = { ], openGraph: { title: "Barns & Neutrons: A Game About the Chart of Nuclides", - description: "A cozy, honest expedition across the real Chart of Nuclides — the anti-spreadsheet. In development by Such Software.", + description: "A cozy, honest expedition across the real Chart of Nuclides: the anti-spreadsheet. In development by Such Software.", type: "website", url: "/products/barns-and-neutrons", }, }; const faqs = [ - { q: "What is Barns & Neutrons?", a: "A cozy exploration-puzzle game set on the real Chart of Nuclides — the grid of every known isotope. You start on a small island of known nuclides and each step into the dark is a small physics puzzle: capture a neutron, coax a decay. The reward is discovery, as a new nuclide lights up and its Compendium entry unfolds." }, + { q: "What is Barns & Neutrons?", a: "A cozy exploration-puzzle game set on the real Chart of Nuclides, the grid of every known isotope. You start on a small island of known nuclides and each step into the dark is a small physics puzzle: capture a neutron, coax a decay. The reward is discovery, as a new nuclide lights up and its Compendium entry unfolds." }, { q: "Is it educational?", a: "Yes, but through play, not lectures. Every animation reflects real physics, and discoveries unlock real-world context (Tc-99m in medical imaging, Am-241 in smoke detectors, C-14 in dating) along with half-lives, Q-values, and cornerstone papers. The data is grounded in open sources like ENDF, IAEA, and NIST." }, - { q: "What does “Barns” mean?", a: "A barn is the real unit of nuclear cross-section (10⁻²⁴ cm²) — a measure of how likely a nucleus is to interact with a neutron. The neutron-capture puzzles are literally about tuning energy to hit that cross-section." }, + { q: "What does “Barns” mean?", a: "A barn is the real unit of nuclear cross-section (10⁻²⁴ cm²), a measure of how likely a nucleus is to interact with a neutron. The neutron-capture puzzles are literally about tuning energy to hit that cross-section." }, { q: "What platforms will it be on?", a: "It is built in Godot for desktop (Windows, macOS, Linux) and mobile (iOS, Android)." }, { q: "When is it out?", a: "It is in active development. The first playable slice (the Mo-99 → Tc-99m neighborhood) is the current milestone. Follow Such Software for release news." }, ]; @@ -51,8 +51,8 @@ const jsonLd = { const features = [ { title: "Discovery is the loop", body: "No linear tech tree. You explore a real, enormous map of ~3,300 nuclides. Completionism and pure curiosity pull you deeper, with no timers and no game-overs." }, - { title: "Honest physics", body: "When reality and a cuter lie compete, reality wins — then we make reality beautiful. Neutron scattering is forward-peaked at fast energies because it actually is." }, - { title: "Failure is serendipity", body: "Miss a neutron capture and the nucleus does what it really would — maybe a decay instead. You discover a different nuclide and learn real behavior. No punishment, only discovery." }, + { title: "Honest physics", body: "When reality and a cuter lie compete, reality wins; then we make reality beautiful. Neutron scattering is forward-peaked at fast energies because it actually is." }, + { title: "Failure is serendipity", body: "Miss a neutron capture and the nucleus does what it really would: maybe a decay instead. You discover a different nuclide and learn real behavior. No punishment, only discovery." }, { title: "The Compendium", body: "Every discovered isotope unlocks a card: real uses, half-lives, Q-values, and a link to a cornerstone paper (Fermi, Chadwick, Hahn & Strassmann). You learn the history, not just the facts." }, { title: "A 3D tabletop, not a spreadsheet", body: "A tilted, extruded ceramic-tile board with a glowing valley of stability and dramatic discovery vignettes. Cozy, warm, and tactile." }, { title: "Open core", body: "The physics, data, and code are open; the art, prose, and Compendium illustrations are ours. Facts aren't copyrightable, and we cite them anyway." }, @@ -85,13 +85,13 @@ export default function BarnsAndNeutronsPage() {

-

A cozy, honest expedition across the real Chart of Nuclides — the anti-spreadsheet.

+

A cozy, honest expedition across the real Chart of Nuclides: the anti-spreadsheet.

Barns & Neutrons is a calm puzzle game about the real Chart of Nuclides. You begin on a tiny lit island of known isotopes, and each step into the dark is a small, elegant physics - puzzle — capture a neutron, coax a decay. The reward is discovery: a new nuclide lights up + puzzle: capture a neutron, coax a decay. The reward is discovery: a new nuclide lights up and its Compendium entry unfolds. It is our flagship edutainment title, and it shares its DNA with our founder’s open-source{" "} GEANT4 radiation labs. diff --git a/apps/web/src/app/products/bauhaus-echo/page.tsx b/apps/web/src/app/products/bauhaus-echo/page.tsx index 7505fd1..483c172 100644 --- a/apps/web/src/app/products/bauhaus-echo/page.tsx +++ b/apps/web/src/app/products/bauhaus-echo/page.tsx @@ -70,7 +70,7 @@ export default function BauhausEchoPage() {

A visual memory puzzle game inspired by Bauhaus design aesthetics. Memorize arrangements of geometric tiles, watch them shuffle, then reconstruct the pattern. - Or unwind in Zen mode — a pressure-free sandbox where you compose with tiles at your own pace. + Or unwind in Zen mode, a pressure-free sandbox where you compose with tiles at your own pace.

@@ -82,7 +82,7 @@ export default function BauhausEchoPage() { ]} extraLinks={[ { href: "https://bauhaus.such.software", label: "Play on Web" }, - { href: "https://suchsoftware.itch.io/bauhaus-echo", label: "itch.io — $2" }, + { href: "https://suchsoftware.itch.io/bauhaus-echo", label: "itch.io: $2" }, ]} /> @@ -90,10 +90,10 @@ export default function BauhausEchoPage() {

How It Works

    -
  1. 1. Memorization — Tiles appear in a grid. Study their positions.
  2. -
  3. 2. Shuffle — Tiles spin, shrink, and scatter to the bottom.
  4. -
  5. 3. Reconstruction — Drag tiles back to their original positions.
  6. -
  7. 4. Scoring — Earn points based on accuracy and speed.
  8. +
  9. 1. Memorization: Tiles appear in a grid. Study their positions.
  10. +
  11. 2. Shuffle: Tiles spin, shrink, and scatter to the bottom.
  12. +
  13. 3. Reconstruction: Drag tiles back to their original positions.
  14. +
  15. 4. Scoring: Earn points based on accuracy and speed.
diff --git a/apps/web/src/app/products/bauhaus-echo/privacy/page.tsx b/apps/web/src/app/products/bauhaus-echo/privacy/page.tsx index 78c20d2..3fd8b5b 100644 --- a/apps/web/src/app/products/bauhaus-echo/privacy/page.tsx +++ b/apps/web/src/app/products/bauhaus-echo/privacy/page.tsx @@ -82,8 +82,8 @@ export default function BauhausEchoPrivacyPage() {

In-App Purchases

If you purchase the "Remove Ads" upgrade, your transaction is processed by:

We do not have access to your payment information. We only receive confirmation of your purchase status. diff --git a/apps/web/src/app/products/bloomword/page.tsx b/apps/web/src/app/products/bloomword/page.tsx index ad97315..cc35105 100644 --- a/apps/web/src/app/products/bloomword/page.tsx +++ b/apps/web/src/app/products/bloomword/page.tsx @@ -95,7 +95,7 @@ export default function BloomwordPage() { Bloomword is a daily word game with a twist you can watch grow. Everyone gets the same letters each day and races the sunset to find words, and every word you find sprouts new growth on a living 3D typographic tree. Keep your streak, collect the biomes, and share the - bloom you grew today. It is free on iOS and Android — learn more at{" "} + bloom you grew today. It is free on iOS and Android. Learn more at{" "} bloomword.earth.

diff --git a/apps/web/src/app/products/decay-theory/opengraph-image.tsx b/apps/web/src/app/products/decay-theory/opengraph-image.tsx index bae1733..87b4a86 100644 --- a/apps/web/src/app/products/decay-theory/opengraph-image.tsx +++ b/apps/web/src/app/products/decay-theory/opengraph-image.tsx @@ -1,6 +1,6 @@ import { gameOgImage, OG_SIZE, OG_CONTENT_TYPE } from "@/lib/og"; -export const alt = "Decay Theory — Erwin's Atomic Adventure"; +export const alt = "Decay Theory: Erwin's Atomic Adventure"; export const size = OG_SIZE; export const contentType = OG_CONTENT_TYPE; diff --git a/apps/web/src/app/products/decay-theory/page.tsx b/apps/web/src/app/products/decay-theory/page.tsx index 43796ca..6d9c2b4 100644 --- a/apps/web/src/app/products/decay-theory/page.tsx +++ b/apps/web/src/app/products/decay-theory/page.tsx @@ -27,10 +27,10 @@ export const metadata: Metadata = { }; const faqs = [ - { q: "What is Decay Theory?", a: "A 2D side-scrolling platformer where the entire world is made of individual atoms undergoing radioactive decay in real time. You don't see platforms vanish in bulk — you watch the ground dissolve atom by atom beneath your feet." }, - { q: "Who is Erwin?", a: "Erwin is a quantum-coherent cat — a nod to Schrödinger — whose body is itself a particle system. Health is 'quantum coherence,' shown as particle density: a healthy Erwin is a tight cloud; near death, a ghostly shimmer." }, + { q: "What is Decay Theory?", a: "A 2D side-scrolling platformer where the entire world is made of individual atoms undergoing radioactive decay in real time. You don't see platforms vanish in bulk; you watch the ground dissolve atom by atom beneath your feet." }, + { q: "Who is Erwin?", a: "Erwin is a quantum-coherent cat, a nod to Schrödinger, whose body is itself a particle system. Health is 'quantum coherence,' shown as particle density: a healthy Erwin is a tight cloud; near death, a ghostly shimmer." }, { q: "Does it actually teach physics?", a: "Yes, through mechanics rather than lectures. Decay modes, half-lives, decay chains, fission, and reactor control are things you feel. Isotopes use real half-lives and color coding." }, - { q: "How is it released?", a: "Episode 1, 'Ground State,' is a free vertical slice — no ads, no IAP. The full game (more zones and powers) unlocks via a single one-time purchase." }, + { q: "How is it released?", a: "Episode 1, 'Ground State,' is a free vertical slice: no ads, no IAP. The full game (more zones and powers) unlocks via a single one-time purchase." }, { q: "When is it out?", a: "Episode 1 is the current milestone, targeting iOS and Android first, with a desktop (Steam) port later. Follow Such Software for the launch." }, ]; @@ -50,8 +50,8 @@ const jsonLd = { }; const features = [ - { title: "The world decays as you watch", body: "Every tile is thousands of simulated atoms with a real decay probability. Platforms erode into swiss cheese and crumble under your feet — stochastic, beautiful, and deadly." }, - { title: "Quantum powers", body: "Observation collapses a wave function to stabilize ground; Time Rewind undoes a fatal step. Later powers — superposition, entanglement, tunneling — each teach a real concept." }, + { title: "The world decays as you watch", body: "Every tile is thousands of simulated atoms with a real decay probability. Platforms erode into swiss cheese and crumble under your feet: stochastic, beautiful, and deadly." }, + { title: "Quantum powers", body: "Observation collapses a wave function to stabilize ground; Time Rewind undoes a fatal step. Later powers each teach a real concept: superposition, entanglement, tunneling." }, { title: "Erwin, a living particle system", body: "Your cat is rendered as 2,000+ particles. Coherence is health: take damage and Erwin literally comes apart at the seams." }, { title: "Real isotope data", body: "Isotopes carry authentic half-lives and decay chains, color-coded by family. The Geiger-counter audio tempo tracks the local decay rate." }, { title: "Tight, skill-based platforming", body: "Precise tilt-and-touch controls, checkpoints, and speedrun-friendly level design. A real platformer, not a quiz with jumps." }, @@ -91,7 +91,7 @@ export default function DecayTheoryPage() {

Decay Theory is a hard-sci-fi platformer where the entire world is composed of individual simulated atoms decaying in real time. You play Erwin, a quantum cat navigating a world that - is literally evaporating at the subatomic level — and you learn real nuclear physics by + is literally evaporating at the subatomic level, and you learn real nuclear physics by feeling it, not by reading it.

@@ -111,7 +111,7 @@ export default function DecayTheoryPage() { diff --git a/apps/web/src/app/products/neroswap/page.tsx b/apps/web/src/app/products/neroswap/page.tsx index 95450a1..bad30c7 100644 --- a/apps/web/src/app/products/neroswap/page.tsx +++ b/apps/web/src/app/products/neroswap/page.tsx @@ -49,7 +49,7 @@ const exchanges = [ { name: "BasicSwap", type: "DEX", - desc: "SMSG atomic swaps — BTC, LTC, XMR, PART, WOW, FIRO, DASH & more. Fully decentralized, on-chain settlement.", + desc: "SMSG atomic swaps: BTC, LTC, XMR, PART, WOW, FIRO, DASH & more. Fully decentralized, on-chain settlement.", }, { name: "Retoswap", @@ -93,7 +93,7 @@ const features = [ }, { title: "Clickable Markets", - desc: "Every ticker row links directly to the market on the source exchange. Find the best price, click, and trade — no extra steps.", + desc: "Every ticker row links directly to the market on the source exchange. Find the best price, click, and trade. No extra steps.", }, { title: "Kraken Reference Prices", @@ -199,7 +199,7 @@ export default function NeroswapPage() {

Neroswap runs a fleet of Python scrapers on a dedicated server. Every 10 minutes, each scraper pulls the latest orderbook or ticker data - from its exchange — via API, gRPC, or HTML scraping over Tor. The + from its exchange, via API, gRPC, or HTML scraping over Tor. The results are merged into JSON files and synced to a CDN edge server.

diff --git a/apps/web/src/app/products/page.tsx b/apps/web/src/app/products/page.tsx index 1e528bd..df48767 100644 --- a/apps/web/src/app/products/page.tsx +++ b/apps/web/src/app/products/page.tsx @@ -152,7 +152,7 @@ export default function ProductsPage() { Portfolio

- Products & projects — from commerce backends to consumer games, plus three nuclear-physics games in development. + Products & projects: from commerce backends to consumer games, plus three nuclear-physics games in development.

diff --git a/apps/web/src/app/products/such-moon-launch/leaderboard/page.tsx b/apps/web/src/app/products/such-moon-launch/leaderboard/page.tsx index 9fc4d33..4ded134 100644 --- a/apps/web/src/app/products/such-moon-launch/leaderboard/page.tsx +++ b/apps/web/src/app/products/such-moon-launch/leaderboard/page.tsx @@ -7,12 +7,12 @@ import Link from "next/link"; import type { Metadata } from "next"; export const metadata: Metadata = { - title: "Such Moon Launch — Global Leaderboard | Such Software", + title: "Such Moon Launch: Global Leaderboard | Such Software", description: "Live global rankings for Such Moon Launch: fastest landings, biggest Moonrock hauls, and Endless Mode wave records across all 12 levels.", alternates: { canonical: "/products/such-moon-launch/leaderboard" }, openGraph: { - title: "Such Moon Launch — Global Leaderboard", + title: "Such Moon Launch: Global Leaderboard", description: "Live global rankings: fastest landings, biggest Moonrock hauls, and Endless Mode wave records.", type: "website", @@ -113,7 +113,7 @@ export default async function LeaderboardPage({ 🏆 Leaderboard

- Live global rankings — {levelName}. Updates every minute. + Live global rankings: {levelName}. Updates every minute.

{/* Level selector */} @@ -167,7 +167,7 @@ export default async function LeaderboardPage({ ) : scores.length === 0 ? ( - No scores yet for {levelName}. Be the first —{" "} + No scores yet for {levelName}. Be the first:{" "} play on web @@ -227,7 +227,7 @@ export default async function LeaderboardPage({ {board === "time" ? "Ranked by fastest completion time." : board === "score" - ? "Ranked by total score — speed + fuel + Moonrocks." + ? "Ranked by total score: speed + fuel + Moonrocks." : "Ranked by highest wave survived."}

diff --git a/apps/web/src/app/products/such-moon-launch/page.tsx b/apps/web/src/app/products/such-moon-launch/page.tsx index 4d97200..f2270fc 100644 --- a/apps/web/src/app/products/such-moon-launch/page.tsx +++ b/apps/web/src/app/products/such-moon-launch/page.tsx @@ -23,7 +23,7 @@ export const metadata: Metadata = { }; const levels = [ - { name: "Moon", description: "Tutorial — learn to fly and land" }, + { name: "Moon", description: "Tutorial: learn to fly and land" }, { name: "Mars", description: "Dodge your first Martians" }, { name: "Venus", description: "Gamma rays and more enemies" }, { name: "Io", description: "Asteroids join the chaos" }, @@ -33,7 +33,7 @@ const levels = [ { name: "Pluto", description: "Tiny target, long journey" }, { name: "Asteroid Belt", description: "Land on a drifting rock cluster" }, { name: "Space Station", description: "Rotating target, black holes" }, - { name: "Mothership", description: "Boss fight — land on the enemy ship" }, + { name: "Mothership", description: "Boss fight: land on the enemy ship" }, { name: "Endless Mode", description: "Procedural waves, infinite challenge" }, ]; @@ -76,7 +76,7 @@ export default function SuchMoonLaunchPage() {

A Wownero-themed pixel-art rocket arcade. Fly across the solar system, dodge Martians, asteroids, gamma rays, and black holes. Collect crypto, upgrade your ship, and unlock - 13 ship skins. 11 story levels plus a procedural endless mode — with tilt-to-steer + 13 ship skins. 11 story levels plus a procedural endless mode, with tilt-to-steer controls on mobile.

@@ -95,7 +95,7 @@ export default function SuchMoonLaunchPage() {

Such Moon Launch is the greatly expanded re-release of the very first game I ever wrote. - The original — Meowlet Moon Launch — was a single-level rocket-landing prototype + The original, Meowlet Moon Launch, was a single-level rocket-landing prototype published years ago as a test app under our old Tabby Labs developer account. One level, simple physics, no music, no juice. But it shipped, and people played it.

@@ -104,7 +104,7 @@ export default function SuchMoonLaunchPage() { a procedural endless mode, 4 weapons, 8 ship upgrades, 13 skins, achievements on Google Play Games and Apple Game Center, cloud save, a global leaderboard backend, a 3D landing mini-game on final approach, and proper tilt-to-steer controls calibrated - for phones — no drift, no fight. All wrapped in a Wownero-themed pixel-art aesthetic. + for phones: no drift, no fight. All wrapped in a Wownero-themed pixel-art aesthetic.

Same rocket, same Moon. Almost everything else is new. @@ -114,10 +114,10 @@ export default function SuchMoonLaunchPage() {

How It Works

    -
  1. 1. Launch — Blast off from Earth with limited fuel.
  2. -
  3. 2. Navigate — Fly through space, dodging hazards and collecting crypto.
  4. -
  5. 3. Land — Touch down gently on the target planet. Tilt and speed matter.
  6. -
  7. 4. Upgrade — Spend Moonrocks on thrust, fuel, weapons, shields, and skins.
  8. +
  9. 1. Launch: Blast off from Earth with limited fuel.
  10. +
  11. 2. Navigate: Fly through space, dodging hazards and collecting crypto.
  12. +
  13. 3. Land: Touch down gently on the target planet. Tilt and speed matter.
  14. +
  15. 4. Upgrade: Spend Moonrocks on thrust, fuel, weapons, shields, and skins.
@@ -184,12 +184,12 @@ export default function SuchMoonLaunchPage() {

Space Hazards

    -
  • Martians — enemy ships that chase your rocket
  • -
  • Gamma Rays — periodic lethal beams across the level
  • -
  • Asteroids — orbiting and drifting rock hazards
  • -
  • Black Holes — extreme gravity, instant death at the event horizon
  • -
  • Nebula Zones — drain fuel and slow you down
  • -
  • Solar Wind — constant force pushing you off course
  • +
  • Martians: enemy ships that chase your rocket
  • +
  • Gamma Rays: periodic lethal beams across the level
  • +
  • Asteroids: orbiting and drifting rock hazards
  • +
  • Black Holes: extreme gravity, instant death at the event horizon
  • +
  • Nebula Zones: drain fuel and slow you down
  • +
  • Solar Wind: constant force pushing you off course
diff --git a/apps/web/src/app/products/such-moon-launch/privacy/page.tsx b/apps/web/src/app/products/such-moon-launch/privacy/page.tsx index 7bd25a3..6ff53a3 100644 --- a/apps/web/src/app/products/such-moon-launch/privacy/page.tsx +++ b/apps/web/src/app/products/such-moon-launch/privacy/page.tsx @@ -103,8 +103,8 @@ export default function SuchMoonLaunchPrivacyPage() {

In-App Purchases

If you purchase the "Remove Ads" upgrade, your transaction is processed by:

We do not have access to your payment information. We only receive confirmation of your purchase status. diff --git a/apps/web/src/app/products/suchoice/page.tsx b/apps/web/src/app/products/suchoice/page.tsx index 03511f7..8283349 100644 --- a/apps/web/src/app/products/suchoice/page.tsx +++ b/apps/web/src/app/products/suchoice/page.tsx @@ -27,7 +27,7 @@ const features = [ { name: "Snap & Decide", description: "Point your camera at any menu, ingredient list, label, or set of options. AI reads them and loads them into the wheel." }, { name: "Spin the Wheel", description: "Add your own options or use the ones AI found. Spin the wheel of destiny and go with it." }, { name: "Coin Flip", description: "Instant 50/50 decisions with a satisfying animated flip, sound effects, and confetti." }, - { name: "Dice Roll", description: "3D physics dice — d6, d8, 2d6, and d20. Shake your phone or tap to roll. Real tumbling, real numbers." }, + { name: "Dice Roll", description: "3D physics dice: d6, d8, 2d6, and d20. Shake your phone or tap to roll. Real tumbling, real numbers." }, { name: "Decision Duel", description: "Two players, one screen. Tap near the puck to send it flying toward your opponent's goal. Speed increases every hit." }, { name: "Adventure Mode", description: "Enter a city, spin for a random activity, and open the winner in Google Maps." }, ]; @@ -69,7 +69,7 @@ export default function SuchoicePage() {

- Stop overthinking every decision. Six ways to decide — snap a photo and let AI read it, spin the wheel, flip a coin, roll 3D physics dice, battle it out in a head-to-head duel, or explore your city with a random activity. + Stop overthinking every decision. Six ways to decide: snap a photo and let AI read it, spin the wheel, flip a coin, roll 3D physics dice, battle it out in a head-to-head duel, or explore your city with a random activity.

diff --git a/apps/web/src/app/products/vegan-iq/page.tsx b/apps/web/src/app/products/vegan-iq/page.tsx index 23bf87c..df4fe80 100644 --- a/apps/web/src/app/products/vegan-iq/page.tsx +++ b/apps/web/src/app/products/vegan-iq/page.tsx @@ -100,10 +100,10 @@ export default function VeganIqPage() { Every question in Vegan IQ is grounded in real data. We do not use LLMs to generate question content. Our sources include:

    -
  • USDA FoodData Central — nutritional composition of plant-based foods
  • -
  • Poore & Nemecek, Science (2018) — environmental impact data for food production
  • -
  • National Institutes of Health (NIH) — health and dietary reference data
  • -
  • FAOSTAT — global food production and agricultural statistics from the UN FAO
  • +
  • USDA FoodData Central: nutritional composition of plant-based foods
  • +
  • Poore & Nemecek, Science (2018): environmental impact data for food production
  • +
  • National Institutes of Health (NIH): health and dietary reference data
  • +
  • FAOSTAT: global food production and agricultural statistics from the UN FAO
diff --git a/apps/web/src/app/services/opengraph-image.tsx b/apps/web/src/app/services/opengraph-image.tsx index ecca978..5b410e6 100644 --- a/apps/web/src/app/services/opengraph-image.tsx +++ b/apps/web/src/app/services/opengraph-image.tsx @@ -1,6 +1,6 @@ import { gameOgImage, OG_SIZE, OG_CONTENT_TYPE } from "@/lib/og"; -export const alt = "Such Software — four things, done well"; +export const alt = "Such Software: four things, done well"; export const size = OG_SIZE; export const contentType = OG_CONTENT_TYPE; diff --git a/apps/web/src/app/support/page.tsx b/apps/web/src/app/support/page.tsx index 2c99adb..7fe7f4d 100644 --- a/apps/web/src/app/support/page.tsx +++ b/apps/web/src/app/support/page.tsx @@ -33,7 +33,7 @@ export default function SupportPage() {

Bug Reports

- Something not working right? Let us know what happened, your device, and OS version — we'll investigate. + Something not working right? Let us know what happened, your device, and OS version. We'll investigate.

diff --git a/apps/web/src/components/UmamiAnalytics.tsx b/apps/web/src/components/UmamiAnalytics.tsx index 309e920..67ed581 100644 --- a/apps/web/src/components/UmamiAnalytics.tsx +++ b/apps/web/src/components/UmamiAnalytics.tsx @@ -1,7 +1,7 @@ 'use client'; import { useEffect } from 'react'; -// Self-hosted, cookieless Umami — config via env so nothing is hardcoded. +// Self-hosted, cookieless Umami: config via env so nothing is hardcoded. // Honors Global Privacy Control + Do-Not-Track. No-op unless both env vars are set. const HOST = process.env.NEXT_PUBLIC_UMAMI_HOST; const WEBSITE_ID = process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID; diff --git a/apps/web/src/components/landing/dynamic-background.tsx b/apps/web/src/components/landing/dynamic-background.tsx index dc75950..0401f88 100644 --- a/apps/web/src/components/landing/dynamic-background.tsx +++ b/apps/web/src/components/landing/dynamic-background.tsx @@ -56,7 +56,7 @@ export function DynamicBackground({ nebulaPosition, visible = true }: DynamicBac const effectiveTheme = resolvedTheme || systemTheme || 'dark'; const themeMode = effectiveTheme === 'dark' ? 'dark' : 'light'; - // While the splash is active (visible === false) keep the nebula/monitor hidden — + // While the splash is active (visible === false) keep the nebula/monitor hidden; // the splash provides its own Cherenkov glow. Reveal it once the visitor enters. if (!showNebula || !visible) { return
; diff --git a/apps/web/src/components/landing/home-shell.tsx b/apps/web/src/components/landing/home-shell.tsx index 0dc8f92..8058644 100644 --- a/apps/web/src/components/landing/home-shell.tsx +++ b/apps/web/src/components/landing/home-shell.tsx @@ -121,7 +121,7 @@ export function HomeShell({ children }: { children: ReactNode }) { const pin = () => window.scrollTo(0, 0); window.addEventListener("scroll", pin, { passive: true }); // The gesture that triggered the enter keeps emitting MOMENTUM (a trackpad flick - // can trail for ~1.5s — longer than the 800ms wave). Releasing the lock on a fixed + // can trail for ~1.5s, longer than the 800ms wave). Releasing the lock on a fixed // timer let those trailing ticks scroll the revealed page, so you landed below the // hero instead of at the very top. Hold the lock until the input goes QUIET // (250ms with no wheel/touch), capped at 3s so a deliberate scroller is never trapped. diff --git a/apps/web/src/components/portfolio/bento-grid.tsx b/apps/web/src/components/portfolio/bento-grid.tsx index 4179ec7..4c338bf 100644 --- a/apps/web/src/components/portfolio/bento-grid.tsx +++ b/apps/web/src/components/portfolio/bento-grid.tsx @@ -4,7 +4,7 @@ import Link from "next/link"; import { HoverVignette } from "@/components/showcase/hover-vignette"; // Literal class strings per color so Tailwind's JIT keeps them (no dynamic interpolation). -// The colour tint + border only paint on hover/focus (via the `group/tile` link) — at rest +// The colour tint + border only paint on hover/focus (via the `group/tile` link); at rest // the .bento-item CSS keeps the card chrome transparent so tiles read as title + render only. const cardBg: Record = { orange: "group-hover/tile:!bg-orange-50/95 dark:group-hover/tile:!bg-orange-950/95 group-focus-within/tile:!bg-orange-50/95 dark:group-focus-within/tile:!bg-orange-950/95 group-hover/tile:!border-orange-500/20 group-focus-within/tile:!border-orange-500/20", @@ -51,7 +51,7 @@ type Item = { href: string; external?: boolean; /** - * Optional hover/focus "vignette" — a transparent alpha-WebM 3D render from the + * Optional hover/focus "vignette", a transparent alpha-WebM 3D render from the * game/app that plays OVER this tile's static art on hover or keyboard focus. * Purely additive: with no assets present (or on Safari / reduced-motion) the tile * renders exactly as its static `image`. Asset convention: @@ -71,11 +71,11 @@ const items: Item[] = [ // 3D smirk coin (our engine + sg_outline inset ink): rests smirk-up, hover tosses it with a // decelerating end-over-end tumble (the suchoice coin-flip feel), lands $-up, half-flips home. { name: "Smirk Wallet", tagline: "Non-custodial browser wallet with social tipping.", color: "amber", span: 1, image: "/images/products/smirk-wallet.png", alt: "Smirk Wallet browser extension", href: "https://smirk.cash", external: true, vignette: { webm: "/showcase/vignettes/smirk.webm", poster: "/showcase/vignettes/smirk.png" } }, - // Transparent chroma-keyed vignette (the engine can't emit real alpha — BW_FLAT magenta key): + // Transparent chroma-keyed vignette (the engine can't emit real alpha, hence the BW_FLAT magenta key): // full-bloom tree at rest, hover retracts and regrows it. Palindrome loop, seam 0.0. { name: "Bloomword", tagline: "A word game where every answer grows the tree.", color: "green", span: 1, image: "/images/products/bloomword.png", alt: "Bloomword, a word game about growing a tree", href: "/products/bloomword", vignette: { webm: "/showcase/vignettes/bloomword.webm", poster: "/showcase/vignettes/bloomword.png" } }, // Single theme-independent asset: the INSET black silhouette stroke (sg_outline) sits ON the yellow letters, so one - // baked alpha render reads on both light and dark tiles — no per-theme pair needed (a 3D->web pipeline win). + // baked alpha render reads on both light and dark tiles; no per-theme pair needed (a 3D->web pipeline win). { name: "Barns & Neutrons", tagline: "Cozy puzzle expedition across the real Chart of Nuclides.", color: "amber", span: 2, image: "/images/products/barns-and-neutrons.svg", alt: "Barns & Neutrons, a game about the Chart of Nuclides", href: "/products/barns-and-neutrons", vignette: { webm: "/showcase/vignettes/barns.webm", poster: "/showcase/vignettes/barns.png" } }, // Cover reel from the vegan-IQ social pipeline: logo panel at rest, card-flips to a real // quiz question (unanswered -> answered) on hover, flips back for a perfect loop seam. @@ -83,8 +83,8 @@ const items: Item[] = [ ]; function BentoCard({ item, delay }: { item: Item; delay: number }) { - // Feature tiles (a live vignette) drop the static screenshot — the transparent poster is the - // rest state — and grow + lift above their neighbours on hover so the animation is the focus. + // Feature tiles (a live vignette) drop the static screenshot, since the transparent poster is the + // rest state, and grow + lift above their neighbours on hover so the animation is the focus. const feature = !!item.vignette; const inner = ( diff --git a/apps/web/src/components/products/demos-gallery.tsx b/apps/web/src/components/products/demos-gallery.tsx index d8836f1..4bc8528 100644 --- a/apps/web/src/components/products/demos-gallery.tsx +++ b/apps/web/src/components/products/demos-gallery.tsx @@ -72,7 +72,7 @@ function DemoCard({ demo }: { demo: Demo }) { aria-label={`Open the ${demo.name} demo storefront in a new tab`} > - {/* Real screenshot of the live themed storefront — captured at 1280×800, + {/* Real screenshot of the live themed storefront, captured at 1280×800, cropped to the hero/nav (the most brand-distinctive region). */}
(null); diff --git a/apps/web/src/components/store-buttons.tsx b/apps/web/src/components/store-buttons.tsx index c3dfaa0..477d276 100644 --- a/apps/web/src/components/store-buttons.tsx +++ b/apps/web/src/components/store-buttons.tsx @@ -28,7 +28,7 @@ export function StoreButtons({ links, extraLinks }: StoreButtonsProps) { return ( ); } @@ -108,7 +108,7 @@ export function BauhausEchoStoreButtons() { ]} extraLinks={[ { href: "https://bauhaus.such.software", label: "Play on Web" }, - { href: "https://suchsoftware.itch.io/bauhaus-echo", label: "itch.io — $2" }, + { href: "https://suchsoftware.itch.io/bauhaus-echo", label: "itch.io: $2" }, ]} /> ); diff --git a/apps/web/src/lib/services.ts b/apps/web/src/lib/services.ts index 71b9fae..9558f93 100644 --- a/apps/web/src/lib/services.ts +++ b/apps/web/src/lib/services.ts @@ -104,7 +104,7 @@ const cryptoProof: Proof[] = [ ]; // Barns/nuclear/Numchangers are the science + math anchors; Zero-Day Defender, Bloomword, and -// Vegan IQ are the edutainment titles (Bloomword + Vegan IQ are cross-listed from Games & Apps — +// Vegan IQ are the edutainment titles (Bloomword + Vegan IQ are cross-listed from Games & Apps: // they are genuinely both a game we ship AND a game that teaches). const educationProof: Proof[] = [ { title: "Barns & Neutrons", blurb: "A cozy exploration-puzzle game across the real Chart of Nuclides: capture neutrons, coax decays, and learn honest nuclear physics. Our premiere visual work.", img: "/images/products/barns-and-neutrons.svg", href: "/products/barns-and-neutrons", tag: "Coming soon" },