diff --git a/src/context/ThemeContext.jsx b/src/context/ThemeContext.jsx
index d1e4511..ba0d733 100644
--- a/src/context/ThemeContext.jsx
+++ b/src/context/ThemeContext.jsx
@@ -29,6 +29,10 @@ const themeRegistry = {
Home: React.lazy(() => import('../themes/corporate/Home')),
Layout: React.lazy(() => import('../themes/corporate/Layout')),
},
+ claude: {
+ Home: React.lazy(() => import('../themes/claude/Home')),
+ Layout: React.lazy(() => import('../themes/claude/Layout')),
+ },
};
// Full-screen loading spinner shown while site info is being fetched
diff --git a/src/themes/claude/Home.jsx b/src/themes/claude/Home.jsx
new file mode 100644
index 0000000..ae2de0f
--- /dev/null
+++ b/src/themes/claude/Home.jsx
@@ -0,0 +1,289 @@
+import React, { useState, useEffect } from 'react';
+import { Link } from 'react-router-dom';
+import { useTranslation } from 'react-i18next';
+import { useAuth } from '../../context/AuthContext';
+import { useSite } from '../../context/SiteContext';
+import { getSiteModels, getSitePackages } from '../../api';
+import CountUp from '../../components/bits/CountUp';
+import FadeContent from '../../components/bits/FadeContent';
+import GradientText from '../../components/bits/GradientText';
+import BlurText from '../../components/bits/BlurText';
+import ShinyText from '../../components/bits/ShinyText';
+import SpotlightCard from '../../components/bits/SpotlightCard';
+import StarBorder from '../../components/bits/StarBorder';
+
+export default function ClaudeHome() {
+ const { t } = useTranslation();
+ const { user } = useAuth();
+ const { site } = useSite();
+ const [models, setModels] = useState([]);
+ const [packages, setPackages] = useState([]);
+
+ useEffect(() => {
+ getSiteModels().then(r => { if (r.data.success) setModels(r.data.data || []); }).catch(() => {});
+ getSitePackages().then(r => { if (r.data.success) setPackages(r.data.data || []); }).catch(() => {});
+ }, []);
+
+ const enabledModels = models.filter(m => m.enabled !== false);
+
+ return (
+
+ {/* Hero */}
+
+ {/* Warm gradient background */}
+
+
+
+
+
+
+
+ {/* Badge */}
+
+
+
+
+
+ {/* Title */}
+
+
+ {site?.name || t('home.defaultHeroTitle')}
+
+
+
+ {/* Subtitle */}
+
+
+
+
+ {/* CTA Buttons */}
+
+ {user ? (
+
+
+ {t('home.goToDashboard')} →
+
+
+ ) : (
+ <>
+
+ {t('home.getStarted')} →
+
+
+ {t('home.viewPricing')}
+
+ >
+ )}
+
+
+
+
+ {/* Stats */}
+
+
+
+
+ +
+
+
{t('home.aiModels')}
+
+
+
+ %
+
+
{t('home.uptime')}
+
+
+
+ <ms
+
+
{t('home.latency')}
+
+
+
+
+
+
+ {/* Features */}
+
+
+
+
+
{t('home.whyChooseUs')}
+
{t('home.whyChooseUsDesc')}
+
+
+
+
+
+
+
{t('home.lightningFast')}
+
{t('home.lightningFastDesc')}
+
+
+
+
+
+
+
{t('home.securePrivate')}
+
{t('home.securePrivateDesc')}
+
+
+
+
+
+
+
{t('home.payAsYouGo')}
+
{t('home.payAsYouGoDesc')}
+
+
+
+
+
+
+
+ {/* Models */}
+ {enabledModels.length > 0 && (
+
+
+
+
{t('home.availableModels')}
+
{t('home.availableModelsDesc', { count: enabledModels.length })}
+
+
+
+ {enabledModels.slice(0, 12).map((m, i) => (
+
+
+
+ {m.display_name || m.model_name}
+
+
+ ))}
+
+
+ {enabledModels.length > 12 && (
+
+
+ {t('home.viewAllModels', { count: enabledModels.length })} →
+
+
+ )}
+
+
+ )}
+
+ {/* Packages */}
+ {packages.length > 0 && (
+
+
+
+
+
{t('home.plansPackages')}
+
{t('home.choosePlan')}
+
+
+
+ {packages.filter(p => p.enabled).slice(0, 3).map((pkg, i) => (
+
+
+ {i === 1 && (
+
+
+ Popular
+
+ )}
+
{pkg.name}
+ {pkg.description &&
{pkg.description}
}
+
+
+ ${pkg.price}
+ {pkg.original_price > pkg.price && (
+ ${pkg.original_price}
+ )}
+
+ {pkg.duration > 0 &&
{t('home.days', { count: pkg.duration })}
}
+
+
+ {user ? t('home.subscribe') : t('home.getStarted')}
+
+
+
+ ))}
+
+
+
+
+ )}
+
+ {/* CTA */}
+
+
+
+ {/* Decorative elements */}
+
+
+
+
+
{t('home.readyToStart')}
+
{t('home.readyToStartDesc')}
+
+ {user ? (
+
+ {t('home.goToDashboard')}
+
+ ) : (
+ <>
+
+ {t('home.createFreeAccount')}
+
+
+ {t('home.signIn')}
+
+ >
+ )}
+
+
+
+
+
+
+ );
+}
diff --git a/src/themes/claude/Layout.jsx b/src/themes/claude/Layout.jsx
new file mode 100644
index 0000000..c19ac95
--- /dev/null
+++ b/src/themes/claude/Layout.jsx
@@ -0,0 +1,148 @@
+import React, { useState } from 'react';
+import { Outlet, Link, useNavigate, useLocation } from 'react-router-dom';
+import { useTranslation } from 'react-i18next';
+import { useAuth } from '../../context/AuthContext';
+import { useSite } from '../../context/SiteContext';
+import LanguageSwitch from '../../components/LanguageSwitch';
+
+export default function ClaudeLayout() {
+ const { t } = useTranslation();
+ const { user, logout } = useAuth();
+ const { site } = useSite();
+ const navigate = useNavigate();
+ const location = useLocation();
+ const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
+
+ const siteName = site?.name || 'AI Platform';
+
+ const navItems = [
+ { to: '/', label: t('nav.home'), auth: false },
+ { to: '/pricing', label: t('nav.pricing'), auth: false },
+ { to: '/packages', label: t('nav.packages'), auth: false },
+ { to: '/dashboard', label: t('nav.dashboard'), auth: true },
+ { to: '/tokens', label: t('nav.apiKeys'), auth: true },
+ ...(site?.enable_topup ? [{ to: '/topup', label: t('nav.topup'), auth: true }] : []),
+ ];
+
+ const visibleNavItems = navItems.filter((n) => !n.auth || user);
+
+ return (
+
+ {/* Announcement */}
+ {site?.announcement && (
+
+ )}
+
+ {/* Header */}
+
+
+
+ {site?.logo ? (
+

+ ) : (
+
+ {siteName.charAt(0)}
+
+ )}
+
+ {siteName}
+
+
+
+
+
+
+
+
+ {user ? (
+
+ {user.display_name || user.username}
+
+
+ ) : (
+ <>
+
+ {t('nav.login')}
+
+
+ {t('nav.signUp')}
+
+ >
+ )}
+
+
+
+
+
+ {mobileMenuOpen && (
+
+
+
+ )}
+
+
+
+
+
+
+ );
+}
diff --git a/src/themes/clean/Home.jsx b/src/themes/clean/Home.jsx
index 52c6933..5ffcaa6 100644
--- a/src/themes/clean/Home.jsx
+++ b/src/themes/clean/Home.jsx
@@ -6,6 +6,10 @@ import { useSite } from '../../context/SiteContext';
import { getSiteModels, getSitePackages } from '../../api';
import CountUp from '../../components/bits/CountUp';
import FadeContent from '../../components/bits/FadeContent';
+import ShinyText from '../../components/bits/ShinyText';
+import BlurText from '../../components/bits/BlurText';
+import SpotlightCard from '../../components/bits/SpotlightCard';
+import StarBorder from '../../components/bits/StarBorder';
export default function CleanHome() {
const { t } = useTranslation();
@@ -28,12 +32,23 @@ export default function CleanHome() {
-
- {t('home.lightningFast')}
+
+
- {site?.name || t('home.defaultHeroTitle')}
+
@@ -42,8 +57,10 @@ export default function CleanHome() {
{user ? (
-
- {t('home.goToDashboard')} →
+
+
+ {t('home.goToDashboard')} →
+
) : (
<>
@@ -94,35 +111,41 @@ export default function CleanHome() {
-
-
-
+
+
+
+
{t('home.lightningFast')}
+
{t('home.lightningFastDesc')}
- {t('home.lightningFast')}
- {t('home.lightningFastDesc')}
-
+
-
-
-
+
+
+
+
{t('home.securePrivate')}
+
{t('home.securePrivateDesc')}
- {t('home.securePrivate')}
- {t('home.securePrivateDesc')}
-
+
-
-
-
+
+
+
+
{t('home.payAsYouGo')}
+
{t('home.payAsYouGoDesc')}
- {t('home.payAsYouGo')}
- {t('home.payAsYouGoDesc')}
-
+
@@ -171,29 +194,35 @@ export default function CleanHome() {
{packages.filter(p => p.enabled).slice(0, 3).map((pkg, i) => (
-
- {i === 1 &&
Popular}
-
{pkg.name}
- {pkg.description &&
{pkg.description}
}
-
-
-
${pkg.price}
- {pkg.original_price > pkg.price && (
-
${pkg.original_price}
- )}
+
+
+ {i === 1 &&
Popular}
+
{pkg.name}
+ {pkg.description &&
{pkg.description}
}
+
+
+ ${pkg.price}
+ {pkg.original_price > pkg.price && (
+ ${pkg.original_price}
+ )}
+
+ {pkg.duration > 0 &&
{t('home.days', { count: pkg.duration })}
}
- {pkg.duration > 0 &&
{t('home.days', { count: pkg.duration })}
}
+
+ {user ? t('home.subscribe') : t('home.getStarted')}
+
-
- {user ? t('home.subscribe') : t('home.getStarted')}
-
-
+
))}
diff --git a/src/themes/corporate/Home.jsx b/src/themes/corporate/Home.jsx
index 75afe86..cef7023 100644
--- a/src/themes/corporate/Home.jsx
+++ b/src/themes/corporate/Home.jsx
@@ -6,6 +6,9 @@ import { useSite } from '../../context/SiteContext';
import { getSiteModels, getSitePackages } from '../../api';
import CountUp from '../../components/bits/CountUp';
import FadeContent from '../../components/bits/FadeContent';
+import GradientText from '../../components/bits/GradientText';
+import SpotlightCard from '../../components/bits/SpotlightCard';
+import ShinyText from '../../components/bits/ShinyText';
export default function CorporateHome() {
const { t } = useTranslation();
@@ -32,11 +35,23 @@ export default function CorporateHome() {
- {t('home.lightningFast')}
+
-
- {site?.name || t('home.defaultHeroTitle')}
+
+
+ {site?.name || t('home.defaultHeroTitle')}
+
@@ -100,35 +115,41 @@ export default function CorporateHome() {
-
-
-
+
+
+
+
{t('home.lightningFast')}
+
{t('home.lightningFastDesc')}
- {t('home.lightningFast')}
- {t('home.lightningFastDesc')}
-
+
-
-
-
+
+
+
+
{t('home.securePrivate')}
+
{t('home.securePrivateDesc')}
- {t('home.securePrivate')}
- {t('home.securePrivateDesc')}
-
+
-
-
-
+
+
+
+
{t('home.payAsYouGo')}
+
{t('home.payAsYouGoDesc')}
- {t('home.payAsYouGo')}
- {t('home.payAsYouGoDesc')}
-
+
@@ -178,37 +199,43 @@ export default function CorporateHome() {
{packages.filter(p => p.enabled).slice(0, 3).map((pkg, i) => (
-
- {i === 1 && (
-
- Popular
-
- )}
-
-
{pkg.name}
- {pkg.description &&
{pkg.description}
}
-
-
-
${pkg.price}
- {pkg.original_price > pkg.price && (
-
${pkg.original_price}
- )}
+
+
+ {i === 1 && (
+
+ Popular
- {pkg.duration > 0 &&
{t('home.days', { count: pkg.duration })}
}
+ )}
+
+
{pkg.name}
+ {pkg.description &&
{pkg.description}
}
+
+
+ ${pkg.price}
+ {pkg.original_price > pkg.price && (
+ ${pkg.original_price}
+ )}
+
+ {pkg.duration > 0 &&
{t('home.days', { count: pkg.duration })}
}
+
+
+
+
+ {user ? t('home.subscribe') : t('home.getStarted')}
+
-
-
- {user ? t('home.subscribe') : t('home.getStarted')}
-
-
-
+
))}