mirror of
https://github.com/Such-Software/such.software.git
synced 2026-10-18 05:41:26 +02:00
services: split the four pillars into dedicated subpages
/services becomes a hub (hero, four linked pillar cards, philosophy, recent work, FAQ, CTA) and each pillar gets its own statically-generated page at /services/[pillar] (commerce/games/crypto/education) with distinct SEO title+description+canonical, its own H1, the products behind it, a pillar-scoped FAQ + FAQ JSON-LD, breadcrumb JSON-LD, and 'the other pillars' cross-links. dynamicParams=false so unknown slugs are a static 404. The pillar/proof/FAQ data + colour maps move to lib/services.ts (single source of truth), ProofCard/PillarCards/ServicesCta/EducationCredentials to components/services, so the hub, subpages, home 'What We Do' preview, and sitemap can't drift. Home preview cards now link to their pillar; sitemap gains the four subpage URLs. All pillar copy kept verbatim. Verified: 4 subpages prebuilt, distinct titles/canonicals, right products per page, click-through nav, education credentials block, bad slug -> 404.
This commit is contained in:
@@ -1,49 +1,54 @@
|
||||
import { Card } from "@repo/ui/components/card";
|
||||
import Link from "next/link";
|
||||
|
||||
// The four "What We Do" cards on the home page, each linking to its /services/<slug> pillar page.
|
||||
const previews = [
|
||||
{
|
||||
href: "/services/commerce",
|
||||
title: "E-Commerce & Hosting",
|
||||
body: "Headless storefronts on Medusa and Next.js, built fast and hosted on our own infrastructure. Stripe Connect with a revenue-share model: you stay the merchant of record, and crypto settles straight to your own wallets.",
|
||||
},
|
||||
{
|
||||
href: "/services/games",
|
||||
title: "Custom App Development",
|
||||
body: "Cross-platform mobile and web apps built to spec. We handle architecture, deployment, and ongoing support so you can focus on your business.",
|
||||
},
|
||||
{
|
||||
href: "/services/crypto",
|
||||
title: "Crypto & Payment Integration",
|
||||
body: "Software and integration for multi-currency checkout and non-custodial crypto payments, in production since 2014. You or a licensed provider hold the funds; we never take custody.",
|
||||
},
|
||||
{
|
||||
href: "/services/education",
|
||||
title: "Nuclear & Radiation Education",
|
||||
body: "Training, talks, and open-source GEANT4 labs on radiation transport and semiconductor detectors, led by a PhD with a Lawrence Livermore background. Published methods and teaching.",
|
||||
},
|
||||
];
|
||||
|
||||
export function ServicesPreview() {
|
||||
return (
|
||||
<div className="w-full max-w-6xl mx-auto px-4 mt-8 mb-16 relative z-10">
|
||||
<div className="text-left mb-8 section-container border-l-4 border-l-emerald-500">
|
||||
<h2 className="text-3xl font-bold mb-3 tracking-tight">What We Do</h2>
|
||||
<p className="text-muted-foreground text-lg max-w-3xl leading-relaxed">
|
||||
We build and host custom e-commerce stores, develop apps to spec, and ship our own
|
||||
titles and games. We handle your project end to end, from architecture to deployment.
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-left mb-8 section-container border-l-4 border-l-emerald-500">
|
||||
<h2 className="text-3xl font-bold mb-3 tracking-tight">What We Do</h2>
|
||||
<p className="text-muted-foreground text-lg max-w-3xl leading-relaxed">
|
||||
We build and host custom e-commerce stores, develop apps to spec, and ship our own
|
||||
titles and games. We handle your project end to end, from architecture to deployment.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
<Card className="glass-card hover:border-indigo-500/40 text-left">
|
||||
<h3 className="text-xl font-bold mb-3">E-Commerce & Hosting</h3>
|
||||
<p className="text-base text-muted-foreground leading-relaxed">
|
||||
Headless storefronts on Medusa and Next.js, built fast and hosted on our own
|
||||
infrastructure. Stripe Connect with a revenue-share model: you stay the merchant
|
||||
of record, and crypto settles straight to your own wallets.
|
||||
</p>
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{previews.map((p) => (
|
||||
<Link key={p.href} href={p.href} className="group block h-full">
|
||||
<Card className="glass-card h-full hover:border-indigo-500/40 text-left transition-colors">
|
||||
<h3 className="text-xl font-bold mb-3">{p.title}</h3>
|
||||
<p className="text-base text-muted-foreground leading-relaxed">{p.body}</p>
|
||||
<span className="mt-3 inline-block text-sm font-medium text-foreground group-hover:underline">
|
||||
Learn more →
|
||||
</span>
|
||||
</Card>
|
||||
<Card className="glass-card hover:border-indigo-500/40 text-left">
|
||||
<h3 className="text-xl font-bold mb-3">Custom App Development</h3>
|
||||
<p className="text-base text-muted-foreground leading-relaxed">
|
||||
Cross-platform mobile and web apps built to spec. We handle architecture,
|
||||
deployment, and ongoing support so you can focus on your business.
|
||||
</p>
|
||||
</Card>
|
||||
<Card className="glass-card hover:border-indigo-500/40 text-left">
|
||||
<h3 className="text-xl font-bold mb-3">Crypto & Payment Integration</h3>
|
||||
<p className="text-base text-muted-foreground leading-relaxed">
|
||||
Software and integration for multi-currency checkout and non-custodial crypto
|
||||
payments, in production since 2014. You or a licensed provider hold the funds;
|
||||
we never take custody.
|
||||
</p>
|
||||
</Card>
|
||||
<Card className="glass-card hover:border-indigo-500/40 text-left">
|
||||
<h3 className="text-xl font-bold mb-3">Nuclear & Radiation Education</h3>
|
||||
<p className="text-base text-muted-foreground leading-relaxed">
|
||||
Training, talks, and open-source GEANT4 labs on radiation transport and
|
||||
semiconductor detectors, led by a PhD with a Lawrence Livermore background.
|
||||
Published methods and teaching.
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Card } from "@repo/ui/components/card";
|
||||
|
||||
// Founder science credentials, shown on the Education & Science pillar page.
|
||||
export function EducationCredentials() {
|
||||
return (
|
||||
<Card className="glass-card border-amber-400/20 mt-6 !p-8">
|
||||
<h3 className="text-lg font-bold mb-4">Why us, on the science</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-xs text-muted-foreground/70 mt-5">
|
||||
This is education and published open-source methods, not for-hire controlled
|
||||
modeling. We are not a licensed professional-engineering (PE) firm and provide no
|
||||
stamped engineering deliverables.
|
||||
</p>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Card } from "@repo/ui/components/card";
|
||||
import Link from "next/link";
|
||||
import { pillars, borderL, hoverBorder } from "@/lib/services";
|
||||
|
||||
// The four pillar cards, each linking to its /services/<slug> subpage. Used as the hub's
|
||||
// primary nav and, with `exclude`, as the "explore the other pillars" block on a subpage.
|
||||
export function PillarCards({ exclude, heading }: { exclude?: string; heading?: string }) {
|
||||
const shown = pillars.filter((p) => p.slug !== exclude);
|
||||
return (
|
||||
<div>
|
||||
{heading && <h2 className="text-2xl font-bold mb-6">{heading}</h2>}
|
||||
<div className="grid sm:grid-cols-2 gap-6">
|
||||
{shown.map((p) => (
|
||||
<Link key={p.slug} href={`/services/${p.slug}`} className="group block h-full">
|
||||
<Card className={`glass-card h-full !p-7 text-left border-l-4 ${borderL[p.accent]} transition-colors ${hoverBorder[p.accent]}`}>
|
||||
<h3 className="text-xl font-bold mb-2 text-foreground">{p.title}</h3>
|
||||
<p className="text-base text-muted-foreground leading-relaxed">{p.card}</p>
|
||||
<span className="mt-3 inline-block text-sm font-medium text-foreground group-hover:underline">
|
||||
Explore {p.label} →
|
||||
</span>
|
||||
</Card>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import { Card } from "@repo/ui/components/card";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { chipAccent, hoverBorder, tagStyle, type Proof } from "@/lib/services";
|
||||
|
||||
// One "real product behind a pillar" card. Used on the hub and on every /services/[pillar] page.
|
||||
export function ProofCard({ p, accent }: { p: Proof; accent: string }) {
|
||||
const inner = (
|
||||
<Card className={`glass-card h-full !p-6 transition-colors ${hoverBorder[accent]}`}>
|
||||
<div className="flex items-start gap-4">
|
||||
{p.img ? (
|
||||
<Image
|
||||
src={p.img}
|
||||
alt={p.title}
|
||||
width={48}
|
||||
height={48}
|
||||
className="rounded-xl flex-shrink-0 h-12 w-12 object-cover bg-white/5"
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className={`flex-shrink-0 h-12 w-12 rounded-xl flex items-center justify-center text-lg font-bold ${chipAccent[accent]}`}
|
||||
>
|
||||
{p.title.charAt(0)}
|
||||
</div>
|
||||
)}
|
||||
<div className="min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1 flex-wrap">
|
||||
<h3 className="text-lg font-bold text-foreground">{p.title}</h3>
|
||||
{p.tag && (
|
||||
<span className={`text-[11px] font-medium px-2 py-0.5 rounded-full ${tagStyle[p.tag] ?? chipAccent[accent]}`}>
|
||||
{p.tag}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground leading-relaxed">{p.blurb}</p>
|
||||
{p.href && (
|
||||
<span className="mt-2 inline-block text-sm font-medium text-foreground group-hover:underline">
|
||||
Learn more →
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
|
||||
if (!p.href) return <div>{inner}</div>;
|
||||
const external = p.href.startsWith("http");
|
||||
return external ? (
|
||||
<a href={p.href} target="_blank" rel="noopener noreferrer" className="group block h-full">
|
||||
{inner}
|
||||
</a>
|
||||
) : (
|
||||
<Link href={p.href} className="group block h-full">
|
||||
{inner}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Button } from "@repo/ui/components/button";
|
||||
import Link from "next/link";
|
||||
|
||||
// Shared closing CTA for the services hub and every pillar subpage.
|
||||
export function ServicesCta({
|
||||
title = "Let's build together",
|
||||
blurb = "We take on a limited number of revenue-share build partners. Tell us what you're building and we'll run a scope review.",
|
||||
}: {
|
||||
title?: string;
|
||||
blurb?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="p-12 md:p-16 rounded-[2.5rem] bg-gradient-to-br from-slate-900 via-slate-800 to-indigo-950 text-white text-center shadow-2xl relative overflow-hidden group border-2 border-white/5">
|
||||
<div className="absolute inset-0 bg-blue-500/10 opacity-0 group-hover:opacity-100 transition-opacity" />
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-6 relative z-10 tracking-tight">{title}</h2>
|
||||
<p className="mb-10 text-slate-300 text-lg max-w-2xl mx-auto relative z-10 leading-relaxed font-medium">
|
||||
{blurb}
|
||||
</p>
|
||||
<Link href="/contact" className="relative z-10">
|
||||
<Button size="lg" variant="secondary" className="rounded-2xl px-12 py-8 text-xl font-bold hover:scale-105 transition-transform bg-white text-slate-900 hover:bg-slate-100">
|
||||
Request a Consultation
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user