Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/app/ai-builds/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { Metadata } from 'next';
import AiBuildWall from '@/features/HomePage/components/AiBuildWall';

export const metadata: Metadata = {
title: 'AI-Assisted Build Wall',
description: 'A showcase of shipped AI-assisted websites and products from J StaR Films Studios, including the AI model stacks and creative attributions behind each build.',
};

export default function AiBuildsPage() {
return <AiBuildWall />;
}
14 changes: 13 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,19 @@ export default async function RootLayout({
}: {
children: React.ReactNode;
}) {
const { user } = await withAuth();
let user = null;

try {
const auth = await withAuth();
user = auth.user;
} catch (error) {
if (typeof error === 'object' && error !== null && 'digest' in error && error.digest === 'DYNAMIC_SERVER_USAGE') {
throw error;
}

console.warn('[WorkOS] Auth is unavailable; rendering public layout without a signed-in user.', error);
}

const authButton = user ? <UserButton user={user} /> : <SignInButton />;

return (
Expand Down
2 changes: 2 additions & 0 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import HeroSection from "@/features/HomePage/components/HeroSection";
import AboutSection from "@/features/HomePage/components/AboutSection";
import ServicesSection from "@/features/HomePage/components/ServicesSection";
import PortfolioSection from "@/features/HomePage/components/PortfolioSection";
import AiBuildWall from "@/features/HomePage/components/AiBuildWall";
import ProcessSection from "@/features/HomePage/components/ProcessSection";
import PricingSection from "@/features/HomePage/components/PricingSection";
import TestimonialsSection from "@/features/HomePage/components/TestimonialsSection";
Expand All @@ -18,6 +19,7 @@ export default function HomePage() {
<AboutSection />
<ServicesSection />
<PortfolioSection />
<AiBuildWall compact />
<ProcessSection />
<PricingSection />
<TestimonialsSection />
Expand Down
2 changes: 2 additions & 0 deletions src/app/portfolio/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

import PortfolioHero from "@/features/PortfolioPage/components/PortfolioHero";
import AiBuildWall from "@/features/HomePage/components/AiBuildWall";
import PortfolioFilter from "@/features/PortfolioPage/components/PortfolioFilter";
import PortfolioGrid from "@/features/PortfolioPage/components/PortfolioGrid";
import PortfolioCta from "@/features/PortfolioPage/components/PortfolioCta";
Expand All @@ -8,6 +9,7 @@ export default function PortfolioPage() {
return (
<>
<PortfolioHero />
<AiBuildWall compact />
<PortfolioFilter />
<PortfolioGrid />
<PortfolioCta />
Expand Down
12 changes: 11 additions & 1 deletion src/components/auth/SignInButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,17 @@ export async function SignInButton() {

// Encode current URL in state parameter
const state = encodeURIComponent(currentUrl);
const signInUrl = await getSignInUrl({ state });
let signInUrl = '/auth/callback';

try {
signInUrl = await getSignInUrl({ state });
} catch (error) {
if (typeof error === 'object' && error !== null && 'digest' in error && error.digest === 'DYNAMIC_SERVER_USAGE') {
throw error;
}

console.warn('[WorkOS] Sign-in URL unavailable; auth is not configured for this environment.', error);
}

return (
<Link
Expand Down
1 change: 1 addition & 0 deletions src/components/layout/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const Footer = () => {
<li><Link href="/" className="text-gray-400 hover:text-white transition-colors">Home</Link></li>
<li><Link href="/services" className="text-gray-400 hover:text-white transition-colors">Services</Link></li>
<li><Link href="/portfolio" className="text-gray-400 hover:text-white transition-colors">Portfolio</Link></li>
<li><Link href="/ai-builds" className="text-gray-400 hover:text-white transition-colors">AI Build Wall</Link></li>
<li><Link href="/about" className="text-gray-400 hover:text-white transition-colors">About Us</Link></li>
<li><Link href="/contact" className="text-gray-400 hover:text-white transition-colors">Contact</Link></li>
</ul>
Expand Down
3 changes: 2 additions & 1 deletion src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { useState, useEffect, useCallback, useMemo } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { MenuIcon, CloseIcon, SunIcon, MoonIcon, UserIcon, VideoCameraIcon, FilmIcon, PenFancyIcon, GiftIcon, EnvelopeIcon } from '@/components/icons';
import { MenuIcon, CloseIcon, SunIcon, MoonIcon, UserIcon, VideoCameraIcon, FilmIcon, CodeIcon, PenFancyIcon, GiftIcon, EnvelopeIcon } from '@/components/icons';
import { useSmartNavigation } from '@/hooks/useSmartNavigation';
import Tooltip from '@/components/ui/Tooltip';

Expand Down Expand Up @@ -73,6 +73,7 @@ const Header: React.FC<HeaderProps> = ({ authButton }) => {
{ href: '/about', label: 'About', icon: UserIcon },
{ href: '/services', label: 'Services', icon: VideoCameraIcon },
{ href: '/portfolio', label: 'Portfolio', icon: FilmIcon },
{ href: '/ai-builds', label: 'AI Builds', icon: CodeIcon },
{ href: '/blog', label: 'Blog', icon: PenFancyIcon },
{ href: '/store', label: 'Store', icon: GiftIcon },
{ href: '/contact', label: 'Contact', icon: EnvelopeIcon }
Expand Down
76 changes: 76 additions & 0 deletions src/content/aiBuildWall.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
export interface AiAssistedBuildProject {
name: string;
url: string;
description: string;
stack: string[];
bannerAttribution: string;
logoAttribution?: string;
proofLine: string;
accent: string;
}

export const aiAssistedBuildProjects: AiAssistedBuildProject[] = [
{
name: 'J StaR Studios',
url: 'https://jstarstudios.com',
description: 'Flagship creative studio website for presenting John’s production, strategy, and technology work.',
stack: ['Gemini 3.0 Pro', 'Claude Opus 4.5'],
bannerAttribution: 'Banner by Gemini 3 Pro',
proofLine: 'Shows how AI can accelerate a premium studio presence without flattening the brand voice.',
accent: 'from-jstar-blue to-faith-purple',
},
{
name: 'For Your Business',
url: 'https://fyb.jstarstudios.com',
description: 'Business-facing web experience built to translate creative capability into clearer client action.',
stack: ['Gemini 3.0 Pro', 'Claude 4.5'],
bannerAttribution: 'Pure SVG banner by Gemini 3.0 Pro',
logoAttribution: 'Logo by Nano Banana',
proofLine: 'Proves fast iteration can still produce custom SVG craft and polished conversion framing.',
accent: 'from-growth-green to-jstar-blue',
},
{
name: 'KageOS',
url: 'https://kageos.jstarstudios.com',
description: 'A high-concept product site for an OS-style creative and technical experience.',
stack: ['Gemini 3.0 Pro', 'Kimi K2.5'],
bannerAttribution: 'Banner by Claude Opus 4.6 SVG and Nano Banana Pro',
proofLine: 'Shows multi-model art direction: one stack for structure, another for cinematic visual language.',
accent: 'from-faith-purple to-red-500',
},
{
name: 'KOE Voice',
url: 'https://www.koevoice.xyz',
description: 'Voice-oriented product website with a character-led identity and advanced AI-assisted build process.',
stack: ['GPT 5.3 Codex', 'GPT 5.4', 'Gemini 3.1 Pro', 'Claude Opus 4.6', 'GPT 5.5'],
bannerAttribution: 'Banner by GPT 5.5 High',
logoAttribution: 'Logo uses a real character',
proofLine: 'Demonstrates orchestration across frontier coding, copy, and visual-direction models.',
accent: 'from-cyan-400 to-faith-purple',
},
{
name: 'Melo School',
url: 'https://meloschool.com',
description: 'Education-focused website for music learning with a friendly product and enrollment feel.',
stack: ['GPT 5.4', 'Gemini 3.1 Flash', 'GPT 5.5 Low'],
bannerAttribution: 'Banner by GPT 5.5 High and GPT Image 2',
proofLine: 'Shows a lighter AI stack can ship a warm, accessible education brand quickly.',
accent: 'from-amber-400 to-growth-green',
},
{
name: 'Olive Vine Dental',
url: 'https://www.olivevinedental.com/',
description: 'Dental practice website with clear service positioning and search-friendly content support.',
stack: ['Gemini 3.5 Flash'],
bannerAttribution: 'Banner not done yet',
logoAttribution: 'SEO support by GPT 5.5',
proofLine: 'Proves a constrained, practical model stack can still move a real client site forward.',
accent: 'from-emerald-400 to-jstar-blue',
},
];

export const aiBuildWallStats = [
{ label: 'Live projects', value: '6' },
{ label: 'AI stacks documented', value: '6' },
{ label: 'Fake metrics', value: '0' },
];
114 changes: 114 additions & 0 deletions src/features/HomePage/components/AiBuildWall.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import Link from 'next/link';
import { aiAssistedBuildProjects, aiBuildWallStats } from '@/content/aiBuildWall';

interface AiBuildWallProps {
compact?: boolean;
}

const AiBuildWall = ({ compact = false }: AiBuildWallProps) => {
const visibleProjects = compact ? aiAssistedBuildProjects.slice(0, 3) : aiAssistedBuildProjects;

return (
<section
id="ai-builds-section"
className="relative overflow-hidden bg-gray-950 py-20 text-white"
aria-labelledby="ai-build-wall-heading"
>
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(59,130,246,0.28),transparent_32%),radial-gradient(circle_at_bottom_right,rgba(147,51,234,0.22),transparent_30%)]" />
<div className="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/30 to-transparent" />

<div className="relative z-10 mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="grid gap-10 lg:grid-cols-[0.9fr_1.1fr] lg:items-end">
<div>
<span className="mb-4 inline-flex rounded-full border border-white/10 bg-white/10 px-4 py-1.5 text-sm font-medium text-jstar-blue backdrop-blur">
AI-Assisted Build Wall
</span>
<h2 id="ai-build-wall-heading" className="text-3xl font-bold tracking-tight md:text-5xl">
AI-accelerated websites/products shipped fast — with the stack in plain sight.
</h2>
<p className="mt-5 max-w-2xl text-lg text-gray-300">
A public ledger of shipped sites where AI was used as a production partner: strategy,
code, SVG direction, image generation, SEO, and polish. Client-friendly on the surface;
builder-detail underneath.
</p>
</div>

<div className="grid grid-cols-3 gap-3 rounded-3xl border border-white/10 bg-white/[0.04] p-4 backdrop-blur">
{aiBuildWallStats.map((stat) => (
<div key={stat.label} className="rounded-2xl bg-black/25 p-4 text-center">
<div className="text-2xl font-bold text-white md:text-3xl">{stat.value}</div>
<div className="mt-1 text-xs uppercase tracking-[0.18em] text-gray-400">{stat.label}</div>
</div>
))}
</div>
</div>

<div className="mt-12 grid gap-6 md:grid-cols-2 xl:grid-cols-3">
{visibleProjects.map((project) => (
<article
key={project.url}
className="group relative flex h-full flex-col overflow-hidden rounded-3xl border border-white/10 bg-white/[0.055] p-6 shadow-2xl shadow-black/20 backdrop-blur transition-all duration-300 hover:-translate-y-1 hover:border-white/20 hover:bg-white/[0.075]"
>
<div className={`absolute inset-x-0 top-0 h-1 bg-gradient-to-r ${project.accent}`} />
<div className="mb-5 flex items-start justify-between gap-4">
<div>
<p className="text-xs font-semibold uppercase tracking-[0.22em] text-gray-400">Live build</p>
<h3 className="mt-2 text-2xl font-bold text-white">{project.name}</h3>
</div>
<a
href={project.url}
target="_blank"
rel="noopener noreferrer"
className="rounded-full border border-white/10 bg-black/30 px-3 py-1 text-xs font-semibold text-gray-200 transition-colors hover:border-jstar-blue/60 hover:text-white"
aria-label={`Open ${project.name}`}
>
Visit ↗
</a>
</div>

<p className="text-sm leading-6 text-gray-300">{project.description}</p>

<div className="mt-6">
<p className="mb-3 text-xs font-semibold uppercase tracking-[0.2em] text-jstar-blue">AI stack used</p>
<div className="flex flex-wrap gap-2">
{project.stack.map((model) => (
<span key={model} className="rounded-full bg-white/10 px-3 py-1 text-xs text-gray-200 ring-1 ring-white/10">
{model}
</span>
))}
</div>
</div>

<div className="mt-6 space-y-2 rounded-2xl border border-white/10 bg-black/25 p-4 text-sm text-gray-300">
<p><span className="font-semibold text-white">Banner:</span> {project.bannerAttribution}</p>
{project.logoAttribution && (
<p><span className="font-semibold text-white">Logo/detail:</span> {project.logoAttribution}</p>
)}
</div>

<div className="mt-6 border-t border-white/10 pt-5">
<p className="text-sm font-medium leading-6 text-white">
<span className="text-jstar-blue">What this proves:</span> {project.proofLine}
</p>
</div>
</article>
))}
</div>

{compact && (
<div className="mt-10 text-center">
<Link
href="/ai-builds"
className="inline-flex items-center rounded-full bg-gradient-to-r from-jstar-blue to-faith-purple px-7 py-3 font-semibold text-white shadow-lg shadow-jstar-blue/20 transition-all duration-300 hover:-translate-y-0.5 hover:shadow-xl"
>
View the full AI build wall
<span className="ml-2">→</span>
</Link>
</div>
)}
</div>
</section>
);
};

export default AiBuildWall;