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>
23
public/avatars/persona-1.svg
Normal 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 |
25
public/avatars/persona-2.svg
Normal 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 |
25
public/avatars/persona-3.svg
Normal 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 |
28
public/avatars/persona-4.svg
Normal 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 |
26
public/avatars/persona-5.svg
Normal 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 |
29
public/avatars/persona-6.svg
Normal 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 |
28
public/avatars/persona-7.svg
Normal 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 |
28
public/avatars/persona-8.svg
Normal 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 |
|
|
@ -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 |
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
||||
|
|
|
|||