mirror of
https://github.com/Such-Software/such.software.git
synced 2026-10-20 05:58:32 +02:00
Add splash intro, nuclear games + consulting, Cherenkov hero
- Splash: full-viewport animated SUCH logo cover with four corner nav buttons; reveals the site once "entered" (scroll-through or Explore) and does not resurrect on scroll-up. Original hero restored beneath it (title-anchored monitor pulse + Cherenkov-blue background). - Logo: traveling Cherenkov glow ring + gentle letter breath (SVG/Framer, reduced-motion safe); beveled glass corner buttons. - Services: new "Nuclear & Radiation Modeling" section + "Consulting" umbrella (payments, crypto, nuclear), MCNP Google Scholar link, and a not-a-licensed-PE clarification. - About/founder bio: LLNL credibility + accessibility, art101.io link. - Products: add Barns & Neutrons, Alpha Doc, Decay Theory (detail pages, OG cards, SVG icons); client-side sortable grid with coming-soon at the bottom. New Neroswap + Custom Websites icons (de-duplicated). - SEO: game pages added to sitemap. - Copy: dial back em-dashes to colons/commas/parens on home + services.
This commit is contained in:
@@ -32,7 +32,7 @@ export default function AboutPage() {
|
||||
|
||||
<div className="prose dark:prose-invert max-w-none mb-12">
|
||||
<p className="text-xl leading-relaxed">
|
||||
Such Software is a software studio in Kennett Square, PA. Founded by <a href="https://jwinterm.com">John Winter Murphy</a>, we build accessible e-commerce websites, crypto infrastructure, and original mobile apps and games.
|
||||
Such Software is a software studio in Kennett Square, PA, founded by <a href="https://jwinterm.com">John Winter Murphy</a>, whose background is in nuclear and radiation science: a radiation-detector PhD and six years at Lawrence Livermore National Laboratory. We build accessible e-commerce websites, crypto infrastructure, and original mobile apps and games (including a series of nuclear-themed games), and offer nuclear and radiation modeling consulting.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
+70
-45
@@ -7,60 +7,89 @@ 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 { HeroSplash } from "@/components/landing/hero-splash";
|
||||
import { ScrollReveal } from "@/components/scroll-reveal";
|
||||
import Link from "next/link";
|
||||
import { Button } from "@repo/ui/components/button";
|
||||
import { useRef, useState, useEffect } from "react";
|
||||
import Link from "next/link";
|
||||
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
||||
|
||||
// Avoid the "useLayoutEffect does nothing on the server" warning during SSR.
|
||||
const useIsoLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
||||
|
||||
export default function Home() {
|
||||
// The splash owns the first screen. Once the visitor scrolls through it (or hits
|
||||
// "Explore"), we "enter" the site: the splash unmounts for good and the real hero,
|
||||
// header, bottom nav, and background take over. Scrolling back up lands on the hero,
|
||||
// never the splash again.
|
||||
const [entered, setEntered] = useState(false);
|
||||
const splashRef = useRef<HTMLElement>(null);
|
||||
const restoreScroll = useRef(0);
|
||||
|
||||
// Deliberately place the nebula/monitor just to the left of the hero title, at any
|
||||
// screen width (restored from the original hero).
|
||||
const titleRef = useRef<HTMLHeadingElement>(null);
|
||||
const [nebulaPosition, setNebulaPosition] = useState<{ x: number; y: number } | null>(null);
|
||||
|
||||
// Dismiss the splash once it has fully scrolled out of view.
|
||||
useEffect(() => {
|
||||
if (entered) return;
|
||||
const el = splashRef.current;
|
||||
if (!el) return;
|
||||
const io = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
if (!entry.isIntersecting) {
|
||||
restoreScroll.current = Math.max(0, window.scrollY - el.offsetHeight);
|
||||
setEntered(true);
|
||||
}
|
||||
},
|
||||
{ threshold: 0 },
|
||||
);
|
||||
io.observe(el);
|
||||
return () => io.disconnect();
|
||||
}, [entered]);
|
||||
|
||||
// After the splash unmounts, keep the visitor's position in the content stable
|
||||
// (no jump). Runs before paint.
|
||||
useIsoLayoutEffect(() => {
|
||||
if (entered) window.scrollTo(0, restoreScroll.current);
|
||||
}, [entered]);
|
||||
|
||||
// Compute the nebula position from the title. Recompute once entered (the title is
|
||||
// now in its final on-screen position) and on resize / font load.
|
||||
useEffect(() => {
|
||||
const updatePosition = () => {
|
||||
if (titleRef.current) {
|
||||
const rect = titleRef.current.getBoundingClientRect();
|
||||
const viewportWidth = window.innerWidth;
|
||||
const viewportHeight = window.innerHeight;
|
||||
|
||||
// Position nebula to the left of the title with a comfortable margin
|
||||
// Convert pixel position to percentage of viewport
|
||||
const titleLeftPercent = (rect.left / viewportWidth) * 100;
|
||||
const titleTopPercent = (rect.top / viewportHeight) * 100;
|
||||
|
||||
// Place the nebula 8% to the left of where the title starts
|
||||
// and vertically aligned with the title's top area
|
||||
const nebulaX = Math.max(5, titleLeftPercent - 8);
|
||||
const nebulaY = Math.max(10, titleTopPercent - 2);
|
||||
|
||||
setNebulaPosition({ x: nebulaX, y: nebulaY });
|
||||
}
|
||||
if (!titleRef.current) return;
|
||||
const rect = titleRef.current.getBoundingClientRect();
|
||||
const titleLeftPercent = (rect.left / window.innerWidth) * 100;
|
||||
const titleTopPercent = (rect.top / window.innerHeight) * 100;
|
||||
setNebulaPosition({
|
||||
x: Math.max(5, titleLeftPercent - 8),
|
||||
y: Math.max(10, titleTopPercent - 2),
|
||||
});
|
||||
};
|
||||
|
||||
updatePosition();
|
||||
|
||||
// Update on resize
|
||||
window.addEventListener('resize', updatePosition);
|
||||
|
||||
// Also update after fonts load (can affect title width)
|
||||
window.addEventListener("resize", updatePosition);
|
||||
document.fonts?.ready.then(updatePosition);
|
||||
|
||||
return () => window.removeEventListener('resize', updatePosition);
|
||||
}, []);
|
||||
return () => window.removeEventListener("resize", updatePosition);
|
||||
}, [entered]);
|
||||
|
||||
const enterFromButton = () => {
|
||||
restoreScroll.current = 0;
|
||||
setEntered(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<main className="relative flex flex-col items-center justify-between overflow-hidden">
|
||||
<DynamicBackground nebulaPosition={nebulaPosition} />
|
||||
<Header />
|
||||
<main className="relative flex flex-col items-center overflow-hidden">
|
||||
<DynamicBackground nebulaPosition={nebulaPosition} visible={entered} />
|
||||
<Header floating visible={entered} />
|
||||
|
||||
<div id="main-content" className="z-10 w-full max-w-7xl mx-auto flex flex-col items-center pt-20 pb-10 px-4 text-center">
|
||||
{!entered && <HeroSplash sectionRef={splashRef} onEnter={enterFromButton} />}
|
||||
|
||||
<div id="main-content" className="z-10 w-full max-w-7xl mx-auto flex flex-col items-center pt-32 pb-10 px-4 text-center scroll-mt-28">
|
||||
<h1
|
||||
ref={titleRef}
|
||||
className="text-4xl sm:text-5xl md:text-7xl font-bold mb-6 bg-clip-text text-transparent bg-gradient-to-r from-blue-500 to-emerald-500 pb-2"
|
||||
style={{
|
||||
// Calculated max-width to prevent nebula overlap (only matters on larger screens)
|
||||
maxWidth: 'min(calc(90vw - 120px), 100%)',
|
||||
}}
|
||||
className="text-4xl sm:text-5xl md:text-7xl font-bold mb-6 bg-clip-text text-transparent bg-gradient-to-r from-cyan-400 to-blue-600 pb-2"
|
||||
style={{ maxWidth: "min(calc(90vw - 120px), 100%)" }}
|
||||
>
|
||||
<span className="block">Precision Engineering</span>
|
||||
<span className="block">for Everyone</span>
|
||||
@@ -71,14 +100,10 @@ export default function Home() {
|
||||
|
||||
<div className="flex gap-4 mb-10">
|
||||
<Link href="/products">
|
||||
<Button size="lg" className="rounded-full">
|
||||
View Portfolio
|
||||
</Button>
|
||||
<Button size="lg" className="rounded-full">View Portfolio</Button>
|
||||
</Link>
|
||||
<Link href="#contact">
|
||||
<Button variant="outline" size="lg" className="rounded-full">
|
||||
Start a Project
|
||||
</Button>
|
||||
<Button variant="outline" size="lg" className="rounded-full">Start a Project</Button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -115,7 +140,7 @@ export default function Home() {
|
||||
<ContactForm />
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
<MobileNav />
|
||||
<MobileNav visible={entered} />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { gameOgImage, OG_SIZE, OG_CONTENT_TYPE } from "@/lib/og";
|
||||
|
||||
export const alt = "Alpha Doc — an academic-horror roguelike";
|
||||
export const size = OG_SIZE;
|
||||
export const contentType = OG_CONTENT_TYPE;
|
||||
|
||||
export default function Image() {
|
||||
return gameOgImage({
|
||||
title: "Alpha Doc",
|
||||
tagline: "A top-down roguelike where you're the disaster. Master four kinds of radiation.",
|
||||
accent: "#fb923c",
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
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 Image from "next/image";
|
||||
import { JsonLd, breadcrumbLd, faqLd } from "@/components/seo/json-ld";
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Alpha Doc: An Academic-Horror Roguelike | Such Software",
|
||||
description: "Alpha Doc is a top-down roguelike where you're the irradiated PhD student. Master four kinds of radiation and descend to your thesis defense. In development.",
|
||||
alternates: { canonical: "/products/alpha-doc" },
|
||||
keywords: [
|
||||
"roguelike",
|
||||
"academic horror game",
|
||||
"radiation game",
|
||||
"indie roguelike",
|
||||
"physics game",
|
||||
"alpha doc",
|
||||
],
|
||||
openGraph: {
|
||||
title: "Alpha Doc: An Academic-Horror Roguelike",
|
||||
description: "A top-down roguelike where you're the disaster. Master four kinds of radiation and decide if the truth matters more than your PhD. In development.",
|
||||
type: "website",
|
||||
url: "/products/alpha-doc",
|
||||
},
|
||||
};
|
||||
|
||||
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: "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." },
|
||||
];
|
||||
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "VideoGame",
|
||||
name: "Alpha Doc",
|
||||
url: "https://such.software/products/alpha-doc",
|
||||
description:
|
||||
"A top-down academic-horror roguelike. Descend through a warped physics facility, master four types of radiation, and decide if the truth matters more than your PhD.",
|
||||
applicationCategory: "Game",
|
||||
genre: ["Roguelike", "Action", "Indie"],
|
||||
gamePlatform: ["PC", "iOS", "Android"],
|
||||
author: { "@type": "Organization", name: "Such Software" },
|
||||
publisher: { "@type": "Organization", name: "Such Software" },
|
||||
};
|
||||
|
||||
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: "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: "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." },
|
||||
];
|
||||
|
||||
export default function AlphaDocPage() {
|
||||
return (
|
||||
<main className="relative min-h-screen flex flex-col items-center bg-background text-foreground">
|
||||
<JsonLd data={breadcrumbLd([
|
||||
{ name: "Home", path: "/" },
|
||||
{ name: "Products", path: "/products" },
|
||||
{ name: "Alpha Doc", path: "/products/alpha-doc" },
|
||||
])} />
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
|
||||
<JsonLd data={faqLd(faqs)} />
|
||||
<Header />
|
||||
<div id="main-content" className="z-10 w-full max-w-4xl mx-auto py-20 px-4 pb-24 md:pb-20">
|
||||
<Link href="/products" className="text-sm text-muted-foreground hover:text-foreground mb-8 inline-block">
|
||||
← Back to Products
|
||||
</Link>
|
||||
|
||||
<div className="flex items-center gap-4 mb-2">
|
||||
<Image src="/images/products/alpha-doc.svg" alt="Alpha Doc icon" width={64} height={64} className="rounded-2xl" />
|
||||
<div>
|
||||
<span className="inline-flex items-center rounded-full bg-orange-400/15 px-2.5 py-0.5 font-mono text-[10px] uppercase tracking-[0.2em] text-orange-600 dark:text-orange-400 mb-1">
|
||||
In Development
|
||||
</span>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-orange-600 dark:text-orange-400 leading-none">
|
||||
Alpha Doc
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-base text-muted-foreground mb-6">A top-down roguelike where you’re the disaster.</p>
|
||||
|
||||
<div className="prose dark:prose-invert max-w-none mb-12">
|
||||
<p className="text-xl text-muted-foreground leading-relaxed">
|
||||
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
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-6">What makes it different</h2>
|
||||
<div className="grid md:grid-cols-2 gap-6 mb-12">
|
||||
{features.map((f) => (
|
||||
<Card key={f.title} className="glass-card border-orange-500/20">
|
||||
<h3 className="text-lg font-bold mb-2">{f.title}</h3>
|
||||
<p className="text-sm text-muted-foreground">{f.body}</p>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-6">Under the Hood</h2>
|
||||
<div className="section-container border-l-4 border-orange-500 mb-12">
|
||||
<ul className="space-y-2 text-muted-foreground">
|
||||
<li><strong>Engine:</strong> Godot 4 (.NET / C#) with a fixed 3/4 orthographic camera.</li>
|
||||
<li><strong>Procedural generation:</strong> BSP rooms and constraint-solved layouts for endless runs.</li>
|
||||
<li><strong>Structure:</strong> five sectors, four bosses plus a multi-phase thesis defense, and four endings.</li>
|
||||
<li><strong>Platforms:</strong> Steam and itch.io on desktop, plus iOS and Android.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-6">FAQ</h2>
|
||||
<div className="space-y-6 mb-12">
|
||||
{faqs.map((f) => (
|
||||
<div key={f.q}>
|
||||
<h3 className="font-bold mb-1 text-orange-600 dark:text-orange-400">{f.q}</h3>
|
||||
<p className="text-muted-foreground">{f.a}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4 text-sm text-muted-foreground flex-wrap">
|
||||
<Link href="/products" className="hover:text-foreground transition-colors">All Products</Link>
|
||||
<span>•</span>
|
||||
<Link href="/support" className="hover:text-foreground transition-colors">Get notified / Feedback</Link>
|
||||
<span>•</span>
|
||||
<span>Contact: apps@such.software</span>
|
||||
</div>
|
||||
</div>
|
||||
<MobileNav />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { gameOgImage, OG_SIZE, OG_CONTENT_TYPE } from "@/lib/og";
|
||||
|
||||
export const alt = "Barns & Neutrons — a game about the Table of Nuclides";
|
||||
export const size = OG_SIZE;
|
||||
export const contentType = OG_CONTENT_TYPE;
|
||||
|
||||
export default function Image() {
|
||||
return gameOgImage({
|
||||
title: "Barns & Neutrons",
|
||||
tagline: "A cozy, honest expedition across the real Table of Nuclides.",
|
||||
accent: "#facc15",
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
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 Image from "next/image";
|
||||
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",
|
||||
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: [
|
||||
"table of nuclides game",
|
||||
"nuclear physics game",
|
||||
"edutainment game",
|
||||
"isotope game",
|
||||
"neutron capture",
|
||||
"radiochemistry game",
|
||||
"barns and neutrons",
|
||||
],
|
||||
openGraph: {
|
||||
title: "Barns & Neutrons: A Game About the Table of Nuclides",
|
||||
description: "A cozy, honest expedition across the real Table 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 Table 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 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." },
|
||||
];
|
||||
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "VideoGame",
|
||||
name: "Barns & Neutrons",
|
||||
url: "https://such.software/products/barns-and-neutrons",
|
||||
description:
|
||||
"A cozy exploration-puzzle game across the real Table of Nuclides. Capture neutrons, coax decays, and learn honest, cited nuclear physics.",
|
||||
applicationCategory: "Game",
|
||||
genre: ["Puzzle", "Educational", "Simulation"],
|
||||
gamePlatform: ["PC", "iOS", "Android"],
|
||||
author: { "@type": "Organization", name: "Such Software" },
|
||||
publisher: { "@type": "Organization", name: "Such Software" },
|
||||
};
|
||||
|
||||
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: "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." },
|
||||
];
|
||||
|
||||
export default function BarnsAndNeutronsPage() {
|
||||
return (
|
||||
<main className="relative min-h-screen flex flex-col items-center bg-background text-foreground">
|
||||
<JsonLd data={breadcrumbLd([
|
||||
{ name: "Home", path: "/" },
|
||||
{ name: "Products", path: "/products" },
|
||||
{ name: "Barns & Neutrons", path: "/products/barns-and-neutrons" },
|
||||
])} />
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
|
||||
<JsonLd data={faqLd(faqs)} />
|
||||
<Header />
|
||||
<div id="main-content" className="z-10 w-full max-w-4xl mx-auto py-20 px-4 pb-24 md:pb-20">
|
||||
<Link href="/products" className="text-sm text-muted-foreground hover:text-foreground mb-8 inline-block">
|
||||
← Back to Products
|
||||
</Link>
|
||||
|
||||
<div className="flex items-center gap-4 mb-2">
|
||||
<Image src="/images/products/barns-and-neutrons.svg" alt="Barns & Neutrons icon" width={64} height={64} className="rounded-2xl" />
|
||||
<div>
|
||||
<span className="inline-flex items-center rounded-full bg-yellow-400/15 px-2.5 py-0.5 font-mono text-[10px] uppercase tracking-[0.2em] text-yellow-600 dark:text-yellow-400 mb-1">
|
||||
In Development
|
||||
</span>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-yellow-600 dark:text-yellow-400 leading-none">
|
||||
Barns & Neutrons
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-base text-muted-foreground mb-6">A cozy, honest expedition across the real Table of Nuclides — the anti-spreadsheet.</p>
|
||||
|
||||
<div className="prose dark:prose-invert max-w-none mb-12">
|
||||
<p className="text-xl text-muted-foreground leading-relaxed">
|
||||
Barns & Neutrons is a calm puzzle game about the real Table 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
|
||||
and its Compendium entry unfolds. It is our flagship edutainment title, and it shares its
|
||||
DNA with our founder’s open-source{" "}
|
||||
<a href="https://jwinterm.github.io/geant4-radiation-labs/" target="_blank" rel="noopener noreferrer" className="text-yellow-600 dark:text-yellow-400 hover:underline">GEANT4 radiation labs</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-6">What makes it different</h2>
|
||||
<div className="grid md:grid-cols-2 gap-6 mb-12">
|
||||
{features.map((f) => (
|
||||
<Card key={f.title} className="glass-card border-yellow-500/20">
|
||||
<h3 className="text-lg font-bold mb-2">{f.title}</h3>
|
||||
<p className="text-sm text-muted-foreground">{f.body}</p>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-6">Under the Hood</h2>
|
||||
<div className="section-container border-l-4 border-yellow-500 mb-12">
|
||||
<ul className="space-y-2 text-muted-foreground">
|
||||
<li><strong>Engine:</strong> Godot 4, one codebase for desktop and mobile.</li>
|
||||
<li><strong>The board:</strong> all ~3,300 nuclides rendered in a single 3D instance, with a glowing valley of stability.</li>
|
||||
<li><strong>Ground truth:</strong> nuclear data from ENDF/B-VIII.0, IAEA, and NIST, with clickable citations in-game.</li>
|
||||
<li><strong>Honest model:</strong> real cross-sections, real decay modes, real moderation physics.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-6">FAQ</h2>
|
||||
<div className="space-y-6 mb-12">
|
||||
{faqs.map((f) => (
|
||||
<div key={f.q}>
|
||||
<h3 className="font-bold mb-1 text-yellow-600 dark:text-yellow-400">{f.q}</h3>
|
||||
<p className="text-muted-foreground">{f.a}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="text-muted-foreground mb-12">
|
||||
Curious about the science behind it? See our{" "}
|
||||
<Link href="/services" className="text-yellow-600 dark:text-yellow-400 hover:underline">nuclear & radiation modeling</Link>
|
||||
{" "}work.
|
||||
</p>
|
||||
|
||||
<div className="flex items-center gap-4 text-sm text-muted-foreground flex-wrap">
|
||||
<Link href="/products" className="hover:text-foreground transition-colors">All Products</Link>
|
||||
<span>•</span>
|
||||
<Link href="/support" className="hover:text-foreground transition-colors">Get notified / Feedback</Link>
|
||||
<span>•</span>
|
||||
<span>Contact: apps@such.software</span>
|
||||
</div>
|
||||
</div>
|
||||
<MobileNav />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { gameOgImage, OG_SIZE, OG_CONTENT_TYPE } from "@/lib/og";
|
||||
|
||||
export const alt = "Decay Theory — Erwin's Atomic Adventure";
|
||||
export const size = OG_SIZE;
|
||||
export const contentType = OG_CONTENT_TYPE;
|
||||
|
||||
export default function Image() {
|
||||
return gameOgImage({
|
||||
title: "Decay Theory",
|
||||
tagline: "Watch the ground dissolve beneath your feet. Atom by atom.",
|
||||
accent: "#22d3ee",
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
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 Image from "next/image";
|
||||
import { JsonLd, breadcrumbLd, faqLd } from "@/components/seo/json-ld";
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Decay Theory: Erwin's Atomic Adventure | Such Software",
|
||||
description: "Decay Theory is a side-scrolling platformer where the world decays atom by atom in real time. Play Erwin, a quantum cat, and learn real nuclear physics. In development.",
|
||||
alternates: { canonical: "/products/decay-theory" },
|
||||
keywords: [
|
||||
"platformer",
|
||||
"physics platformer",
|
||||
"nuclear physics game",
|
||||
"indie game",
|
||||
"decay theory",
|
||||
"Erwin atomic adventure",
|
||||
],
|
||||
openGraph: {
|
||||
title: "Decay Theory: Erwin's Atomic Adventure",
|
||||
description: "Watch the ground dissolve beneath your feet, atom by atom. A platformer that teaches real nuclear physics. In development.",
|
||||
type: "website",
|
||||
url: "/products/decay-theory",
|
||||
},
|
||||
};
|
||||
|
||||
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: "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: "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." },
|
||||
];
|
||||
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "VideoGame",
|
||||
name: "Decay Theory: Erwin's Atomic Adventure",
|
||||
alternateName: "Decay Theory",
|
||||
url: "https://such.software/products/decay-theory",
|
||||
description:
|
||||
"A side-scrolling platformer where the world is simulated atom by atom, decaying in real time. Play Erwin, a quantum cat, and learn real nuclear physics.",
|
||||
applicationCategory: "Game",
|
||||
genre: ["Platformer", "Educational", "Indie"],
|
||||
gamePlatform: ["iOS", "Android", "PC"],
|
||||
author: { "@type": "Organization", name: "Such Software" },
|
||||
publisher: { "@type": "Organization", name: "Such Software" },
|
||||
};
|
||||
|
||||
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: "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." },
|
||||
{ title: "Premium, not predatory", body: "Free Episode 1, one-time unlock for the rest. No ads, no loot boxes, no energy systems, no tracking." },
|
||||
];
|
||||
|
||||
export default function DecayTheoryPage() {
|
||||
return (
|
||||
<main className="relative min-h-screen flex flex-col items-center bg-background text-foreground">
|
||||
<JsonLd data={breadcrumbLd([
|
||||
{ name: "Home", path: "/" },
|
||||
{ name: "Products", path: "/products" },
|
||||
{ name: "Decay Theory", path: "/products/decay-theory" },
|
||||
])} />
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
|
||||
<JsonLd data={faqLd(faqs)} />
|
||||
<Header />
|
||||
<div id="main-content" className="z-10 w-full max-w-4xl mx-auto py-20 px-4 pb-24 md:pb-20">
|
||||
<Link href="/products" className="text-sm text-muted-foreground hover:text-foreground mb-8 inline-block">
|
||||
← Back to Products
|
||||
</Link>
|
||||
|
||||
<div className="flex items-center gap-4 mb-2">
|
||||
<Image src="/images/products/decay-theory.svg" alt="Decay Theory icon" width={64} height={64} className="rounded-2xl" />
|
||||
<div>
|
||||
<span className="inline-flex items-center rounded-full bg-cyan-400/15 px-2.5 py-0.5 font-mono text-[10px] uppercase tracking-[0.2em] text-cyan-600 dark:text-cyan-400 mb-1">
|
||||
In Development
|
||||
</span>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-cyan-600 dark:text-cyan-400 leading-none">
|
||||
Decay Theory
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-base text-muted-foreground mb-6">Watch the ground dissolve beneath your feet. Atom by atom.</p>
|
||||
|
||||
<div className="prose dark:prose-invert max-w-none mb-12">
|
||||
<p className="text-xl text-muted-foreground leading-relaxed">
|
||||
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
|
||||
feeling it, not by reading it.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-6">What makes it different</h2>
|
||||
<div className="grid md:grid-cols-2 gap-6 mb-12">
|
||||
{features.map((f) => (
|
||||
<Card key={f.title} className="glass-card border-cyan-500/20">
|
||||
<h3 className="text-lg font-bold mb-2">{f.title}</h3>
|
||||
<p className="text-sm text-muted-foreground">{f.body}</p>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-6">Under the Hood</h2>
|
||||
<div className="section-container border-l-4 border-cyan-500 mb-12">
|
||||
<ul className="space-y-2 text-muted-foreground">
|
||||
<li><strong>Architecture:</strong> Godot renders; a Rust core runs 100% of the atom simulation.</li>
|
||||
<li><strong>Performance:</strong> tens of thousands of active, decaying atoms at a smooth frame rate on mid-range phones.</li>
|
||||
<li><strong>Powers:</strong> quantum mechanics turned into verbs — observation, time rewind, and more.</li>
|
||||
<li><strong>Platforms:</strong> iOS and Android first, desktop (Steam) to follow.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold mb-6">FAQ</h2>
|
||||
<div className="space-y-6 mb-12">
|
||||
{faqs.map((f) => (
|
||||
<div key={f.q}>
|
||||
<h3 className="font-bold mb-1 text-cyan-600 dark:text-cyan-400">{f.q}</h3>
|
||||
<p className="text-muted-foreground">{f.a}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4 text-sm text-muted-foreground flex-wrap">
|
||||
<Link href="/products" className="hover:text-foreground transition-colors">All Products</Link>
|
||||
<span>•</span>
|
||||
<Link href="/support" className="hover:text-foreground transition-colors">Get notified / Feedback</Link>
|
||||
<span>•</span>
|
||||
<span>Contact: apps@such.software</span>
|
||||
</div>
|
||||
</div>
|
||||
<MobileNav />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -1,36 +1,35 @@
|
||||
import { Header } from "@/components/layout/header";
|
||||
import { MobileNav } from "@/components/layout/mobile-nav";
|
||||
import { ScrollReveal } from "@/components/scroll-reveal";
|
||||
import { Card } from "@repo/ui/components/card";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { ProductsGrid, type Product } from "@/components/portfolio/products-grid";
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Our Products & Apps: Crypto Tools, Games & Commerce | Such Software",
|
||||
description: "Explore Such Software's products: Wownerogue Monero roguelike, Neroswap crypto aggregator, Smirk tipping wallet, headless Webshops, and our mobile games.",
|
||||
title: "Our Products & Apps: Crypto Tools, Nuclear 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, Games & Commerce | Such Software",
|
||||
description: "Explore Such Software's products: Wownerogue Monero roguelike, Neroswap crypto aggregator, Smirk tipping wallet, headless Webshops, and our mobile games.",
|
||||
title: "Our Products & Apps: Crypto Tools, Nuclear 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",
|
||||
},
|
||||
};
|
||||
|
||||
const products = [
|
||||
const products: Product[] = [
|
||||
{
|
||||
slug: "webshops",
|
||||
title: "Webshops",
|
||||
description: "Custom online stores on revenue-share pricing. No upfront cost. Built on headless Medusa.",
|
||||
color: "emerald",
|
||||
icon: "/images/products/occupy-wallets.png",
|
||||
releaseDate: "2025-01-01",
|
||||
},
|
||||
{
|
||||
slug: "custom-websites",
|
||||
title: "Custom Websites",
|
||||
description: "Real-time web apps, multiplayer games, and live dashboards. Built on Next.js, Socket.io, and WebRTC.",
|
||||
color: "purple",
|
||||
icon: "/images/products/neroswap.png",
|
||||
icon: "/images/products/custom-websites.svg",
|
||||
releaseDate: "2025-01-01",
|
||||
},
|
||||
{
|
||||
slug: "smirk-wallet",
|
||||
@@ -38,6 +37,7 @@ const products = [
|
||||
description: "Non-custodial browser wallet for social tipping. BTC, LTC, XMR, WOW, GRIN.",
|
||||
color: "amber",
|
||||
icon: "/images/products/smirk-wallet.png",
|
||||
releaseDate: "2026-03-01",
|
||||
},
|
||||
{
|
||||
slug: "bauhaus-echo",
|
||||
@@ -45,6 +45,7 @@ const products = [
|
||||
description: "Visual memory puzzle game inspired by Bauhaus design. Android, iOS, Web.",
|
||||
color: "blue",
|
||||
icon: "/images/products/bauhaus-echo.png",
|
||||
releaseDate: "2026-04-01",
|
||||
},
|
||||
{
|
||||
slug: "suchoice",
|
||||
@@ -52,6 +53,7 @@ const products = [
|
||||
description: "Stop overthinking decisions. Snap a photo, let AI read the options, spin the wheel. Plus coin flip and adventure mode. Android and iOS.",
|
||||
color: "pink",
|
||||
icon: "/images/products/suchoice.png",
|
||||
releaseDate: "2026-04-01",
|
||||
},
|
||||
{
|
||||
slug: "vegan-iq",
|
||||
@@ -59,6 +61,7 @@ const products = [
|
||||
description: "Test your plant-based knowledge with 1,000+ trivia questions across 8 categories, plus a daily challenge and weekly quiz. Android and iOS.",
|
||||
color: "green",
|
||||
icon: "/images/products/vegan-iq.png",
|
||||
releaseDate: "2026-04-01",
|
||||
},
|
||||
{
|
||||
slug: "such-moon-launch",
|
||||
@@ -66,6 +69,7 @@ const products = [
|
||||
description: "Vry rocket. Much landing. Wow! Wownero-themed pixel rocket arcade. 11 levels, 4 weapons, tilt-to-steer, endless mode. Android, iOS, Web, Desktop.",
|
||||
color: "amber",
|
||||
icon: "/images/products/such-moon-launch.png",
|
||||
releaseDate: "2026-05-01",
|
||||
},
|
||||
{
|
||||
slug: "wownerogue",
|
||||
@@ -73,38 +77,45 @@ const products = [
|
||||
description: "A provably-fair multiplayer roguelike synced to Monero and Wownero block times. Play free in the browser, escape the dungeon, earn on-chain payouts.",
|
||||
color: "orange",
|
||||
icon: "/images/products/privacy-labs.png",
|
||||
releaseDate: "2026-06-01",
|
||||
},
|
||||
{
|
||||
slug: "neroswap",
|
||||
title: "Neroswap",
|
||||
description: "Aggregated DEX & CEX orderbook data. Compare Monero, Wownero, and Bitcoin prices across 6 exchanges in real time.",
|
||||
color: "yellow",
|
||||
icon: "/images/products/neroswap.png",
|
||||
icon: "/images/products/neroswap.svg",
|
||||
releaseDate: "2026-03-01",
|
||||
},
|
||||
{
|
||||
slug: "barns-and-neutrons",
|
||||
title: "Barns & Neutrons",
|
||||
description: "A cozy exploration-puzzle game across the real Table of Nuclides—the anti-spreadsheet. Capture neutrons, coax decays, and light up the chart while learning honest nuclear physics. Desktop and mobile.",
|
||||
color: "yellow",
|
||||
icon: "/images/products/barns-and-neutrons.svg",
|
||||
releaseDate: null,
|
||||
comingSoon: true,
|
||||
},
|
||||
{
|
||||
slug: "alpha-doc",
|
||||
title: "Alpha Doc",
|
||||
description: "A top-down academic-horror roguelike. You're the irradiated PhD student—master four kinds of radiation and descend through a warped physics facility to your thesis defense. Desktop and mobile.",
|
||||
color: "orange",
|
||||
icon: "/images/products/alpha-doc.svg",
|
||||
releaseDate: null,
|
||||
comingSoon: true,
|
||||
},
|
||||
{
|
||||
slug: "decay-theory",
|
||||
title: "Decay Theory",
|
||||
description: "A side-scrolling platformer where the world is simulated atom by atom, decaying in real time. Play Erwin, a quantum cat, and learn real nuclear physics. Episode 1 coming to iOS and Android.",
|
||||
color: "cyan",
|
||||
icon: "/images/products/decay-theory.svg",
|
||||
releaseDate: null,
|
||||
comingSoon: true,
|
||||
},
|
||||
];
|
||||
|
||||
const colorClasses: Record<string, string> = {
|
||||
emerald: "border-emerald-500/30 hover:border-emerald-500/60",
|
||||
purple: "border-purple-500/30 hover:border-purple-500/60",
|
||||
amber: "border-amber-500/30 hover:border-amber-500/60",
|
||||
blue: "border-blue-500/30 hover:border-blue-500/60",
|
||||
pink: "border-pink-500/30 hover:border-pink-500/60",
|
||||
orange: "border-orange-500/30 hover:border-orange-500/60",
|
||||
yellow: "border-yellow-500/30 hover:border-yellow-500/60",
|
||||
green: "border-green-500/30 hover:border-green-500/60",
|
||||
};
|
||||
|
||||
const titleColors: Record<string, string> = {
|
||||
emerald: "text-emerald-600 dark:text-emerald-400",
|
||||
purple: "text-purple-600 dark:text-purple-400",
|
||||
amber: "text-amber-600 dark:text-amber-400",
|
||||
blue: "text-blue-600 dark:text-blue-400",
|
||||
pink: "text-pink-600 dark:text-pink-400",
|
||||
orange: "text-orange-600 dark:text-orange-400",
|
||||
yellow: "text-yellow-600 dark:text-yellow-400",
|
||||
green: "text-green-600 dark:text-green-400",
|
||||
};
|
||||
|
||||
export default function ProductsPage() {
|
||||
return (
|
||||
<main className="relative min-h-screen flex flex-col items-center bg-background text-foreground">
|
||||
@@ -115,35 +126,12 @@ export default function ProductsPage() {
|
||||
Portfolio
|
||||
</h1>
|
||||
<p className="text-xl text-muted-foreground max-w-2xl mx-auto">
|
||||
Tools we have built, from commerce infrastructure to consumer apps.
|
||||
Tools we have built, from commerce infrastructure to consumer apps—plus a trio of
|
||||
nuclear games in development.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-8">
|
||||
{products.map((product, i) => (
|
||||
<ScrollReveal key={product.slug} delay={(i % 2) * 0.08}>
|
||||
<Link href={`/products/${product.slug}`}>
|
||||
<Card className={`glass-card h-full min-h-[200px] ${colorClasses[product.color]} transition-all cursor-pointer`}>
|
||||
<div className="flex items-center gap-4 mb-3">
|
||||
<Image
|
||||
src={product.icon}
|
||||
alt={`${product.title} icon`}
|
||||
width={56}
|
||||
height={56}
|
||||
className="rounded-xl flex-shrink-0"
|
||||
/>
|
||||
<h2 className={`text-2xl font-bold ${titleColors[product.color]}`}>
|
||||
{product.title}
|
||||
</h2>
|
||||
</div>
|
||||
<p className="text-muted-foreground leading-relaxed">
|
||||
{product.description}
|
||||
</p>
|
||||
</Card>
|
||||
</Link>
|
||||
</ScrollReveal>
|
||||
))}
|
||||
</div>
|
||||
<ProductsGrid products={products} />
|
||||
|
||||
<div className="flex justify-center mt-16 motion-reduce:hidden">
|
||||
<img
|
||||
|
||||
@@ -10,7 +10,8 @@ import { JsonLd, faqLd } from "@/components/seo/json-ld";
|
||||
import type { Metadata } from "next";
|
||||
|
||||
const faqs = [
|
||||
{ q: "What does Such Software build?", a: "Custom e-commerce on Medusa v2, real-time web apps and multiplayer experiences, and cryptocurrency and Monero integrations and consulting. We work across the stack, from backend infrastructure to accessible front-ends." },
|
||||
{ q: "What does Such Software build?", a: "Custom e-commerce on Medusa v2, real-time web apps and multiplayer experiences, cryptocurrency and Monero integrations, and PhD-led nuclear and radiation modeling. We work across the stack, from backend infrastructure to accessible front-ends." },
|
||||
{ q: "Do you offer nuclear and radiation consulting?", a: "Yes, for select engagements. Our founder holds a PhD in radiation-detector materials and spent six years at Lawrence Livermore National Laboratory, with a specialty in MCNP Monte Carlo transport, plus shielding and spent-fuel/dry-cask work at Holtec. We take on Monte Carlo modeling (MCNP, GEANT4), shielding and dose calculations, detector design, and radiation-science training. Contact us for rates." },
|
||||
{ q: "Where are you based?", a: "We are a software studio in Kennett Square, Pennsylvania, working with clients remotely across the US and beyond." },
|
||||
{ q: "Do you build for accessibility?", a: "Yes. We build to WCAG 2.2 and audit for accessibility and Core Web Vitals as part of every project, not as an afterthought." },
|
||||
{ q: "How does a project start?", a: "Reach out through the contact form with what you need. We scope it, propose an approach, and from there it can run as a fixed project or a performance-based revenue-share partnership." },
|
||||
@@ -18,14 +19,14 @@ const faqs = [
|
||||
];
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Medusa, Web App & Crypto Development Services | Such Software",
|
||||
description: "Custom e-commerce on Medusa v2, real-time web apps, and Monero/crypto consulting. A Kennett Square, PA studio building for scale, accessibility, and performance.",
|
||||
title: "Web, Crypto & Nuclear Modeling Services | Such Software",
|
||||
description: "Custom e-commerce on Medusa v2, real-time web apps, Monero/crypto consulting, and PhD-led nuclear & radiation modeling (MCNP, GEANT4). A Kennett Square, PA studio.",
|
||||
alternates: {
|
||||
canonical: "/services",
|
||||
},
|
||||
openGraph: {
|
||||
title: "Medusa, Web App & Crypto Development Services | Such Software",
|
||||
description: "Custom e-commerce on Medusa v2, real-time web apps, and Monero/crypto consulting. A Kennett Square, PA studio building for scale, accessibility, and performance.",
|
||||
title: "Web, Crypto & Nuclear Modeling Services | Such Software",
|
||||
description: "Custom e-commerce on Medusa v2, real-time web apps, Monero/crypto consulting, and PhD-led nuclear & radiation modeling (MCNP, GEANT4). A Kennett Square, PA studio.",
|
||||
type: "website",
|
||||
},
|
||||
};
|
||||
@@ -44,7 +45,8 @@ export default function ServicesPage() {
|
||||
Specialized Solutions
|
||||
</h1>
|
||||
<p className="text-xl text-muted-foreground max-w-2xl mx-auto">
|
||||
Focused expertise in commerce, crypto, and custom web applications.
|
||||
Focused expertise in commerce and custom web apps, plus consulting: from payments
|
||||
and crypto to nuclear and radiation modeling.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -73,8 +75,8 @@ export default function ServicesPage() {
|
||||
<Card className="glass-card hover:border-indigo-500/30">
|
||||
<h3 className="text-xl font-bold mb-3">Flexible Architecture</h3>
|
||||
<p className="text-base text-muted-foreground leading-relaxed">
|
||||
Model your exact business logic—subscriptions, bundles, B2B pricing,
|
||||
multi-warehouse inventory—without platform constraints.
|
||||
Model your exact business logic (subscriptions, bundles, B2B pricing,
|
||||
multi-warehouse inventory) without platform constraints.
|
||||
</p>
|
||||
</Card>
|
||||
<Card className="glass-card hover:border-indigo-500/30">
|
||||
@@ -87,7 +89,7 @@ export default function ServicesPage() {
|
||||
<h3 className="text-xl font-bold mb-3">Performance-First Frontend</h3>
|
||||
<p className="text-base text-muted-foreground leading-relaxed">
|
||||
Custom Next.js storefronts optimized for Core Web Vitals, accessibility,
|
||||
and conversion—not template bloat.
|
||||
and conversion, not template bloat.
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
@@ -119,10 +121,26 @@ export default function ServicesPage() {
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
{/* Consulting umbrella */}
|
||||
<ScrollReveal className="mb-12">
|
||||
<div className="text-left section-container border-l-4 border-l-teal-500">
|
||||
<h2 className="text-3xl font-bold mb-2">Consulting</h2>
|
||||
<p className="text-muted-foreground text-lg max-w-3xl leading-relaxed">
|
||||
Beyond build work, we consult where specialized, hard-won expertise matters. We
|
||||
advise on payment architecture and orchestration, and on cryptocurrency and Monero
|
||||
integration. Most distinctively, we take on nuclear and radiation modeling.
|
||||
</p>
|
||||
<p className="text-muted-foreground text-lg max-w-3xl leading-relaxed mt-3">
|
||||
The nuclear work is our standout: PhD-led Monte Carlo transport, shielding analysis,
|
||||
detector design, and training, grounded in years at a national lab. Details below.
|
||||
</p>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
{/* Crypto Section */}
|
||||
<ScrollReveal className="mb-24">
|
||||
<div className="text-left mb-10 section-container border-l-4 border-l-cyan-500">
|
||||
<h2 className="text-3xl font-bold mb-2">Cryptocurrency & Payment Consulting</h2>
|
||||
<h2 className="text-3xl font-bold mb-2">Cryptocurrency & Payments</h2>
|
||||
<p className="text-muted-foreground text-lg max-w-2xl leading-relaxed">
|
||||
Bridge traditional payments and decentralized protocols with secure, auditable infrastructure.
|
||||
</p>
|
||||
@@ -145,6 +163,84 @@ export default function ServicesPage() {
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
{/* Nuclear & Radiation Modeling Section */}
|
||||
<ScrollReveal className="mb-24">
|
||||
<div className="text-left mb-10 section-container border-l-4 border-l-cyan-400">
|
||||
<h2 className="text-3xl font-bold mb-2">Nuclear & Radiation Modeling</h2>
|
||||
<p className="text-muted-foreground text-lg max-w-3xl leading-relaxed">
|
||||
PhD-led radiation transport and nuclear expertise, available for select engagements.
|
||||
From Monte Carlo modeling to shielding analysis, we bring lab-grade rigor to hard
|
||||
problems: modeling, analysis, and consulting.
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid md:grid-cols-2 gap-6 mb-8">
|
||||
<Card className="glass-card hover:border-cyan-400/30">
|
||||
<h3 className="text-xl font-bold mb-3">Monte Carlo Transport</h3>
|
||||
<p className="text-base text-muted-foreground leading-relaxed">
|
||||
Radiation transport modeling in <span className="font-semibold text-foreground">MCNP</span>{" "}
|
||||
(<a href="https://scholar.google.com/citations?user=xTyYIKkAAAAJ&hl=en" target="_blank" rel="noopener noreferrer" className="font-semibold text-foreground underline decoration-cyan-400/50 hover:text-primary transition-colors">multiple peer-reviewed papers</a>)
|
||||
and <span className="font-semibold text-foreground">GEANT4</span>, for
|
||||
detectors, sources, and complex geometries.
|
||||
</p>
|
||||
</Card>
|
||||
<Card className="glass-card hover:border-cyan-400/30">
|
||||
<h3 className="text-xl font-bold mb-3">Shielding & Dose</h3>
|
||||
<p className="text-base text-muted-foreground leading-relaxed">
|
||||
Shielding calculations and dose analysis, including spent-fuel handling and
|
||||
dry-cask storage optimization.
|
||||
</p>
|
||||
</Card>
|
||||
<Card className="glass-card hover:border-cyan-400/30">
|
||||
<h3 className="text-xl font-bold mb-3">Detectors & Isotopes</h3>
|
||||
<p className="text-base text-muted-foreground leading-relaxed">
|
||||
Radiation detector design and characterization, plus radioisotope power
|
||||
(RTG / betavoltaic) modeling.
|
||||
</p>
|
||||
</Card>
|
||||
<Card className="glass-card hover:border-cyan-400/30">
|
||||
<h3 className="text-xl font-bold mb-3">Training & Curriculum</h3>
|
||||
<p className="text-base text-muted-foreground leading-relaxed">
|
||||
Radiation-science training and coursework. See our open-source{" "}
|
||||
<a
|
||||
href="https://jwinterm.github.io/geant4-radiation-labs/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="font-semibold text-foreground underline decoration-cyan-400/50 hover:text-primary transition-colors"
|
||||
>
|
||||
GEANT4 radiation labs
|
||||
</a>.
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
<Card className="glass-card border-cyan-400/20">
|
||||
<h3 className="text-lg font-bold mb-4">Why us</h3>
|
||||
<ul className="space-y-2 text-base text-muted-foreground leading-relaxed">
|
||||
<li>
|
||||
<span className="font-semibold text-foreground">PhD in radiation-detector materials</span>, UT-Dallas (2014)
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-semibold text-foreground">Lawrence Livermore National Laboratory</span> (2015–2021): detector systems, radioisotope battery program, MCNP5 publications
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-semibold text-foreground">Holtec International</span>: radiation shielding and spent-fuel-to-dry-cask optimization
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-semibold text-foreground">College-level instructor</span>: author of open-source GEANT4 radiation labs
|
||||
</li>
|
||||
</ul>
|
||||
<p className="text-sm text-muted-foreground mt-5">
|
||||
Select engagements, PhD-led.{" "}
|
||||
<Link href="/#contact" className="font-semibold text-foreground underline decoration-cyan-400/50 hover:text-primary transition-colors">
|
||||
Contact us for rates
|
||||
</Link>.
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground/70 mt-3">
|
||||
We provide modeling, analysis, and consulting. We are not a licensed
|
||||
professional-engineering (PE) firm and do not provide stamped engineering deliverables.
|
||||
</p>
|
||||
</Card>
|
||||
</ScrollReveal>
|
||||
|
||||
{/* Recent Work */}
|
||||
<ScrollReveal className="mb-24">
|
||||
<div className="text-left mb-10 section-container border-l-4 border-l-amber-500">
|
||||
|
||||
@@ -22,6 +22,9 @@ export default function sitemap(): MetadataRoute.Sitemap {
|
||||
{ url: `${base}/products/vegan-iq`, lastModified: updated, changeFrequency: "monthly", priority: 0.8 },
|
||||
{ url: `${base}/products/suchoice`, lastModified: updated, changeFrequency: "monthly", priority: 0.7 },
|
||||
{ url: `${base}/products/such-moon-launch`, lastModified: updated, changeFrequency: "monthly", priority: 0.7 },
|
||||
{ url: `${base}/products/barns-and-neutrons`, lastModified: updated, changeFrequency: "weekly", priority: 0.8 },
|
||||
{ url: `${base}/products/alpha-doc`, lastModified: updated, changeFrequency: "weekly", priority: 0.7 },
|
||||
{ url: `${base}/products/decay-theory`, lastModified: updated, changeFrequency: "weekly", priority: 0.7 },
|
||||
{ url: `${base}/services`, lastModified: updated, changeFrequency: "monthly", priority: 0.9 },
|
||||
{ url: `${base}/about`, lastModified: updated, changeFrequency: "monthly", priority: 0.7 },
|
||||
{ url: `${base}/support`, lastModified: updated, changeFrequency: "monthly", priority: 0.5 },
|
||||
|
||||
Reference in New Issue
Block a user