Fix critical accessibility and SEO issues

- Fix homepage heading hierarchy (h2 -> h1)
- Add page-specific metadata to services and about pages
- Fix outline-none on form inputs for keyboard accessibility
- Delete sync conflict files
- Add group class back to bento cards for hover animations
- Use raw CSS for glassmorphism to fix Tailwind opacity errors
- Add TODO.md with production checklist
- Add semantic CSS classes (.section-container, .glass-card)
- Update Tailwind config for opacity modifier support
This commit is contained in:
jwinterm
2026-01-16 15:03:12 -05:00
parent b40193c086
commit ffaea03e58
24 changed files with 485 additions and 4566 deletions
+18 -6
View File
@@ -1,17 +1,29 @@
import { DynamicBackground } from "@/components/landing/dynamic-background";
import { ThemeToggle } from "@/components/theme-toggle";
import { FounderSignature } from "@/components/about/founder-signature";
import { SiteLogo } from "@/components/layout/site-logo";
import Link from "next/link";
import { FaMapMarkerAlt, FaPhone, FaBuilding, FaExternalLinkAlt } from "react-icons/fa";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "About | Such Software",
description: "Full-service software provider in Kennett Square, PA. Founded by John Winter Murphy, specializing in accessible web engineering and WCAG 2.2 compliance.",
openGraph: {
title: "About | Such Software",
description: "Full-service software provider in Kennett Square, PA. Founded by John Winter Murphy.",
type: "website",
},
};
export default function AboutPage() {
return (
<main className="relative flex flex-col items-center overflow-hidden">
<header className="z-50 w-full max-w-7xl mx-auto flex justify-between items-center p-6 bg-background/50 backdrop-blur-sm sticky top-0">
<div className="flex items-center gap-6">
<Link href="/" className="text-2xl font-bold tracking-tighter">Such Software</Link>
<nav className="hidden md:flex gap-4 text-sm font-medium">
<header className="z-50 w-full max-w-7xl mx-auto flex justify-between items-center p-6 bg-background/50 backdrop-blur-3xl sticky top-0 rounded-b-3xl border-b border-border/50">
<div className="flex items-center gap-8">
<SiteLogo />
<nav className="hidden md:flex gap-6 text-sm font-medium">
<Link href="/services" className="hover:text-primary transition-colors">Services</Link>
<Link href="/about" className="text-primary transition-colors">About</Link>
</nav>
@@ -19,10 +31,10 @@ export default function AboutPage() {
<ThemeToggle />
</header>
<div className="z-10 w-full max-w-4xl mx-auto py-20 px-4">
<div className="z-10 w-full max-w-6xl mx-auto py-20 px-4">
<h1 className="text-4xl md:text-5xl font-bold mb-10 text-center">About Us</h1>
<div className="bg-card/80 backdrop-blur-md rounded-2xl p-8 md:p-12 shadow-xl border border-border/50">
<div className="section-container">
<div className="prose dark:prose-invert max-w-none mb-12">
<p className="text-xl leading-relaxed">
+27 -1
View File
@@ -73,4 +73,30 @@
body {
@apply bg-background text-foreground;
}
}
}
@layer components {
/* High-contrast content masking for accessibility and streamer protection */
.mask-backdrop {
background-color: hsl(var(--card) / 0.98);
backdrop-filter: blur(64px);
-webkit-backdrop-filter: blur(64px);
border-width: 2px;
border-color: hsl(var(--border) / 0.5);
box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
position: relative;
overflow: hidden;
transition: all 300ms;
}
.section-container {
@apply mask-backdrop rounded-[2.5rem] p-10 md:p-16 text-card-foreground;
}
.glass-card {
@apply mask-backdrop rounded-[2rem] p-8 text-card-foreground;
}
.glass-card:hover {
border-color: hsl(var(--primary) / 0.3);
}
}
+14 -1
View File
@@ -7,7 +7,20 @@ import { DynamicBackground } from "@/components/landing/dynamic-background";
const inter = Inter({ subsets: ["latin"] });
// ... (metadata omitted)
export const metadata: Metadata = {
title: "Such Software | Digital Craftsmanship",
description: "Next-generation web applications engineered for scale, compliance, and performance.",
icons: {
icon: [
{ url: "/images/favicon_192.png", sizes: "192x192", type: "image/png" },
],
shortcut: "/images/favicon_192.png",
apple: [
{ url: "/images/favicon_192.png", sizes: "192x192", type: "image/png" },
],
},
manifest: "/manifest.json",
};
export default function RootLayout({
children,
+19 -39
View File
@@ -4,6 +4,7 @@ import { PortfolioGrid } from "@/components/portfolio/bento-grid";
import { ContactForm } from "@/components/contact/contact-form";
import { FounderSignature } from "@/components/about/founder-signature";
import { ServicesPreview } from "@/components/landing/services-preview";
import { SiteLogo } from "@/components/layout/site-logo";
import Link from "next/link";
import { Button } from "@repo/ui/components/button";
import { Card } from "@repo/ui/components/card";
@@ -12,10 +13,10 @@ export default function Home() {
return (
<main className="relative flex flex-col items-center justify-between overflow-hidden">
<header className="z-50 w-full max-w-7xl mx-auto flex justify-between items-center p-6 pb-2">
<div className="flex items-center gap-6">
<h1 className="text-2xl font-bold tracking-tighter">Such Software</h1>
<nav className="hidden md:flex gap-4 text-sm font-medium">
<header className="z-50 w-full max-w-7xl mx-auto flex justify-between items-center p-6 bg-background/50 backdrop-blur-3xl sticky top-0 rounded-b-3xl border-b border-border/50">
<div className="flex items-center gap-8">
<SiteLogo />
<nav className="hidden md:flex gap-6 text-sm font-medium">
<Link href="/services" className="hover:text-primary transition-colors">Services</Link>
<Link href="/about" className="hover:text-primary transition-colors">About</Link>
</nav>
@@ -24,9 +25,9 @@ export default function Home() {
</header>
<div className="z-10 w-full max-w-7xl mx-auto flex flex-col items-center pt-20 pb-10 px-4 text-center">
<h2 className="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">
<h1 className="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">
Digital Craftsmanship
</h2>
</h1>
<p className="max-w-2xl text-xl text-muted-foreground mb-8">
Next-generation web applications engineered for scale, compliance, and performance.
</p>
@@ -47,9 +48,9 @@ export default function Home() {
<ServicesPreview />
<div className="w-full max-w-6xl mx-auto mb-16 px-4">
<div className="text-left mb-8 px-2 border-l-2 border-blue-500/50 pl-6">
<h3 className="text-2xl font-bold mb-2">Selected Works</h3>
<p className="text-muted-foreground text-lg max-w-3xl">
<div className="text-left mb-8 px-2 border-l-2 border-blue-500/50 section-container">
<h3 className="text-3xl font-bold mb-3 tracking-tight text-foreground">Selected Works</h3>
<p className="text-muted-foreground text-lg max-w-3xl leading-relaxed">
A curated gallery of recent projects where we've pushed the boundaries of
performance, accessibility, and user experience.
</p>
@@ -57,42 +58,21 @@ export default function Home() {
<PortfolioGrid />
</div>
<div className="w-full max-w-6xl mx-auto mb-16 px-4">
<div className="text-left mb-8 px-2 border-l-2 border-purple-500/50 pl-6">
<h3 className="text-2xl font-bold mb-2">Inclusive by Design</h3>
<p className="text-muted-foreground text-lg max-w-3xl">
<div className="w-full max-w-6xl mx-auto mb-20 px-4">
<div className="text-left mb-12 px-2 border-l-2 border-purple-500/50 section-container">
<h3 className="text-3xl font-bold mb-3 tracking-tight text-foreground">Inclusive by Design</h3>
<p className="text-muted-foreground text-lg max-w-3xl leading-relaxed">
We believe the web is for everyone. Every line of code we write is
audited for WCAG 2.1 compliance and high-performance across all devices.
audited for WCAG 2.2 compliance and high-performance across all devices.
</p>
</div>
<div className="grid md:grid-cols-2 gap-8">
<Card className="p-8 bg-card/50 backdrop-blur-sm border-purple-500/10 hover:border-purple-500/30 transition-all group">
<h4 className="text-xl font-bold mb-4 flex items-center gap-2">
<span className="w-8 h-8 rounded-full bg-purple-500/10 flex items-center justify-center text-purple-500 text-sm">01</span>
A11y First Architecture
</h4>
<p className="text-muted-foreground text-sm">
Semantic HTML, ARIA patterns, and keyboard navigation aren't afterthoughts—they are the foundation of our build process.
</p>
</Card>
<Card className="p-8 bg-card/50 backdrop-blur-sm border-blue-500/10 hover:border-blue-500/30 transition-all group">
<h4 className="text-xl font-bold mb-4 flex items-center gap-2">
<span className="w-8 h-8 rounded-full bg-blue-500/10 flex items-center justify-center text-blue-500 text-sm">02</span>
Edge Performance
</h4>
<p className="text-muted-foreground text-sm">
By leveraging edge computing and static generation, we ensure your site is usable even on 3G connections and older hardware.
</p>
</Card>
</div>
<FounderSignature />
</div>
<FounderSignature />
<div id="contact" className="w-full mt-20 mb-20 flex flex-col items-center">
<div className="w-full max-w-6xl text-left mb-12 px-2 border-l-2 border-emerald-500/50 pl-6">
<h3 className="text-2xl font-bold mb-2">Start a Project</h3>
<p className="text-muted-foreground text-lg max-w-3xl">
<div className="w-full max-w-6xl text-left mb-12 px-2 border-l-2 border-emerald-500/50 section-container">
<h3 className="text-3xl font-bold mb-3 tracking-tight text-foreground">Start a Project</h3>
<p className="text-muted-foreground text-lg max-w-3xl leading-relaxed">
Ready to build something exceptional? Drop us a line and let's discuss
how we can help you scale your digital presence.
</p>
+49 -37
View File
@@ -1,8 +1,20 @@
import { DataGrid } from "@repo/ui/procedural/data-grid";
import { ThemeToggle } from "@/components/theme-toggle";
import { Button } from "@repo/ui/components/button";
import { SiteLogo } from "@/components/layout/site-logo";
import Link from "next/link";
import { Card } from "@repo/ui/components/card";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Services | Such Software",
description: "Medusa v2 development, custom web applications, and cryptocurrency consulting. High-performance headless commerce, real-time platforms, and Web3 integration.",
openGraph: {
title: "Services | Such Software",
description: "Medusa v2 development, custom web applications, and cryptocurrency consulting.",
type: "website",
},
};
export default function ServicesPage() {
return (
@@ -11,10 +23,10 @@ export default function ServicesPage() {
{/* Option B: Data Grid Background for Technical Feel */}
<DataGrid />
<header className="z-50 w-full max-w-7xl mx-auto flex justify-between items-center p-6 bg-background/50 backdrop-blur-sm sticky top-0">
<div className="flex items-center gap-6">
<Link href="/" className="text-2xl font-bold tracking-tighter">Such Software</Link>
<nav className="hidden md:flex gap-4 text-sm font-medium">
<header className="z-50 w-full max-w-7xl mx-auto flex justify-between items-center p-6 bg-background/50 backdrop-blur-3xl sticky top-0 border-b border-border/50 rounded-b-3xl">
<div className="flex items-center gap-8">
<SiteLogo />
<nav className="hidden md:flex gap-6 text-sm font-medium">
<Link href="/services" className="text-primary transition-colors">Services</Link>
<Link href="/about" className="hover:text-primary transition-colors">About</Link>
</nav>
@@ -25,7 +37,7 @@ export default function ServicesPage() {
<div className="z-10 w-full max-w-5xl mx-auto py-20 px-4">
{/* Context Header */}
<div className="mb-20">
<div className="text-left mb-8 px-2 border-l-2 border-emerald-500/50 pl-6">
<div className="text-left mb-8 px-2 border-l-2 border-emerald-500/50 section-container">
<h1 className="text-4xl md:text-6xl font-bold mb-6 bg-clip-text text-transparent bg-gradient-to-r from-emerald-400 to-blue-500">
Specialized Solutions
</h1>
@@ -39,7 +51,7 @@ export default function ServicesPage() {
{/* Medusa / Webshops Section */}
<div className="mb-24">
<div className="text-left mb-8 px-2 border-l-2 border-blue-500/50 pl-6">
<div className="text-left mb-8 px-2 border-l-2 border-blue-500/50 section-container mb-10">
<h2 className="text-3xl font-bold mb-2">Medusa v2 Development</h2>
<p className="text-muted-foreground text-lg max-w-3xl">
We build proprietary, headless commerce engines that scale with your business logic.
@@ -48,23 +60,23 @@ export default function ServicesPage() {
</div>
<div className="grid md:grid-cols-3 gap-6">
<Card className="p-6 bg-card/80 backdrop-blur-sm border-indigo-500/10 hover:border-indigo-500/30 transition-all">
<h3 className="text-xl font-bold mb-2">Unlimited Data Modeling</h3>
<p className="text-sm text-muted-foreground">
<Card className="glass-card hover:border-indigo-500/30">
<h3 className="text-xl font-bold mb-3">Unlimited Data Modeling</h3>
<p className="text-base text-muted-foreground leading-relaxed">
Natively model complex entities like "DNA Sequences" or "Royalty Logic"
directly in the database without hacky metadata.
</p>
</Card>
<Card className="p-6 bg-card/80 backdrop-blur-sm border-indigo-500/10 hover:border-indigo-500/30 transition-all">
<h3 className="text-xl font-bold mb-2">Zero Capital Upfront</h3>
<p className="text-sm text-muted-foreground">
<Card className="glass-card hover:border-indigo-500/30">
<h3 className="text-xl font-bold mb-3">Zero Capital Upfront</h3>
<p className="text-base text-muted-foreground leading-relaxed">
Our "Toast" style partnership means we win when you win. Low friction onboarding
with performance-based incentives.
</p>
</Card>
<Card className="p-6 bg-card/80 backdrop-blur-sm border-indigo-500/10 hover:border-indigo-500/30 transition-all">
<h3 className="text-xl font-bold mb-2">Headless SEO</h3>
<p className="text-sm text-muted-foreground">
<Card className="glass-card hover:border-indigo-500/30">
<h3 className="text-xl font-bold mb-3">Headless SEO</h3>
<p className="text-base text-muted-foreground leading-relaxed">
Custom Next.js frontends engineered for perfect lighthouse scores and
superior organic search conversion.
</p>
@@ -74,24 +86,24 @@ export default function ServicesPage() {
{/* Custom Apps Section */}
<div className="mb-24">
<div className="text-left mb-8 px-2 border-l-2 border-purple-500/50 pl-6">
<div className="text-left mb-8 px-2 border-l-2 border-purple-500/50 section-container mb-10">
<h2 className="text-3xl font-bold mb-2">Custom Apps & Interactive Websites</h2>
<p className="text-muted-foreground text-lg max-w-2xl">
<p className="text-muted-foreground text-lg max-w-2xl leading-relaxed">
Whether it's a real-time collaborative tool or a high-end brand experience,
we build performant web applications that delight users.
</p>
</div>
<div className="grid md:grid-cols-2 gap-6">
<Card className="p-6 bg-card/80 backdrop-blur-sm border-purple-500/10 hover:border-purple-500/30 transition-all">
<h3 className="text-xl font-bold mb-2">Real-time Platforms</h3>
<p className="text-sm text-muted-foreground">
<Card className="glass-card hover:border-purple-500/30">
<h3 className="text-xl font-bold mb-3">Real-time Platforms</h3>
<p className="text-base text-muted-foreground leading-relaxed">
Socket.io and WebRTC integration for collaborative tools, dashboards,
and live data visualization.
</p>
</Card>
<Card className="p-6 bg-card/80 backdrop-blur-sm border-purple-500/10 hover:border-purple-500/30 transition-all">
<h3 className="text-xl font-bold mb-2">Brand Motion</h3>
<p className="text-sm text-muted-foreground">
<Card className="glass-card hover:border-purple-500/30">
<h3 className="text-xl font-bold mb-3">Brand Motion</h3>
<p className="text-base text-muted-foreground leading-relaxed">
Framermotion and Three.js powered interfaces that tell your brand's story
through motion and depth.
</p>
@@ -101,24 +113,24 @@ export default function ServicesPage() {
{/* Crypto Section */}
<div className="mb-24">
<div className="text-left mb-8 px-2 border-l-2 border-cyan-500/50 pl-6">
<div className="text-left mb-8 px-2 border-l-2 border-cyan-500/50 section-container mb-10">
<h2 className="text-3xl font-bold mb-2">Cryptocurrency & Payment Consulting</h2>
<p className="text-muted-foreground text-lg max-w-2xl">
<p className="text-muted-foreground text-lg max-w-2xl leading-relaxed">
Navigate the complex world of global finance. We bridge the gap between
traditional banking and decentralized protocols.
</p>
</div>
<div className="grid md:grid-cols-2 gap-6">
<Card className="p-6 bg-card/80 backdrop-blur-sm border-cyan-500/10 hover:border-cyan-500/30 transition-all">
<h3 className="text-xl font-bold mb-2">Payment Orchestration</h3>
<p className="text-sm text-muted-foreground">
<Card className="glass-card hover:border-cyan-500/30">
<h3 className="text-xl font-bold mb-3">Payment Orchestration</h3>
<p className="text-base text-muted-foreground leading-relaxed">
Multi-PSP routing, automated reconciliation, and fraud prevention for
high-volume merchants.
</p>
</Card>
<Card className="p-6 bg-card/80 backdrop-blur-sm border-cyan-500/10 hover:border-cyan-500/30 transition-all">
<h3 className="text-xl font-bold mb-2">Web3 Integration</h3>
<p className="text-sm text-muted-foreground">
<Card className="glass-card hover:border-cyan-500/30">
<h3 className="text-xl font-bold mb-3">Web3 Integration</h3>
<p className="text-base text-muted-foreground leading-relaxed">
Non-custodial wallet auth, on/off ramp solutions, and smart contract
interactions for modern dApps.
</p>
@@ -126,16 +138,16 @@ export default function ServicesPage() {
</div>
</div>
<div className="mt-20 p-12 rounded-2xl bg-gradient-to-br from-slate-900 via-slate-800 to-indigo-950 text-white text-center shadow-2xl relative overflow-hidden group">
<div className="absolute inset-0 bg-blue-500/5 opacity-0 group-hover:opacity-100 transition-opacity" />
<h2 className="text-3xl font-bold mb-4 relative z-10">Start building the future</h2>
<p className="mb-8 text-slate-300 max-w-xl mx-auto relative z-10">
<div className="mt-20 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-4xl font-bold mb-6 relative z-10 tracking-tight">Start building the future</h2>
<p className="mb-10 text-slate-300 text-lg max-w-2xl mx-auto relative z-10 leading-relaxed font-medium">
We are currently accepting a limited number of partners for performance-based development.
Let's see if we're a fit.
</p>
<Link href="/#contact" className="relative z-10">
<Button size="lg" variant="secondary" className="rounded-full px-12 py-6 text-lg hover:scale-105 transition-transform">
Request a Demo
<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>