feat: new logo mark, 8 persona avatars, remove unauthenticated billing API call

- Logo.tsx: C arc + 3 people silhouettes SVG mark matching brand design
- favicon.svg: updated to match new logo mark
- public/avatars/: 8 diverse persona SVGs (skin tones, hair styles, ages)
- Index.tsx: remove billingApi.getBalance() call on public landing page (was causing 401 console errors for anonymous visitors; pricing uses hardcoded defaults)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vadym Samoilenko 2026-05-23 20:15:33 +01:00
parent b2a063b55f
commit 32d21d1260
11 changed files with 287 additions and 50 deletions

View file

@ -0,0 +1,23 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<!-- Background -->
<circle cx="50" cy="50" r="50" fill="#2D3E50"/>
<!-- Body / shoulders -->
<ellipse cx="50" cy="85" rx="28" ry="20" fill="#1C2A38"/>
<!-- Neck -->
<rect x="44" y="58" width="12" height="14" rx="4" fill="#C68642"/>
<!-- Head -->
<ellipse cx="50" cy="48" rx="18" ry="20" fill="#C68642"/>
<!-- Hair — short dark -->
<ellipse cx="50" cy="31" rx="18" ry="10" fill="#1A1A1A"/>
<rect x="32" y="28" width="36" height="12" rx="6" fill="#1A1A1A"/>
<!-- Eyes -->
<ellipse cx="43" cy="47" rx="3" ry="3.5" fill="#fff"/>
<ellipse cx="57" cy="47" rx="3" ry="3.5" fill="#fff"/>
<circle cx="44" cy="47" r="1.8" fill="#1A1A1A"/>
<circle cx="58" cy="47" r="1.8" fill="#1A1A1A"/>
<!-- Eyebrows -->
<path d="M 39 42 Q 43 40 47 42" stroke="#1A1A1A" stroke-width="1.5" fill="none" stroke-linecap="round"/>
<path d="M 53 42 Q 57 40 61 42" stroke="#1A1A1A" stroke-width="1.5" fill="none" stroke-linecap="round"/>
<!-- Mouth -->
<path d="M 44 57 Q 50 61 56 57" stroke="#A0522D" stroke-width="1.8" fill="none" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,25 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" fill="#3D2B4E"/>
<!-- Body -->
<ellipse cx="50" cy="85" rx="28" ry="20" fill="#2A1D38"/>
<!-- Neck -->
<rect x="45" y="59" width="10" height="13" rx="4" fill="#F0C8A0"/>
<!-- Head -->
<ellipse cx="50" cy="48" rx="17" ry="19" fill="#F0C8A0"/>
<!-- Hair — long auburn, side parted -->
<ellipse cx="50" cy="30" rx="19" ry="10" fill="#7B3F00"/>
<rect x="31" y="26" width="38" height="16" rx="6" fill="#7B3F00"/>
<!-- Long hair sides -->
<path d="M 32 36 Q 28 55 30 68" stroke="#7B3F00" stroke-width="8" fill="none" stroke-linecap="round"/>
<path d="M 68 36 Q 72 55 70 68" stroke="#7B3F00" stroke-width="8" fill="none" stroke-linecap="round"/>
<!-- Eyes -->
<ellipse cx="43" cy="47" rx="3.2" ry="3.2" fill="#fff"/>
<ellipse cx="57" cy="47" rx="3.2" ry="3.2" fill="#fff"/>
<circle cx="43.5" cy="47" r="1.9" fill="#3B2005"/>
<circle cx="57.5" cy="47" r="1.9" fill="#3B2005"/>
<!-- Eyebrows -->
<path d="M 38 42 Q 43 39 47 41" stroke="#7B3F00" stroke-width="1.8" fill="none" stroke-linecap="round"/>
<path d="M 53 41 Q 57 39 62 42" stroke="#7B3F00" stroke-width="1.8" fill="none" stroke-linecap="round"/>
<!-- Mouth -->
<path d="M 44 57 Q 50 62 56 57" stroke="#C0704A" stroke-width="2" fill="none" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,25 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" fill="#1E3A2F"/>
<!-- Body -->
<ellipse cx="50" cy="86" rx="28" ry="20" fill="#132A20"/>
<!-- Neck -->
<rect x="44" y="59" width="12" height="13" rx="4" fill="#8D5524"/>
<!-- Head -->
<ellipse cx="50" cy="48" rx="17" ry="20" fill="#8D5524"/>
<!-- Hair — tight curls / afro -->
<circle cx="50" cy="32" r="20" fill="#1A0A00"/>
<ellipse cx="50" cy="40" rx="18" ry="10" fill="#8D5524"/>
<!-- Ear detail -->
<ellipse cx="33" cy="49" rx="3" ry="4" fill="#7A4A1E"/>
<ellipse cx="67" cy="49" rx="3" ry="4" fill="#7A4A1E"/>
<!-- Eyes -->
<ellipse cx="43" cy="47" rx="3" ry="3.2" fill="#fff"/>
<ellipse cx="57" cy="47" rx="3" ry="3.2" fill="#fff"/>
<circle cx="43.5" cy="47" r="1.8" fill="#1A0A00"/>
<circle cx="57.5" cy="47" r="1.8" fill="#1A0A00"/>
<!-- Eyebrows -->
<path d="M 39 42 Q 43 40 47 42" stroke="#1A0A00" stroke-width="2" fill="none" stroke-linecap="round"/>
<path d="M 53 42 Q 57 40 61 42" stroke="#1A0A00" stroke-width="2" fill="none" stroke-linecap="round"/>
<!-- Mouth -->
<path d="M 43 58 Q 50 63 57 58" stroke="#6B3015" stroke-width="2" fill="none" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,28 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" fill="#243447"/>
<!-- Body -->
<ellipse cx="50" cy="86" rx="28" ry="20" fill="#182433"/>
<!-- Neck -->
<rect x="44" y="59" width="12" height="13" rx="4" fill="#FDBCB4"/>
<!-- Head -->
<ellipse cx="50" cy="47" rx="17" ry="19" fill="#FDBCB4"/>
<!-- Hair — blonde, short on sides, longer top -->
<ellipse cx="50" cy="30" rx="17" ry="8" fill="#D4A017"/>
<rect x="33" y="26" width="34" height="14" rx="5" fill="#D4A017"/>
<!-- Side hair fade -->
<rect x="33" y="34" width="6" height="14" rx="3" fill="#D4A017" opacity="0.6"/>
<rect x="61" y="34" width="6" height="14" rx="3" fill="#D4A017" opacity="0.6"/>
<!-- Eyes — blue -->
<ellipse cx="43" cy="46" rx="3.5" ry="3.5" fill="#fff"/>
<ellipse cx="57" cy="46" rx="3.5" ry="3.5" fill="#fff"/>
<circle cx="43.5" cy="46" r="2" fill="#4A90D9"/>
<circle cx="57.5" cy="46" r="2" fill="#4A90D9"/>
<circle cx="44" cy="45.5" r="0.7" fill="#fff"/>
<!-- Eyebrows -->
<path d="M 38 41 Q 43 39 47 41" stroke="#C49010" stroke-width="1.8" fill="none" stroke-linecap="round"/>
<path d="M 53 41 Q 57 39 62 41" stroke="#C49010" stroke-width="1.8" fill="none" stroke-linecap="round"/>
<!-- Mouth -->
<path d="M 44 57 Q 50 61 56 57" stroke="#C08070" stroke-width="2" fill="none" stroke-linecap="round"/>
<!-- Stubble hint -->
<path d="M 38 54 Q 50 60 62 54" stroke="#E0A090" stroke-width="0.5" fill="none" opacity="0.5"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,26 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" fill="#2E2040"/>
<!-- Body -->
<ellipse cx="50" cy="86" rx="28" ry="20" fill="#1E1530"/>
<!-- Neck -->
<rect x="44" y="59" width="12" height="13" rx="4" fill="#F5CBA7"/>
<!-- Head -->
<ellipse cx="50" cy="47" rx="17" ry="20" fill="#F5CBA7"/>
<!-- Hair — dark brown, medium length, wavy -->
<ellipse cx="50" cy="29" rx="18" ry="9" fill="#2C1810"/>
<rect x="32" y="26" width="36" height="15" rx="6" fill="#2C1810"/>
<!-- Wavy ends -->
<path d="M 32 38 Q 28 52 32 64" stroke="#2C1810" stroke-width="7" fill="none" stroke-linecap="round"/>
<path d="M 68 38 Q 72 52 68 64" stroke="#2C1810" stroke-width="7" fill="none" stroke-linecap="round"/>
<!-- Eyes — dark -->
<ellipse cx="43" cy="46" rx="3.2" ry="3.2" fill="#fff"/>
<ellipse cx="57" cy="46" rx="3.2" ry="3.2" fill="#fff"/>
<circle cx="43.5" cy="46" r="1.9" fill="#1A0800"/>
<circle cx="57.5" cy="46" r="1.9" fill="#1A0800"/>
<!-- Eyebrows — arched -->
<path d="M 38 41 Q 43 38 47 41" stroke="#2C1810" stroke-width="2" fill="none" stroke-linecap="round"/>
<path d="M 53 41 Q 57 38 62 41" stroke="#2C1810" stroke-width="2" fill="none" stroke-linecap="round"/>
<!-- Lips -->
<path d="M 44 57 Q 47 60 50 58 Q 53 60 56 57" stroke="#C07060" stroke-width="1.5" fill="none" stroke-linecap="round"/>
<path d="M 44 57 Q 50 55 56 57" stroke="#C07060" stroke-width="1.2" fill="none" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,29 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" fill="#1A3040"/>
<!-- Body -->
<ellipse cx="50" cy="86" rx="28" ry="20" fill="#102030"/>
<!-- Neck -->
<rect x="44" y="59" width="12" height="13" rx="4" fill="#D4956A"/>
<!-- Head — slightly wider, older -->
<ellipse cx="50" cy="47" rx="18" ry="20" fill="#D4956A"/>
<!-- Hair — salt and pepper, short -->
<ellipse cx="50" cy="29" rx="18" ry="9" fill="#888"/>
<rect x="32" y="26" width="36" height="14" rx="6" fill="#888"/>
<!-- Grey temples -->
<rect x="32" y="34" width="6" height="12" rx="3" fill="#AAA"/>
<rect x="62" y="34" width="6" height="12" rx="3" fill="#AAA"/>
<!-- Eyes -->
<ellipse cx="43" cy="47" rx="3.2" ry="3" fill="#fff"/>
<ellipse cx="57" cy="47" rx="3.2" ry="3" fill="#fff"/>
<circle cx="43.5" cy="47" r="1.8" fill="#2C1810"/>
<circle cx="57.5" cy="47" r="1.8" fill="#2C1810"/>
<!-- Glasses -->
<rect x="37" y="43" width="12" height="8" rx="3" stroke="#666" stroke-width="1.5" fill="none"/>
<rect x="51" y="43" width="12" height="8" rx="3" stroke="#666" stroke-width="1.5" fill="none"/>
<line x1="49" y1="47" x2="51" y2="47" stroke="#666" stroke-width="1.5"/>
<!-- Eyebrows — bushy -->
<path d="M 37 42 Q 43 40 49 42" stroke="#666" stroke-width="2.2" fill="none" stroke-linecap="round"/>
<path d="M 51 42 Q 57 40 63 42" stroke="#666" stroke-width="2.2" fill="none" stroke-linecap="round"/>
<!-- Mouth — slight smile -->
<path d="M 43 58 Q 50 63 57 58" stroke="#B07050" stroke-width="1.8" fill="none" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,28 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" fill="#2A3828"/>
<!-- Body -->
<ellipse cx="50" cy="86" rx="28" ry="20" fill="#1A2818"/>
<!-- Neck -->
<rect x="44" y="59" width="12" height="13" rx="4" fill="#E8B98A"/>
<!-- Head -->
<ellipse cx="50" cy="47" rx="16" ry="19" fill="#E8B98A"/>
<!-- Hair — black, straight, bob cut -->
<ellipse cx="50" cy="29" rx="16" ry="8" fill="#0D0D0D"/>
<rect x="34" y="26" width="32" height="16" rx="4" fill="#0D0D0D"/>
<!-- Bob sides -->
<rect x="34" y="34" width="6" height="22" rx="3" fill="#0D0D0D"/>
<rect x="60" y="34" width="6" height="22" rx="3" fill="#0D0D0D"/>
<!-- Eyes — almond shape -->
<ellipse cx="43" cy="46" rx="3.5" ry="2.8" fill="#fff"/>
<ellipse cx="57" cy="46" rx="3.5" ry="2.8" fill="#fff"/>
<circle cx="43.5" cy="46" r="1.8" fill="#0D0D0D"/>
<circle cx="57.5" cy="46" r="1.8" fill="#0D0D0D"/>
<!-- Eyelids — slight monolid -->
<path d="M 39 44 Q 43 43 47 44" stroke="#0D0D0D" stroke-width="1.2" fill="none" stroke-linecap="round"/>
<path d="M 53 44 Q 57 43 61 44" stroke="#0D0D0D" stroke-width="1.2" fill="none" stroke-linecap="round"/>
<!-- Eyebrows — straight -->
<path d="M 39 41 L 47 41" stroke="#0D0D0D" stroke-width="2" fill="none" stroke-linecap="round"/>
<path d="M 53 41 L 61 41" stroke="#0D0D0D" stroke-width="2" fill="none" stroke-linecap="round"/>
<!-- Mouth -->
<path d="M 45 57 Q 50 61 55 57" stroke="#C08060" stroke-width="1.8" fill="none" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,28 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" fill="#2D2010"/>
<!-- Body -->
<ellipse cx="50" cy="86" rx="28" ry="20" fill="#1E1508"/>
<!-- Neck -->
<rect x="44" y="59" width="12" height="13" rx="4" fill="#6B3A2A"/>
<!-- Head -->
<ellipse cx="50" cy="47" rx="17" ry="20" fill="#6B3A2A"/>
<!-- Hair — natural black, medium afro -->
<ellipse cx="50" cy="28" rx="21" ry="14" fill="#0D0808"/>
<ellipse cx="50" cy="38" rx="18" ry="8" fill="#6B3A2A"/>
<!-- Ears -->
<ellipse cx="33" cy="49" rx="3" ry="4" fill="#5A2E1E"/>
<ellipse cx="67" cy="49" rx="3" ry="4" fill="#5A2E1E"/>
<!-- Eyes -->
<ellipse cx="43" cy="47" rx="3.2" ry="3.2" fill="#fff"/>
<ellipse cx="57" cy="47" rx="3.2" ry="3.2" fill="#fff"/>
<circle cx="43.5" cy="47" r="1.9" fill="#0D0808"/>
<circle cx="57.5" cy="47" r="1.9" fill="#0D0808"/>
<!-- Eyebrows -->
<path d="M 39 42 Q 43 40 47 42" stroke="#0D0808" stroke-width="2" fill="none" stroke-linecap="round"/>
<path d="M 53 42 Q 57 40 61 42" stroke="#0D0808" stroke-width="2" fill="none" stroke-linecap="round"/>
<!-- Wide smile -->
<path d="M 41 57 Q 50 65 59 57" stroke="#4A1A0A" stroke-width="2.2" fill="none" stroke-linecap="round"/>
<!-- Smile lines -->
<path d="M 40 54 Q 38 58 41 60" stroke="#5A2E1E" stroke-width="1" fill="none" stroke-linecap="round" opacity="0.6"/>
<path d="M 60 54 Q 62 58 59 60" stroke="#5A2E1E" stroke-width="1" fill="none" stroke-linecap="round" opacity="0.6"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,13 +1,20 @@
<svg viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="32" height="32" rx="8" fill="#04080F"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<defs>
<linearGradient id="fg" x1="3" y1="3" x2="29" y2="29" gradientUnits="userSpaceOnUse">
<stop stop-color="#06B6D4"/>
<stop offset="1" stop-color="#8B5CF6"/>
<linearGradient id="arc" x1="50" y1="8" x2="50" y2="92" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#FFB340"/>
<stop offset="100%" stop-color="#E07800"/>
</linearGradient>
<linearGradient id="person" x1="50" y1="32" x2="50" y2="66" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#FFB340"/>
<stop offset="100%" stop-color="#E07800"/>
</linearGradient>
</defs>
<path d="M25 7C22.2 5.1 18.9 4 15.3 4C8 4 2 10 2 16.5C2 23 8 29 15.3 29C18.9 29 22.2 27.9 25 26"
stroke="url(#fg)" stroke-width="3.5" stroke-linecap="round" fill="none"/>
<circle cx="25" cy="7" r="2.2" fill="#06B6D4"/>
<circle cx="25" cy="26" r="2.2" fill="#8B5CF6"/>
<rect width="100" height="100" rx="22" fill="#161D2E"/>
<path d="M 77.5 25.3 A 37 37 0 1 0 77.5 74.7" stroke="url(#arc)" stroke-width="14" stroke-linecap="round" fill="none"/>
<circle cx="36" cy="42" r="5.5" fill="#4B5568"/>
<path d="M 28 53 A 8 8 0 0 1 44 53 Z" fill="#4B5568"/>
<circle cx="64" cy="42" r="5.5" fill="#4B5568"/>
<path d="M 56 53 A 8 8 0 0 1 72 53 Z" fill="#4B5568"/>
<circle cx="50" cy="39" r="7.5" fill="url(#person)"/>
<path d="M 39 52 A 11 11 0 0 1 61 52 Z" fill="url(#person)"/>
</svg>

Before

Width:  |  Height:  |  Size: 625 B

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -1,3 +1,4 @@
import { useId } from 'react';
import { cn } from '@/lib/utils';
interface LogoProps {
@ -6,37 +7,68 @@ interface LogoProps {
size?: 'sm' | 'md' | 'lg';
}
const sizes = { sm: 'h-6 w-6', md: 'h-8 w-8', lg: 'h-10 w-10' };
function LogoMark({ px, id }: { px: number; id: string }) {
const arcId = `${id}-arc`;
const personId = `${id}-person`;
return (
<svg width={px} height={px} viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
{/* Arc gradient: light orange top → deep orange bottom */}
<linearGradient id={arcId} x1="50" y1="8" x2="50" y2="92" gradientUnits="userSpaceOnUse">
<stop offset="0%" stopColor="#FFB340" />
<stop offset="100%" stopColor="#E07800" />
</linearGradient>
{/* Center person gradient: same orange */}
<linearGradient id={personId} x1="50" y1="32" x2="50" y2="66" gradientUnits="userSpaceOnUse">
<stop offset="0%" stopColor="#FFB340" />
<stop offset="100%" stopColor="#E07800" />
</linearGradient>
</defs>
{/*
C arc: center (50,50), mid-radius 37, stroke-width 14
Opens to the right. Tips at ±42° from horizontal right.
Top tip: (50+37·cos(-42°), 50+37·sin(-42°)) (77.5, 25.3)
Bottom tip: (77.5, 74.7)
large-arc=1, sweep=0 long counter-clockwise arc through the left side = C shape
*/}
<path
d="M 77.5 25.3 A 37 37 0 1 0 77.5 74.7"
stroke={`url(#${arcId})`}
strokeWidth="14"
strokeLinecap="round"
fill="none"
/>
{/* ── Left person — dark gray, small, behind ── */}
{/* Head */}
<circle cx="36" cy="42" r="5.5" fill="#4B5568" />
{/* Shoulder arc */}
<path d="M 28 53 A 8 8 0 0 1 44 53 Z" fill="#4B5568" />
{/* ── Right person — dark gray, small, behind ── */}
<circle cx="64" cy="42" r="5.5" fill="#4B5568" />
<path d="M 56 53 A 8 8 0 0 1 72 53 Z" fill="#4B5568" />
{/* ── Center person — orange, larger, in front ── */}
<circle cx="50" cy="39" r="7.5" fill={`url(#${personId})`} />
<path d="M 39 52 A 11 11 0 0 1 61 52 Z" fill={`url(#${personId})`} />
</svg>
);
}
export default function Logo({ className, withWordmark = false, size = 'md' }: LogoProps) {
const id = useId().replace(/:/g, '');
const px = size === 'sm' ? 24 : size === 'lg' ? 40 : 32;
const textSize = size === 'sm' ? 'text-base' : size === 'lg' ? 'text-xl' : 'text-lg';
return (
<div className={cn('flex items-center gap-2.5', className)}>
<svg viewBox="0 0 36 36" fill="none" className={sizes[size]}>
<defs>
<linearGradient id="logo-lg" x1="2" y1="2" x2="34" y2="34" gradientUnits="userSpaceOnUse">
<stop stopColor="hsl(28 78% 56%)" />
<stop offset="1" stopColor="hsl(38 90% 65%)" />
</linearGradient>
</defs>
{/* Hexagonal mark */}
<path
d="M18 3L31 10.5V25.5L18 33L5 25.5V10.5L18 3Z"
stroke="url(#logo-lg)"
strokeWidth="2.5"
strokeLinejoin="round"
fill="none"
/>
<path
d="M13 18L16.5 22.5L23 13.5"
stroke="url(#logo-lg)"
strokeWidth="2.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
<div className={cn('flex items-center gap-2', className)}>
<LogoMark px={px} id={id} />
{withWordmark && (
<span
className="font-display font-bold text-lg tracking-tight text-foreground"
className={cn('font-display font-bold tracking-tight text-foreground', textSize)}
style={{ letterSpacing: '-0.02em' }}
>
Cohorta

View file

@ -5,8 +5,6 @@ import {
Zap, Clock, DollarSign, Globe, ChevronDown, ChevronUp,
CheckCircle2, Star
} from 'lucide-react';
import { billingApi } from '@/lib/api';
// ──────────────────────────────────────────────
// Helpers
// ──────────────────────────────────────────────
@ -108,7 +106,7 @@ function FAQItem({ q, a }: { q: string; a: string }) {
export default function Index() {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const [packs, setPacks] = useState<CreditPack[]>(DEFAULT_PACKS);
const packs = DEFAULT_PACKS;
useEffect(() => {
const section = searchParams.get('scroll');
@ -117,18 +115,6 @@ export default function Index() {
}
}, [searchParams]);
useEffect(() => {
billingApi.getBalance()
.then(r => {
const apiPacks: CreditPack[] = (r.data.credit_packs || []).map((p: any) => ({
...p,
popular: p.id === 'pro',
}));
if (apiPacks.length >= 2) setPacks(apiPacks);
})
.catch(() => {});
}, []);
return (
<div className="bg-background overflow-hidden">