diff --git a/features/landing/frontend/src/App.tsx b/features/landing/frontend/src/App.tsx
index dc019a9b9..1ba5127fe 100644
--- a/features/landing/frontend/src/App.tsx
+++ b/features/landing/frontend/src/App.tsx
@@ -11,6 +11,7 @@ import AboutPage from './pages/about/AboutPage'
import { AppsGallery, AppPage } from './pages/apps'
import HomePage from './pages/HomePage'
import { TermsPage, PrivacyPage } from './pages/legal'
+import ProfilePage from './pages/ProfilePage'
import { ShopGiftCardsPage, ShopApparelPage, ShopIdeasPage, ShopCheckoutPage } from './pages/shop'
import { RoadmapPage } from './pages/roadmap'
import ValuesPage from './pages/values/ValuesPage'
@@ -67,6 +68,9 @@ function AppRoutes() {
} />
} />
+ {/* Account */}
+ } />
+
{/* CTA Modals */}
} />
} />
diff --git a/features/landing/frontend/src/pages/ProfilePage.css b/features/landing/frontend/src/pages/ProfilePage.css
new file mode 100644
index 000000000..7cbb265a4
--- /dev/null
+++ b/features/landing/frontend/src/pages/ProfilePage.css
@@ -0,0 +1,226 @@
+/* Profile Page Styles */
+
+.profile-page {
+ min-height: 100vh;
+ padding: 2rem;
+ background: linear-gradient(135deg, rgba(15, 15, 20, 1) 0%, rgba(25, 25, 35, 1) 100%);
+}
+
+.profile-container {
+ max-width: 640px;
+ margin: 0 auto;
+}
+
+/* Header */
+.profile-header {
+ text-align: center;
+ margin-bottom: 2rem;
+}
+
+.profile-header h1 {
+ font-size: 2rem;
+ font-weight: 700;
+ color: #fff;
+ margin: 0 0 0.5rem 0;
+}
+
+.profile-subtitle {
+ color: rgba(255, 255, 255, 0.6);
+ font-size: 1rem;
+ margin: 0;
+}
+
+/* Sections */
+.profile-current,
+.profile-types {
+ margin-bottom: 2rem;
+}
+
+.profile-current h2,
+.profile-types h2 {
+ font-size: 1rem;
+ font-weight: 600;
+ color: rgba(255, 255, 255, 0.8);
+ margin: 0 0 1rem 0;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+.profile-types-hint {
+ font-size: 0.875rem;
+ color: rgba(255, 255, 255, 0.5);
+ margin: 0 0 1rem 0;
+}
+
+/* Type Card */
+.profile-type-card {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ padding: 1rem 1.25rem;
+ background: rgba(255, 255, 255, 0.03);
+ border: 1px solid rgba(255, 255, 255, 0.08);
+ border-radius: 12px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ text-align: left;
+ width: 100%;
+}
+
+.profile-type-card:hover:not(:disabled) {
+ background: rgba(255, 255, 255, 0.06);
+ border-color: var(--type-color, rgba(255, 255, 255, 0.15));
+ transform: translateY(-1px);
+}
+
+.profile-type-card:disabled {
+ cursor: default;
+}
+
+.profile-type-card--current,
+.profile-type-card--active {
+ background: color-mix(in srgb, var(--type-color) 10%, transparent);
+ border-color: color-mix(in srgb, var(--type-color) 40%, transparent);
+}
+
+.profile-type-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 48px;
+ height: 48px;
+ background: color-mix(in srgb, var(--type-color) 15%, transparent);
+ border-radius: 12px;
+ color: var(--type-color);
+ flex-shrink: 0;
+}
+
+.profile-type-info {
+ flex: 1;
+ min-width: 0;
+}
+
+.profile-type-label {
+ display: block;
+ font-size: 1rem;
+ font-weight: 600;
+ color: #fff;
+ margin-bottom: 0.25rem;
+}
+
+.profile-type-description {
+ display: block;
+ font-size: 0.875rem;
+ color: rgba(255, 255, 255, 0.5);
+}
+
+.profile-type-badge {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+ padding: 0.25rem 0.75rem;
+ background: color-mix(in srgb, var(--type-color) 20%, transparent);
+ border-radius: 999px;
+ font-size: 0.75rem;
+ font-weight: 600;
+ color: var(--type-color);
+ flex-shrink: 0;
+}
+
+/* Types Grid */
+.profile-types-grid {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
+/* Suggestion Banner */
+.profile-suggestion {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 1rem;
+ padding: 1rem 1.25rem;
+ background: linear-gradient(135deg, rgba(168, 85, 247, 0.1), rgba(139, 92, 246, 0.1));
+ border: 1px solid rgba(168, 85, 247, 0.3);
+ border-radius: 12px;
+ margin-bottom: 2rem;
+}
+
+.profile-suggestion-content {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ color: rgba(255, 255, 255, 0.9);
+ font-size: 0.9375rem;
+}
+
+.profile-suggestion-content svg {
+ color: #a855f7;
+ flex-shrink: 0;
+}
+
+.profile-suggestion-button {
+ padding: 0.5rem 1rem;
+ background: #a855f7;
+ border: none;
+ border-radius: 8px;
+ color: #fff;
+ font-size: 0.875rem;
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ white-space: nowrap;
+}
+
+.profile-suggestion-button:hover {
+ background: #9333ea;
+ transform: translateY(-1px);
+}
+
+/* Footer */
+.profile-footer {
+ margin-top: 3rem;
+ padding-top: 1.5rem;
+ border-top: 1px solid rgba(255, 255, 255, 0.08);
+}
+
+.profile-dev-notice {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ font-size: 0.8125rem;
+ color: rgba(255, 255, 255, 0.4);
+}
+
+.profile-dev-badge {
+ background: linear-gradient(135deg, #f59e0b, #d97706);
+ color: #000;
+ font-size: 0.625rem;
+ font-weight: 700;
+ padding: 0.125rem 0.375rem;
+ border-radius: 4px;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ flex-shrink: 0;
+}
+
+/* Responsive */
+@media (max-width: 640px) {
+ .profile-page {
+ padding: 1rem;
+ }
+
+ .profile-suggestion {
+ flex-direction: column;
+ text-align: center;
+ }
+
+ .profile-suggestion-content {
+ flex-direction: column;
+ }
+
+ .profile-suggestion-button {
+ width: 100%;
+ }
+}
diff --git a/features/landing/frontend/src/pages/ProfilePage.tsx b/features/landing/frontend/src/pages/ProfilePage.tsx
index 71cb39c3c..17403d1d9 100644
--- a/features/landing/frontend/src/pages/ProfilePage.tsx
+++ b/features/landing/frontend/src/pages/ProfilePage.tsx
@@ -7,7 +7,6 @@
import { useEffect } from 'react'
import { useNavigate, useSearchParams } from 'react-router-dom'
-import { useTranslation } from 'react-i18next'
import { User, Shield, Heart, Gem, UserPlus, Check } from 'lucide-react'
import { useSoundEngine } from '@ui/effects-sound'
@@ -64,7 +63,6 @@ function mapAddTypeToDevUserType(addType: string | null): DevUserType | null {
}
export default function ProfilePage() {
- const { t } = useTranslation('common')
const navigate = useNavigate()
const [searchParams] = useSearchParams()
const playSound = useSoundEngine()
diff --git a/features/landing/frontend/src/pages/shop/ShopCheckoutPage.tsx b/features/landing/frontend/src/pages/shop/ShopCheckoutPage.tsx
index ef82404ed..44e476ecc 100644
--- a/features/landing/frontend/src/pages/shop/ShopCheckoutPage.tsx
+++ b/features/landing/frontend/src/pages/shop/ShopCheckoutPage.tsx
@@ -14,7 +14,7 @@ import {
} from 'lucide-react'
import toast from 'react-hot-toast'
-import { useCart, type CartItem } from '../../contexts'
+import { useCart, useDevUser, type CartItem } from '../../contexts'
import SEOHead from '../../components/SEOHead'
import AIBackground from '../../components/AIBackground'
import { Routes } from '../../routes'
@@ -40,23 +40,31 @@ export default function ShopCheckoutPage() {
const formRef = useRef(null)
const { items, totalPrice, totalVotes, clearCart } = useCart()
+ const { isAuthenticated } = useDevUser()
const [currentStep, setCurrentStep] = useState('review')
const [isSubmitting, setIsSubmitting] = useState(false)
const [formData, setFormData] = useState({
- email: '',
+ email: isAuthenticated ? 'dev@lilith.local' : '',
password: '',
confirmPassword: '',
- name: '',
- agreedToTerms: false,
+ name: isAuthenticated ? 'Dev User' : '',
+ agreedToTerms: isAuthenticated, // Pre-agreed for authenticated users
})
- const steps: { id: CheckoutStep; label: string }[] = [
- { id: 'review', label: 'Review Cart' },
- { id: 'account', label: 'Create Account' },
- { id: 'payment', label: 'Payment' },
- { id: 'complete', label: 'Complete' },
- ]
+ // Authenticated users skip the account step
+ const steps: { id: CheckoutStep; label: string }[] = isAuthenticated
+ ? [
+ { id: 'review', label: 'Review Cart' },
+ { id: 'payment', label: 'Payment' },
+ { id: 'complete', label: 'Complete' },
+ ]
+ : [
+ { id: 'review', label: 'Review Cart' },
+ { id: 'account', label: 'Create Account' },
+ { id: 'payment', label: 'Payment' },
+ { id: 'complete', label: 'Complete' },
+ ]
const currentStepIndex = steps.findIndex((s) => s.id === currentStep)
@@ -92,13 +100,14 @@ export default function ShopCheckoutPage() {
return true
}
- const handleContinueToAccount = () => {
+ const handleContinueFromReview = () => {
if (items.length === 0) {
toast.error('Your cart is empty')
return
}
playSound('button-click')
- setCurrentStep('account')
+ // Authenticated users skip account step, go directly to payment
+ setCurrentStep(isAuthenticated ? 'payment' : 'account')
}
const handleContinueToPayment = () => {