Files
such.software/apps/web/src/app/layout.tsx
T
jwinterm 261cb04667 feat(site): one voice, brand gradients, a lighter splash gate, denser portfolio
- Voice unified on the title-tag register: the homepage h1 now says what we
  sell (Custom E-commerce, Apps & Crypto Tools); 'Precision engineering for
  everyone' is demoted to the supporting line. The structured-data and
  manifest descriptions now match the OG description instead of carrying
  their own registers.
- The off-palette cyan/blue gradients are gone: .hero-title and the new
  .brand-gradient-text use the four-colour system (light palette on light,
  dark palette on dark, per the pack). Splash cover text, services and
  portfolio headings, the hero aura, and button shadows all follow.
- The splash now dismisses once 40% scrolled past instead of requiring the
  whole screen to leave the viewport (it was already once-per-session and
  reduced-motion-skipping).
- Portfolio: heading 'Portfolio', subtitle 'Products & projects', meta title
  to match; grid grows to three columns on xl in a max-w-6xl container.
- anim3_matrix slimmed: single-layer glow, unfiltered crackle and orbs, and
  the border cycles stroke colour instead of animating filter:hue-rotate --
  the filter animation forced a full filter re-render per frame and pegged a
  core on the page hosting it.
2026-08-16 00:04:28 -04:00

132 lines
4.8 KiB
TypeScript

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { ThemeProvider } from "@/components/theme-provider";
import { DynamicFavicon } from "@/components/dynamic-favicon";
import { Footer } from "@/components/layout/footer";
import { UmamiAnalytics } from "@/components/UmamiAnalytics";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
metadataBase: new URL("https://such.software"),
title: "Custom E-Commerce, App & Crypto Development | Such Software",
description: "Such Software is a Kennett Square, PA studio building custom online stores, web apps, mobile games, and Monero & crypto tools. Start a project today.",
alternates: {
canonical: "/",
},
openGraph: {
title: "Such Software: Custom E-Commerce, Apps & Crypto Development",
description: "A Kennett Square, PA software studio building custom online stores, web apps, mobile games, and Monero & crypto tools.",
type: "website",
siteName: "Such Software",
images: [
{
url: "/images/branding/OG_banner_v2_light.png",
width: 1200,
height: 630,
alt: "Such Software",
},
],
},
twitter: {
card: "summary_large_image",
title: "Such Software: Custom E-Commerce, Apps & Crypto Development",
description: "A Kennett Square, PA software studio building custom online stores, web apps, mobile games, and Monero & crypto tools.",
images: ["/images/branding/OG_banner_v2_light.png"],
},
icons: {
// Favicons are served inverse to the browser chrome: dark chrome gets the
// light-tile file for contrast, light chrome gets the dark-tile file.
icon: [
{ url: "/images/branding/favicon_light.svg", type: "image/svg+xml", media: "(prefers-color-scheme: dark)" },
{ url: "/images/branding/favicon_dark.svg", type: "image/svg+xml", media: "(prefers-color-scheme: light)" },
{ url: "/images/branding/favicon_light.png", sizes: "192x192", type: "image/png", media: "(prefers-color-scheme: dark)" },
{ url: "/images/branding/favicon_dark.png", sizes: "192x192", type: "image/png", media: "(prefers-color-scheme: light)" },
],
shortcut: "/images/branding/favicon_light.svg",
apple: [
{ url: "/images/branding/favicon_light.png", sizes: "192x192", type: "image/png", media: "(prefers-color-scheme: dark)" },
{ url: "/images/branding/favicon_dark.png", sizes: "192x192", type: "image/png", media: "(prefers-color-scheme: light)" },
],
},
manifest: "/manifest.json",
};
const structuredData = {
"@context": "https://schema.org",
"@type": "Organization",
name: "Such Software LLC",
url: "https://such.software",
logo: "https://such.software/images/branding/icon-512.png",
description: "A Kennett Square, PA software studio building custom online stores, web apps, mobile games, and Monero & crypto tools.",
address: {
"@type": "PostalAddress",
streetAddress: "110 E State St, Suite 300",
addressLocality: "Kennett Square",
addressRegion: "PA",
postalCode: "19348",
addressCountry: "US",
},
founder: {
"@type": "Person",
name: "John Winter Murphy",
jobTitle: "Founder & Principal Engineer",
},
sameAs: [
"https://github.com/suchsoftware",
"https://www.linkedin.com/company/such-software",
"https://x.com/such_software",
"https://bsky.app/profile/suchsoftware.bsky.social",
"https://www.youtube.com/@SuchSoftware",
"https://www.instagram.com/such_software/",
"https://www.tiktok.com/@such.software",
"https://www.facebook.com/people/Such-Software/61572076196412/",
"https://www.pinterest.com/SuchSoftware/",
"https://t.me/SuchSoftware",
],
};
const websiteData = {
"@context": "https://schema.org",
"@type": "WebSite",
name: "Such Software",
url: "https://such.software",
publisher: { "@type": "Organization", name: "Such Software LLC" },
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en" suppressHydrationWarning>
<head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
/>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(websiteData) }}
/>
</head>
<body className={inter.className}>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
<DynamicFavicon />
<UmamiAnalytics />
<div className="relative z-10 flex flex-col min-h-screen">
{children}
<Footer />
</div>
</ThemeProvider>
</body>
</html>
);
}