Update components and styling

This commit is contained in:
2025-09-19 15:36:32 +05:30
parent ee87f004ed
commit 1ea39f0ecf
7 changed files with 108 additions and 71 deletions

View File

@@ -43,7 +43,6 @@ function App() {
<WaitlistForm
isVisible={showWaitlistForm}
onClose={closeWaitlistForm}
onBack={closeWaitlistForm}
/>
</div>
);

View File

@@ -90,27 +90,35 @@ const FeaturesSection: React.FC = () => {
{features.map((feature, index) => (
<div
key={index}
className="group bg-deep-forest bg-opacity-40 backdrop-blur-sm border border-luxury-gold border-opacity-20 rounded-2xl p-8 hover:bg-opacity-60 hover:border-opacity-40 transition-all duration-500 transform hover:-translate-y-2 hover:shadow-2xl hover:shadow-luxury-gold/10"
className="group bg-deep-forest bg-opacity-40 backdrop-blur-sm border border-luxury-gold border-opacity-20 rounded-2xl p-8 hover:bg-opacity-60 hover:border-opacity-40 transition-all duration-500 transform hover:-translate-y-2 hover:shadow-2xl hover:shadow-luxury-gold/10 relative overflow-hidden"
>
{/* Running Golden Line Animation - Bottom */}
<div className="absolute bottom-0 left-0 w-full h-1 bg-gradient-to-r from-transparent via-luxury-gold to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-luxury-gold to-transparent animate-pulse"></div>
<div className="absolute h-full w-8 bg-luxury-gold/80 shadow-lg shadow-luxury-gold/50" style={{
animation: 'slide-right 2s infinite linear'
}}></div>
</div>
{/* Icon */}
<div className="mb-8">
<div className="mb-8 relative z-10">
<div className="w-20 h-20 bg-luxury-gold bg-opacity-10 rounded-2xl flex items-center justify-center group-hover:bg-opacity-20 transition-all duration-300 group-hover:scale-110">
{feature.icon}
</div>
</div>
{/* Feature Name */}
<h3 className="text-2xl font-luxury-serif font-semibold text-luxury-gold mb-6 tracking-wide">
<h3 className="text-2xl font-luxury-serif font-semibold text-luxury-gold mb-6 tracking-wide relative z-10">
{feature.name}
</h3>
{/* Description */}
<p className="text-cream leading-relaxed font-elegant-sans opacity-90 group-hover:opacity-100 transition-opacity duration-300">
<p className="text-cream leading-relaxed font-elegant-sans opacity-90 group-hover:opacity-100 transition-opacity duration-300 relative z-10">
{feature.description}
</p>
{/* Decorative element */}
<div className="mt-6 w-12 h-0.5 bg-luxury-gold opacity-30 group-hover:opacity-100 group-hover:w-20 transition-all duration-500"></div>
<div className="mt-6 w-12 h-0.5 bg-luxury-gold opacity-30 group-hover:opacity-100 group-hover:w-20 transition-all duration-500 relative z-10"></div>
</div>
))}
</div>

View File

@@ -1,6 +1,6 @@
const Footer: React.FC = () => {
return (
<footer className="bg-deep-forest bg-opacity-80 border-t border-luxury-gold border-opacity-30 py-16 relative">
<footer className="bg-deep-forest bg-opacity-80 border-t border-luxury-gold border-opacity-30 py-4 relative">
{/* Background overlay */}
<div className="absolute inset-0 bg-rich-brown bg-opacity-10"></div>
@@ -12,7 +12,7 @@ const Footer: React.FC = () => {
<img
src="/assets/Dark-LineLogo-cropped.svg"
alt="Pennyzo Logo"
className="h-12 w-auto"
className="h-16 w-auto"
/>
</div>
<p className="text-cream mb-8 max-w-md font-elegant-sans leading-relaxed opacity-90">

View File

@@ -1,14 +1,14 @@
const Header: React.FC = () => {
return (
<header className="sticky top-0 z-50 bg-deep-forest bg-opacity-95 backdrop-blur-sm border-b border-luxury-gold border-opacity-20">
<div className="container mx-auto px-6 py-4">
<div className="container mx-auto px-6 py-1">
<div className="flex items-center justify-between">
{/* Logo */}
<div className="flex-shrink-0">
<img
src="/assets/Dark-LineLogo-cropped.svg"
alt="Pennyzo Logo"
className="h-10 w-auto"
className="h-16 w-auto"
/>
</div>

View File

@@ -88,32 +88,35 @@ const HeroSection: React.FC<HeroSectionProps> = ({ onJoinWaitlist }) => {
<div className="flex-1 relative">
<div className="relative max-w-lg mx-auto">
{/* Main Card */}
<div className="relative bg-gradient-to-br from-deep-forest/40 to-rich-brown/20 backdrop-blur-2xl border border-luxury-gold/20 rounded-3xl p-12 shadow-2xl">
<div className="text-center space-y-4">
<div className="relative bg-gradient-to-br from-deep-forest/40 to-rich-brown/20 backdrop-blur-2xl border border-luxury-gold/20 rounded-3xl px-12 py-6 shadow-2xl">
<div className="text-center">
{/* Premium Icon */}
{/* <div className="inline-flex items-center justify-center w-20 h-20 bg-gradient-to-br from-luxury-gold/20 to-luxury-gold/10 rounded-2xl border border-luxury-gold/30"> */}
<img
src="/assets/Dark-Icon-cropped.svg"
alt="Pennyzo Icon"
className="w-60 h-60 mx-auto"
className="w-60 h-60 mx-auto -mb-16"
/>
{/* </div> */}
{/* Premium Text */}
<div>
<div className="text-center">
<h3 className="text-luxury-gold font-luxury-serif text-3xl font-bold mb-4">
Executive Suite
</h3>
<p className="text-cream/70 font-elegant-sans text-base leading-relaxed">
<p className="text-cream/70 font-elegant-sans text-base leading-relaxed mb-6">
Experience the pinnacle of business management with our meticulously crafted platform designed for visionary leaders.
</p>
</div>
{/* Features List */}
<div className="space-y-3 text-left">
<div className="space-y-3 text-center mt-4">
{['Advanced Analytics Dashboard', 'AI-Powered Insights', 'White-Glove Support'].map((feature, index) => (
<div key={index} className="flex items-center space-x-3">
<div className="w-2 h-2 bg-luxury-gold rounded-full"></div>
<div key={index} className="flex items-center justify-center space-x-3">
<svg className="w-4 h-4 text-luxury-gold" fill="currentColor" viewBox="0 0 24 24">
<path d="M6 3h12l4 6-10 12L2 9l4-6z" />
<path d="M6 3l6 6 6-6M2 9l10 3 10-3" fillOpacity="0.7" />
</svg>
<span className="text-cream/80 font-elegant-sans text-sm">{feature}</span>
</div>
))}

View File

@@ -3,7 +3,6 @@ import React, { useState } from 'react';
interface WaitlistFormProps {
isVisible: boolean;
onClose: () => void;
onBack: () => void;
}
interface FormData {
@@ -13,13 +12,13 @@ interface FormData {
companyName: string;
companyType: string;
gstRegistered: string;
gstNumber: string;
cin: string;
panNumber: string;
industry: string;
goals: string;
}
const WaitlistForm: React.FC<WaitlistFormProps> = ({ isVisible, onClose, onBack }) => {
const WaitlistForm: React.FC<WaitlistFormProps> = ({ isVisible, onClose }) => {
const [formData, setFormData] = useState<FormData>({
firstName: '',
lastName: '',
@@ -27,10 +26,10 @@ const WaitlistForm: React.FC<WaitlistFormProps> = ({ isVisible, onClose, onBack
companyName: '',
companyType: '',
gstRegistered: '',
gstNumber: '',
cin: '',
panNumber: '',
industry: '',
goals: ''
industry: ''
});
const [isLoading, setIsLoading] = useState(false);
const [errors, setErrors] = useState<Partial<FormData>>({});
@@ -78,6 +77,11 @@ const WaitlistForm: React.FC<WaitlistFormProps> = ({ isVisible, onClose, onBack
newData.panNumber = '';
}
// Clear GST number when GST registration changes to "no"
if (field === 'gstRegistered' && value === 'no') {
newData.gstNumber = '';
}
return newData;
});
@@ -101,6 +105,11 @@ const WaitlistForm: React.FC<WaitlistFormProps> = ({ isVisible, onClose, onBack
if (!formData.companyType) newErrors.companyType = 'Company type is required';
if (!formData.gstRegistered) newErrors.gstRegistered = 'GST registration status is required';
// GST Number validation when GST is registered
if (formData.gstRegistered === 'yes' && !formData.gstNumber.trim()) {
newErrors.gstNumber = 'GST Number is required when registered';
}
// Conditional validation - only when GST is NOT registered
if (formData.gstRegistered === 'no') {
if (['Pvt Ltd', 'LLP'].includes(formData.companyType)) {
@@ -113,7 +122,6 @@ const WaitlistForm: React.FC<WaitlistFormProps> = ({ isVisible, onClose, onBack
}
if (!formData.industry) newErrors.industry = 'Industry is required';
if (!formData.goals.trim()) newErrors.goals = 'Please tell us about your goals';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
@@ -139,34 +147,38 @@ const WaitlistForm: React.FC<WaitlistFormProps> = ({ isVisible, onClose, onBack
return (
<div className="fixed inset-0 z-[60] flex items-center justify-center bg-deep-forest/80 backdrop-blur-sm">
<div className="relative max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto">
{/* Close Button */}
<button
onClick={onClose}
className="absolute -top-2 -right-2 w-8 h-8 bg-luxury-gold hover:bg-luxury-gold/90 text-deep-forest rounded-full flex items-center justify-center font-bold z-10 transition-all duration-200 shadow-lg"
>
×
</button>
{/* Back Button */}
<button
onClick={onBack}
className="absolute -top-2 -left-2 w-8 h-8 bg-luxury-gold/20 hover:bg-luxury-gold/30 text-luxury-gold border border-luxury-gold/30 rounded-full flex items-center justify-center font-bold z-10 transition-all duration-200 shadow-lg"
>
←
</button>
<div
className="relative max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto overflow-x-hidden"
style={{
scrollbarWidth: 'thin',
scrollbarColor: '#C59D59 transparent',
}}
onMouseEnter={(e) => {
e.currentTarget.style.scrollbarColor = '#C59D59 rgba(197, 157, 89, 0.1)';
}}
onMouseLeave={(e) => {
e.currentTarget.style.scrollbarColor = '#C59D59 transparent';
}}
>
{/* Form Container */}
<div className="bg-gradient-to-br from-deep-forest/95 to-rich-brown/90 backdrop-blur-2xl border border-luxury-gold/30 rounded-2xl shadow-2xl overflow-hidden">
<div className="bg-gradient-to-br from-deep-forest/95 to-rich-brown/90 backdrop-blur-2xl border border-luxury-gold/30 rounded-2xl shadow-2xl overflow-hidden relative">
{/* Close Button - Inside Form */}
<button
onClick={onClose}
className="absolute top-4 right-4 w-8 h-8 bg-luxury-gold hover:bg-luxury-gold/90 text-deep-forest rounded-full flex items-center justify-center font-bold z-10 transition-all duration-200 shadow-lg"
>
×
</button>
{/* Header */}
<div className="bg-gradient-to-r from-luxury-gold/10 to-luxury-gold/5 px-8 py-6 border-b border-luxury-gold/20">
<div className="bg-gradient-to-r from-luxury-gold/10 to-luxury-gold/5 px-8 pt-0 pb-1 border-b border-luxury-gold/20">
<div className="text-center">
<img
src="/assets/Dark-Icon-cropped.svg"
alt="Pennyzo Icon"
className="w-16 h-16 mx-auto mb-4"
className="w-32 h-32 mx-auto"
/>
<h2 className="text-luxury-gold font-luxury-serif text-2xl font-bold mb-2">
<h2 className="text-luxury-gold font-luxury-serif text-2xl font-bold mb-1">
Join Our Exclusive Waitlist
</h2>
<p className="text-cream/70 font-elegant-sans text-sm">
@@ -324,6 +336,29 @@ const WaitlistForm: React.FC<WaitlistFormProps> = ({ isVisible, onClose, onBack
</div>
</div>
{/* Conditional GST Number Field - shows when GST is registered */}
{formData.gstRegistered === 'yes' && (
<div className="mb-4">
<label className="block text-cream/90 font-elegant-sans text-sm font-medium mb-2">
GST Number <span className="text-red-400">*</span>
</label>
<input
type="text"
value={formData.gstNumber}
onChange={(e) => handleInputChange('gstNumber', e.target.value.toUpperCase())}
className={`w-full bg-deep-forest/50 border ${errors.gstNumber ? 'border-red-400' : 'border-luxury-gold/20'} rounded-lg px-4 py-3 text-cream placeholder-cream/40 focus:outline-none focus:ring-2 focus:ring-luxury-gold/50 focus:border-luxury-gold/50 transition-all duration-300 font-elegant-sans`}
placeholder="e.g., 27AAPFU0939F1ZV"
maxLength={15}
/>
{errors.gstNumber && (
<p className="text-red-400 text-xs mt-1 font-elegant-sans">{errors.gstNumber}</p>
)}
<p className="text-cream/50 text-xs mt-1 font-elegant-sans">
15-character Goods and Services Tax Identification Number
</p>
</div>
)}
{/* Conditional CIN Field - shows when company type is Pvt Ltd or LLP AND GST is NOT registered */}
{formData.gstRegistered === 'no' && ['Pvt Ltd', 'LLP'].includes(formData.companyType) && (
<div className="mb-4">
@@ -393,32 +428,6 @@ const WaitlistForm: React.FC<WaitlistFormProps> = ({ isVisible, onClose, onBack
</div>
</div>
{/* Qualifying Question Section */}
<div>
<h3 className="text-luxury-gold font-elegant-sans text-lg font-semibold mb-4 flex items-center">
<svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" />
</svg>
Tell Us About Your Goals
</h3>
<div>
<label className="block text-cream/90 font-elegant-sans text-sm font-medium mb-2">
What do you want to achieve with Pennyzo? <span className="text-red-400">*</span>
</label>
<textarea
value={formData.goals}
onChange={(e) => handleInputChange('goals', e.target.value)}
rows={4}
className={`w-full bg-deep-forest/50 border ${errors.goals ? 'border-red-400' : 'border-luxury-gold/20'} rounded-lg px-4 py-3 text-cream placeholder-cream/40 focus:outline-none focus:ring-2 focus:ring-luxury-gold/50 focus:border-luxury-gold/50 transition-all duration-300 font-elegant-sans resize-none`}
placeholder="Tell us about your business goals, challenges you're facing, or what you hope to achieve with our platform..."
/>
{errors.goals && (
<p className="text-red-400 text-xs mt-1 font-elegant-sans">{errors.goals}</p>
)}
</div>
</div>
{/* Submit Button */}
<div className="pt-4">
<button

View File

@@ -6,3 +6,21 @@
html {
scroll-behavior: smooth;
}
/* Running golden line animation - horizontal */
@keyframes slide-right {
0% {
transform: translateX(-100%);
opacity: 0;
}
10% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
transform: translateX(400%);
opacity: 0;
}
}