Rework home hero and portfolio, invert favicon theme mapping

- Home hero subhead rewritten to name commerce/websites/apps/consulting
  plus in-house mobile apps and games; primary CTA points to /products
- Portfolio page (/products) title renamed and each product card now shows
  a 56px icon beside the title
- Favicon served inverse to the browser color scheme so the tile contrasts
  with the chrome instead of blending into it
This commit is contained in:
jwinterm
2026-04-20 13:04:27 -04:00
parent ae87efe77f
commit ca5f555918
6 changed files with 40 additions and 18 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 510 KiB

+2 -2
View File
@@ -8,12 +8,12 @@
"theme_color": "#000000",
"icons": [
{
"src": "/images/branding/favicon_dark.svg",
"src": "/images/branding/favicon_light.svg",
"type": "image/svg+xml",
"purpose": "any"
},
{
"src": "/images/branding/favicon_dark.png",
"src": "/images/branding/favicon_light.png",
"sizes": "192x192",
"type": "image/png"
}
+9 -7
View File
@@ -35,16 +35,18 @@ export const metadata: Metadata = {
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_dark.svg", type: "image/svg+xml", media: "(prefers-color-scheme: dark)" },
{ url: "/images/branding/favicon_light.svg", type: "image/svg+xml", media: "(prefers-color-scheme: light)" },
{ url: "/images/branding/favicon_dark.png", sizes: "192x192", type: "image/png", media: "(prefers-color-scheme: dark)" },
{ url: "/images/branding/favicon_light.png", sizes: "192x192", type: "image/png", media: "(prefers-color-scheme: light)" },
{ 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_dark.svg",
shortcut: "/images/branding/favicon_light.svg",
apple: [
{ url: "/images/branding/favicon_dark.png", sizes: "192x192", type: "image/png", media: "(prefers-color-scheme: dark)" },
{ url: "/images/branding/favicon_light.png", sizes: "192x192", type: "image/png", 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)" },
],
},
manifest: "/manifest.json",
+4 -4
View File
@@ -65,13 +65,13 @@ export default function Home() {
<span className="block">for Everyone</span>
</h1>
<p className="max-w-2xl text-xl text-muted-foreground mb-8">
E-commerce, mobile apps, and custom solutions: we build accessible software to perform at scale.
Custom e-commerce, websites, apps, and consulting. Plus our own mobile apps and games. A software studio in Kennett Square, PA.
</p>
<div className="flex gap-4 mb-10">
<Link href="/services">
<Link href="/products">
<Button size="lg" className="rounded-full">
Explore Services
View Portfolio
</Button>
</Link>
<Link href="#contact">
+22 -4
View File
@@ -1,6 +1,7 @@
import { Header } from "@/components/layout/header";
import { MobileNav } from "@/components/layout/mobile-nav";
import { Card } from "@repo/ui/components/card";
import Image from "next/image";
import Link from "next/link";
import type { Metadata } from "next";
@@ -21,48 +22,56 @@ const products = [
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",
},
{
slug: "webshops",
title: "Webshops",
description: "Headless Medusa commerce with revenue-share pricing. No upfront costs.",
color: "emerald",
icon: "/images/products/occupy-wallets.png",
},
{
slug: "custom-websites",
title: "Custom Websites",
description: "Real-time platforms and interactive experiences. See rcryptocurrency.com and moonplace.io.",
color: "purple",
icon: "/images/products/r-cryptocurrency.png",
},
{
slug: "smirk-wallet",
title: "Smirk Wallet",
description: "Non-custodial browser wallet for social tipping. BTC, LTC, XMR, WOW, GRIN.",
color: "amber",
icon: "/images/products/smirk-wallet.png",
},
{
slug: "bauhaus-echo",
title: "Bauhaus Echo",
description: "Visual memory puzzle game inspired by Bauhaus design. Android, iOS, Web.",
color: "blue",
icon: "/images/products/bauhaus-echo.png",
},
{
slug: "suchoice",
title: "Suchoice",
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",
},
{
slug: "vegan-iq",
title: "Vegan IQ",
description: "Test your plant-based knowledge with 2000+ trivia questions across 8 categories. Verified data, swipe gameplay. Android and iOS.",
color: "green",
icon: "/images/products/vegan-iq.png",
},
{
slug: "wownero-moon-launch",
title: "Wownero Moon Launch",
description: "Crypto-themed space landing game. 11 levels, 4 weapons, endless mode. Android, iOS, Web, Desktop.",
color: "orange",
icon: "/images/products/such-moon-launch.png",
},
];
@@ -95,7 +104,7 @@ export default function ProductsPage() {
<div id="main-content" className="z-10 w-full max-w-5xl mx-auto py-20 px-4 pb-24 md:pb-20">
<div className="text-center mb-16">
<h1 className="text-4xl md:text-6xl font-bold mb-6 bg-clip-text text-transparent bg-gradient-to-r from-amber-400 to-purple-500">
Our Products
Portfolio
</h1>
<p className="text-xl text-muted-foreground max-w-2xl mx-auto">
Tools we have built, from commerce infrastructure to consumer apps.
@@ -106,9 +115,18 @@ export default function ProductsPage() {
{products.map((product) => (
<Link key={product.slug} href={`/products/${product.slug}`}>
<Card className={`glass-card h-full min-h-[200px] ${colorClasses[product.color]} transition-all cursor-pointer`}>
<h2 className={`text-2xl font-bold mb-3 ${titleColors[product.color]}`}>
{product.title}
</h2>
<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>
+3 -1
View File
@@ -9,7 +9,9 @@ export function DynamicFavicon() {
useEffect(() => {
if (!resolvedTheme) return;
const variant = resolvedTheme === 'dark' ? 'dark' : 'light';
// Favicons contrast with browser chrome, so we serve the opposite-tone tile:
// dark mode → light tile, light mode → dark tile.
const variant = resolvedTheme === 'dark' ? 'light' : 'dark';
// Update all favicon link elements
const links = document.querySelectorAll<HTMLLinkElement>('link[rel="icon"], link[rel="shortcut icon"], link[rel="apple-touch-icon"]');