Apply Limelite dark crimson theme to the application

This commit is contained in:
2026-09-22 13:31:41 +05:30
parent fc720f5393
commit 45d13fa7be
6 changed files with 88 additions and 97 deletions
+34 -34
View File
@@ -102,7 +102,7 @@ const AnalysisResultPage = () => {
if (!score && score !== 0) return 'bg-gray-600'; if (!score && score !== 0) return 'bg-gray-600';
if (score >= 70) return 'bg-emerald-500'; if (score >= 70) return 'bg-emerald-500';
if (score >= 40) return 'bg-yellow-500'; if (score >= 40) return 'bg-yellow-500';
return 'bg-[#0097C3]'; return 'bg-[limelite-red]';
}; };
const getMetricDisplayName = (metricKey) => { const getMetricDisplayName = (metricKey) => {
@@ -469,7 +469,7 @@ const AnalysisResultPage = () => {
if (isLoading) return ( if (isLoading) return (
<div className="min-h-screen flex items-center justify-center"> <div className="min-h-screen flex items-center justify-center">
<div className="flex flex-col items-center gap-4"> <div className="flex flex-col items-center gap-4">
<div className="w-12 h-12 border-4 border-white/10 border-t-[#0097C3] rounded-full animate-spin"></div> <div className="w-12 h-12 border-4 border-white/10 border-t-[limelite-red] rounded-full animate-spin"></div>
<p className="text-gray-300 animate-pulse">Analyzing skin profile...</p> <p className="text-gray-300 animate-pulse">Analyzing skin profile...</p>
</div> </div>
</div> </div>
@@ -478,12 +478,12 @@ const AnalysisResultPage = () => {
if (error) return ( if (error) return (
<div className="min-h-screen flex items-center justify-center p-4"> <div className="min-h-screen flex items-center justify-center p-4">
<div className="glass-panel p-8 rounded-none shadow-xl max-w-md w-full text-center border border-white/10"> <div className="glass-panel p-8 rounded-none shadow-xl max-w-md w-full text-center border border-white/10">
<div className="w-16 h-16 bg-[#0097C3]/20 rounded-none flex items-center justify-center mx-auto mb-4"> <div className="w-16 h-16 bg-[limelite-red]/20 rounded-none flex items-center justify-center mx-auto mb-4">
<svg className="w-8 h-8 text-[#0097C3]" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg> <svg className="w-8 h-8 text-[limelite-red]" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
</div> </div>
<h2 className="text-xl font-bold text-white mb-2">Analysis Failed</h2> <h2 className="text-xl font-bold text-white mb-2">Analysis Failed</h2>
<p className="text-gray-300 mb-6">{errorDescriptions[error] || error}</p> <p className="text-gray-300 mb-6">{errorDescriptions[error] || error}</p>
<button onClick={handleNewAnalysis} className="w-full py-3 bg-[#0097C3] hover:bg-[#007ba0] text-white rounded-none font-bold transition-colors shadow-lg shadow-[#0097C3]/30"> <button onClick={handleNewAnalysis} className="w-full py-3 bg-[limelite-red] hover:bg-[limelite-maroon] text-white rounded-none font-bold transition-colors shadow-lg shadow-[limelite-red]/30">
Try Again Try Again
</button> </button>
</div> </div>
@@ -494,7 +494,7 @@ const AnalysisResultPage = () => {
<div className="min-h-screen flex items-center justify-center"> <div className="min-h-screen flex items-center justify-center">
<div className="text-center"> <div className="text-center">
<p className="text-gray-300 mb-4">No analysis data available.</p> <p className="text-gray-300 mb-4">No analysis data available.</p>
<button onClick={handleNewAnalysis} className="px-6 py-2 bg-[#0097C3] text-white rounded-none shadow-lg">Start New Analysis</button> <button onClick={handleNewAnalysis} className="px-6 py-2 bg-[limelite-red] text-white rounded-none shadow-lg">Start New Analysis</button>
</div> </div>
</div> </div>
); );
@@ -530,7 +530,7 @@ const AnalysisResultPage = () => {
<div className="h-screen overflow-hidden bg-[#18181b] font-sans relative flex flex-col"> <div className="h-screen overflow-hidden bg-[#18181b] font-sans relative flex flex-col">
{/* Header (Matching App.js) */} {/* Header (Matching App.js) */}
<header className="fixed top-0 left-0 right-0 z-50 py-4 px-6 flex items-center justify-between bg-[#0097C3] shadow-lg"> <header className="fixed top-0 left-0 right-0 z-50 py-4 px-6 flex items-center justify-between bg-[limelite-red] shadow-lg">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite Logo" className="h-12 md:h-16 w-auto brightness-0 invert" /> <img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite Logo" className="h-12 md:h-16 w-auto brightness-0 invert" />
</div> </div>
@@ -574,7 +574,7 @@ const AnalysisResultPage = () => {
{activeMask && ( {activeMask && (
<button <button
onClick={handleClearMask} onClick={handleClearMask}
className="text-white hover:text-[#0097C3] transition-colors flex items-center mb-2" className="text-white hover:text-[limelite-red] transition-colors flex items-center mb-2"
title="Show original image" title="Show original image"
> >
<svg className="w-7 h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg className="w-7 h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
@@ -608,7 +608,7 @@ const AnalysisResultPage = () => {
{/* Badge */} {/* Badge */}
<div className={`px-3 py-1 rounded-full text-[11px] font-bold uppercase min-w-[65px] text-center ${metric.ui_score >= 70 ? 'bg-emerald-500/20 text-[#4ade80] border border-emerald-500/30' : <div className={`px-3 py-1 rounded-full text-[11px] font-bold uppercase min-w-[65px] text-center ${metric.ui_score >= 70 ? 'bg-emerald-500/20 text-[#4ade80] border border-emerald-500/30' :
metric.ui_score >= 40 ? 'bg-amber-500/20 text-[#fbbf24] border border-amber-500/30' : metric.ui_score >= 40 ? 'bg-amber-500/20 text-[#fbbf24] border border-amber-500/30' :
'bg-[#0097C3]/20 text-[#0097C3] border border-[#0097C3]/30' 'bg-[limelite-red]/20 text-[limelite-red] border border-[limelite-red]/30'
}`}> }`}>
{metric.ui_score >= 70 ? 'Good' : metric.ui_score >= 40 ? 'Average' : 'Bad'} {metric.ui_score >= 70 ? 'Good' : metric.ui_score >= 40 ? 'Average' : 'Bad'}
</div> </div>
@@ -631,7 +631,7 @@ const AnalysisResultPage = () => {
<div className="bg-[#18181b] px-5 py-6 flex flex-col gap-4 relative z-30 shrink-0 border-t border-white/10"> <div className="bg-[#18181b] px-5 py-6 flex flex-col gap-4 relative z-30 shrink-0 border-t border-white/10">
<button <button
onClick={() => setShowSignupModal(true)} onClick={() => setShowSignupModal(true)}
className="w-full bg-[#0097C3] hover:bg-[#007ba0] text-white h-14 rounded-none font-bold text-lg shadow-sm flex items-center justify-center gap-3 transition-all transform active:scale-95 relative" className="w-full bg-[limelite-red] hover:bg-[limelite-maroon] text-white h-14 rounded-none font-bold text-lg shadow-sm flex items-center justify-center gap-3 transition-all transform active:scale-95 relative"
> >
<span className="text-[1.1rem]">Access Full Report</span> <span className="text-[1.1rem]">Access Full Report</span>
<div className="w-6 h-6 bg-white/20 rounded-full flex items-center justify-center"> <div className="w-6 h-6 bg-white/20 rounded-full flex items-center justify-center">
@@ -646,7 +646,7 @@ const AnalysisResultPage = () => {
<div className="bg-[#18181b] px-5 py-6 flex flex-col gap-4 relative z-30 shrink-0 border-t border-white/10"> <div className="bg-[#18181b] px-5 py-6 flex flex-col gap-4 relative z-30 shrink-0 border-t border-white/10">
<button <button
onClick={handleDownloadPDF} onClick={handleDownloadPDF}
className="w-full bg-[#0097C3] hover:bg-[#007ba0] text-white h-14 rounded-none font-bold text-lg shadow-sm flex items-center justify-center gap-3 transition-all transform active:scale-95 relative" className="w-full bg-[limelite-red] hover:bg-[limelite-maroon] text-white h-14 rounded-none font-bold text-lg shadow-sm flex items-center justify-center gap-3 transition-all transform active:scale-95 relative"
> >
<span className="text-[1.1rem]">Download Report</span> <span className="text-[1.1rem]">Download Report</span>
<div className="w-6 h-6 bg-white/20 rounded-full flex items-center justify-center"> <div className="w-6 h-6 bg-white/20 rounded-full flex items-center justify-center">
@@ -680,36 +680,36 @@ const AnalysisResultPage = () => {
<div className="flex flex-col gap-6"> <div className="flex flex-col gap-6">
<div> <div>
<label className="block text-gray-700 text-sm font-medium mb-1"> <label className="block text-gray-700 text-sm font-medium mb-1">
Full Name<span className="text-[#0097C3]">*</span> Full Name<span className="text-[limelite-red]">*</span>
</label> </label>
<input <input
type="text" type="text"
placeholder="Enter your First Name" placeholder="Enter your First Name"
value={formData.name} value={formData.name}
onChange={handleNameChange} onChange={handleNameChange}
className={`w-full border-b border-dashed py-2 text-base text-black placeholder-gray-400 focus:outline-none transition-colors bg-transparent ${formErrors.name ? 'border-[#0097C3]' : 'border-gray-400 focus:border-[#0097C3]'}`} className={`w-full border-b border-dashed py-2 text-base text-black placeholder-gray-400 focus:outline-none transition-colors bg-transparent ${formErrors.name ? 'border-[limelite-red]' : 'border-gray-400 focus:border-[limelite-red]'}`}
/> />
{formErrors.name && <p className="text-[#0097C3] text-xs mt-1">{formErrors.name}</p>} {formErrors.name && <p className="text-[limelite-red] text-xs mt-1">{formErrors.name}</p>}
</div> </div>
<div> <div>
<label className="block text-gray-700 text-sm font-medium mb-1"> <label className="block text-gray-700 text-sm font-medium mb-1">
Whatsapp Number<span className="text-[#0097C3]">*</span> Whatsapp Number<span className="text-[limelite-red]">*</span>
</label> </label>
<input <input
type="tel" type="tel"
placeholder="Enter your Whatsapp Number" placeholder="Enter your Whatsapp Number"
value={formData.phone} value={formData.phone}
onChange={handlePhoneChange} onChange={handlePhoneChange}
className={`w-full border-b border-dashed py-2 text-base text-black placeholder-gray-400 focus:outline-none transition-colors bg-transparent ${formErrors.phone ? 'border-[#0097C3]' : 'border-gray-400 focus:border-[#0097C3]'}`} className={`w-full border-b border-dashed py-2 text-base text-black placeholder-gray-400 focus:outline-none transition-colors bg-transparent ${formErrors.phone ? 'border-[limelite-red]' : 'border-gray-400 focus:border-[limelite-red]'}`}
/> />
{formErrors.phone && <p className="text-[#0097C3] text-[13px] mt-2 font-medium leading-tight">{formErrors.phone}</p>} {formErrors.phone && <p className="text-[limelite-red] text-[13px] mt-2 font-medium leading-tight">{formErrors.phone}</p>}
</div> </div>
<button <button
onClick={handleSignupSubmit} onClick={handleSignupSubmit}
disabled={isSubmittingSignup} disabled={isSubmittingSignup}
className="w-full bg-[#0097C3] hover:bg-[#007ba0] text-white py-3 font-semibold text-lg mt-4 transition-colors disabled:opacity-70 flex items-center justify-center h-14" className="w-full bg-[limelite-red] hover:bg-[limelite-maroon] text-white py-3 font-semibold text-lg mt-4 transition-colors disabled:opacity-70 flex items-center justify-center h-14"
> >
{isSubmittingSignup ? ( {isSubmittingSignup ? (
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
@@ -748,7 +748,7 @@ const AnalysisResultPage = () => {
<div className="flex justify-between gap-2 mb-8"> <div className="flex justify-between gap-2 mb-8">
{otp.map((data, index) => ( {otp.map((data, index) => (
<input <input
className="w-11 h-11 border border-gray-300 rounded-md text-center text-xl focus:border-[#0097C3] focus:outline-none font-medium text-black" className="w-11 h-11 border border-gray-300 rounded-md text-center text-xl focus:border-[limelite-red] focus:outline-none font-medium text-black"
type="text" type="text"
name="otp" name="otp"
maxLength="1" maxLength="1"
@@ -760,12 +760,12 @@ const AnalysisResultPage = () => {
))} ))}
</div> </div>
{otpError && <p className="text-[#0097C3] text-sm mb-4 text-center">{otpError}</p>} {otpError && <p className="text-[limelite-red] text-sm mb-4 text-center">{otpError}</p>}
<button <button
onClick={handleVerifyOtp} onClick={handleVerifyOtp}
disabled={isVerifying} disabled={isVerifying}
className="w-full bg-[#0097C3] hover:bg-[#007ba0] text-white py-4 font-semibold text-lg transition-colors disabled:opacity-70 flex items-center justify-center" className="w-full bg-[limelite-red] hover:bg-[limelite-maroon] text-white py-4 font-semibold text-lg transition-colors disabled:opacity-70 flex items-center justify-center"
> >
{isVerifying ? ( {isVerifying ? (
<div className="w-6 h-6 border-2 border-white/30 border-t-white rounded-full animate-spin"></div> <div className="w-6 h-6 border-2 border-white/30 border-t-white rounded-full animate-spin"></div>
@@ -813,9 +813,9 @@ const AnalysisResultPage = () => {
{/* Toast Notification */} {/* Toast Notification */}
{toast.show && ( {toast.show && (
<div className="fixed top-24 right-6 z-[200] animate-[fadeIn_0.3s_ease-out]"> <div className="fixed top-24 right-6 z-[200] animate-[fadeIn_0.3s_ease-out]">
<div className="bg-white text-[#0097C3] px-6 py-4 shadow-[0_10px_40px_rgba(0,0,0,0.15)] flex items-center gap-3 border-l-4 border-[#0097C3]"> <div className="bg-white text-[limelite-red] px-6 py-4 shadow-[0_10px_40px_rgba(0,0,0,0.15)] flex items-center gap-3 border-l-4 border-[limelite-red]">
<div className="bg-[#0097C3]/10 p-1.5 rounded-full"> <div className="bg-[limelite-red]/10 p-1.5 rounded-full">
<svg className="w-5 h-5 text-[#0097C3]" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg className="w-5 h-5 text-[limelite-red]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
</svg> </svg>
</div> </div>
@@ -844,13 +844,13 @@ const AnalysisResultPage = () => {
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} style={{ height: '45px', objectFit: 'contain' }} alt="Logo" /> <img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} style={{ height: '45px', objectFit: 'contain' }} alt="Logo" />
</div> </div>
<div style={{ flex: 1, textAlign: 'center' }}> <div style={{ flex: 1, textAlign: 'center' }}>
<h1 style={{ fontSize: '28px', fontWeight: '900', margin: 0, textTransform: 'uppercase', letterSpacing: '0.02em', color: '#0097C3', fontFamily: "'Playfair Display', serif" }}>Face Analysis Report</h1> <h1 style={{ fontSize: '28px', fontWeight: '900', margin: 0, textTransform: 'uppercase', letterSpacing: '0.02em', color: 'limelite-red', fontFamily: "'Playfair Display', serif" }}>Face Analysis Report</h1>
</div> </div>
<div style={{ width: '120px' }}></div> <div style={{ width: '120px' }}></div>
</div> </div>
{/* Accent Line */} {/* Accent Line */}
<div style={{ height: '2px', backgroundColor: '#0097C3', marginBottom: '25px' }}></div> <div style={{ height: '2px', backgroundColor: 'limelite-red', marginBottom: '25px' }}></div>
{/* Info Row (Name, Phone, Date) */} {/* Info Row (Name, Phone, Date) */}
<div style={{ backgroundColor: '#f3f4f6', padding: '18px 25px', display: 'flex', justifyContent: 'space-between', marginBottom: '30px' }}> <div style={{ backgroundColor: '#f3f4f6', padding: '18px 25px', display: 'flex', justifyContent: 'space-between', marginBottom: '30px' }}>
@@ -882,7 +882,7 @@ const AnalysisResultPage = () => {
width: '100%', width: '100%',
height: '320px', height: '320px',
overflow: 'hidden', overflow: 'hidden',
border: '4px solid #0097C3' border: '4px solid limelite-red'
}}> }}>
<img src={analysisData?.originalImage} style={{ width: '100%', height: '100%', objectFit: 'cover' }} alt="Original Scan" /> <img src={analysisData?.originalImage} style={{ width: '100%', height: '100%', objectFit: 'cover' }} alt="Original Scan" />
</div> </div>
@@ -890,7 +890,7 @@ const AnalysisResultPage = () => {
position: 'absolute', position: 'absolute',
bottom: '15px', bottom: '15px',
right: '15px', right: '15px',
backgroundColor: '#0097C3', backgroundColor: 'limelite-red',
color: '#fff', color: '#fff',
padding: '6px 15px', padding: '6px 15px',
fontSize: '10px', fontSize: '10px',
@@ -903,7 +903,7 @@ const AnalysisResultPage = () => {
<div style={{ flex: '0.6', display: 'flex', flexDirection: 'column' }}> <div style={{ flex: '0.6', display: 'flex', flexDirection: 'column' }}>
<div style={{ <div style={{
flex: 1, flex: 1,
backgroundColor: '#0097C3', backgroundColor: 'limelite-red',
color: '#fff', color: '#fff',
padding: '20px 15px', padding: '20px 15px',
display: 'flex', display: 'flex',
@@ -933,7 +933,7 @@ const AnalysisResultPage = () => {
alignItems: 'center', alignItems: 'center',
gap: '10px' gap: '10px'
}}> }}>
<span style={{ height: '15px', width: '15px', display: 'inline-block', border: '3px solid #0097C3' }}></span> <span style={{ height: '15px', width: '15px', display: 'inline-block', border: '3px solid limelite-red' }}></span>
Diagnostic Deep-Dive Diagnostic Deep-Dive
</h2> </h2>
@@ -958,7 +958,7 @@ const AnalysisResultPage = () => {
<div style={{ <div style={{
width: `${metric.ui_score}%`, width: `${metric.ui_score}%`,
height: '100%', height: '100%',
backgroundColor: metric.ui_score >= 70 ? '#10b981' : metric.ui_score >= 40 ? '#f59e0b' : '#0097C3' backgroundColor: metric.ui_score >= 70 ? '#10b981' : metric.ui_score >= 40 ? '#f59e0b' : 'limelite-red'
}}></div> }}></div>
</div> </div>
</div> </div>
@@ -977,15 +977,15 @@ const AnalysisResultPage = () => {
<h3 style={{ margin: '0 0 15px 0', fontSize: '14px', fontWeight: '900', color: '#1a1a1a', textTransform: 'uppercase', letterSpacing: '1px' }}>Prescriptive Guidance</h3> <h3 style={{ margin: '0 0 15px 0', fontSize: '14px', fontWeight: '900', color: '#1a1a1a', textTransform: 'uppercase', letterSpacing: '1px' }}>Prescriptive Guidance</h3>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '15px' }}> <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '15px' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
<span style={{ fontSize: '10px', fontWeight: '900', color: '#0097C3' }}>STEP 01</span> <span style={{ fontSize: '10px', fontWeight: '900', color: 'limelite-red' }}>STEP 01</span>
<p style={{ margin: 0, fontSize: '11px', color: '#555', lineHeight: '1.5' }}><strong>Advanced Hydration:</strong> Apply hyaluronic acid serum daily to stabilize moisture levels.</p> <p style={{ margin: 0, fontSize: '11px', color: '#555', lineHeight: '1.5' }}><strong>Advanced Hydration:</strong> Apply hyaluronic acid serum daily to stabilize moisture levels.</p>
</div> </div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
<span style={{ fontSize: '10px', fontWeight: '900', color: '#0097C3' }}>STEP 02</span> <span style={{ fontSize: '10px', fontWeight: '900', color: 'limelite-red' }}>STEP 02</span>
<p style={{ margin: 0, fontSize: '11px', color: '#555', lineHeight: '1.5' }}><strong>Dermal Protection:</strong> Broad-spectrum physical sunshade is mandatory for UV protection.</p> <p style={{ margin: 0, fontSize: '11px', color: '#555', lineHeight: '1.5' }}><strong>Dermal Protection:</strong> Broad-spectrum physical sunshade is mandatory for UV protection.</p>
</div> </div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
<span style={{ fontSize: '10px', fontWeight: '900', color: '#0097C3' }}>STEP 03</span> <span style={{ fontSize: '10px', fontWeight: '900', color: 'limelite-red' }}>STEP 03</span>
<p style={{ margin: 0, fontSize: '11px', color: '#555', lineHeight: '1.5' }}><strong>Clinical Intervention:</strong> Visit your specialist for focused treatment on top priority zones.</p> <p style={{ margin: 0, fontSize: '11px', color: '#555', lineHeight: '1.5' }}><strong>Clinical Intervention:</strong> Visit your specialist for focused treatment on top priority zones.</p>
</div> </div>
</div> </div>
+31 -48
View File
@@ -41,7 +41,7 @@ const App = () => {
// --- Load skin-api models --- // --- Load skin-api models ---
useEffect(() => { useEffect(() => {
console.log(`%c Build Version: ${buildInfo.version} | Date: ${buildInfo.date}`, 'color: #0097C3; font-weight: bold; font-size: 14px;'); console.log(`%c Build Version: ${buildInfo.version} | Date: ${buildInfo.date}`, 'color: limelite-red; font-weight: bold; font-size: 14px;');
const loadModels = async () => { const loadModels = async () => {
await Promise.all([ await Promise.all([
skinapi.nets.tinyFaceDetector.loadFromUri(process.env.PUBLIC_URL + '/models'), skinapi.nets.tinyFaceDetector.loadFromUri(process.env.PUBLIC_URL + '/models'),
@@ -391,13 +391,13 @@ const App = () => {
// --- Render --- // --- Render ---
return ( return (
<div className="min-h-screen relative overflow-hidden bg-[#F8F9FA]"> <div className="min-h-screen relative overflow-hidden bg-gradient-to-r from-limelite-maroon to-limelite-dark text-white">
<div className="container mx-auto px-4 py-10 md:py-16 relative z-10 min-h-screen flex flex-col items-center justify-start gap-4 md:gap-8"> <div className="container mx-auto px-4 py-10 md:py-16 relative z-10 min-h-screen flex flex-col items-center justify-start gap-4 md:gap-8">
{/* Header */} {/* Header */}
<header className="fixed top-0 left-0 right-0 z-[60] py-4 px-6 flex items-center justify-between bg-[#0097C3] shadow-lg"> <header className="fixed top-0 left-0 right-0 z-[60] py-4 px-6 flex items-center justify-between bg-[limelite-red] shadow-lg">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite Logo" className="h-12 md:h-16 w-auto brightness-0 invert" /> <img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite Logo" className="h-12 md:h-16 w-auto " />
</div> </div>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
@@ -444,62 +444,45 @@ const App = () => {
{view === 'landing' && ( {view === 'landing' && (
<div className="flex flex-col items-center justify-center w-full px-4 gap-8 fade-in mt-20 md:mt-32"> <div className="flex flex-col items-center justify-center w-full px-4 gap-8 fade-in mt-20 md:mt-32">
<div className="text-center space-y-4 mb-2"> <div className="text-center space-y-4 mb-2">
<h1 className="text-4xl md:text-5xl font-bold text-[#0e5e73] leading-tight tracking-[0.02em] uppercase" style={{ fontFamily: "'Oswald', sans-serif" }}> <h1 className="text-4xl md:text-5xl font-serif italic text-white leading-tight tracking-[0.02em]">
AI-POWERED<br />FACE ANALYZER Step into your style
</h1> </h1>
<p className="text-lg text-gray-700 font-medium tracking-wide max-w-sm mx-auto"> <p className="text-xs text-gray-300 font-sans font-bold tracking-widest uppercase mt-4 max-w-sm mx-auto">
Experience professional-grade face analysis in seconds Select your action to begin
</p> </p>
</div> </div>
{/* Action Buttons Container */} {/* Action Buttons Container */}
<div className="w-full flex flex-col gap-4"> <div className="w-full flex flex-row items-center justify-center gap-4 max-w-md mx-auto">
{/* Take Photo Card */} {/* Take Photo Card */}
<div <button
onClick={() => setView('camera')} onClick={() => setView('camera')}
className="bg-white border-2 border-dashed border-[#0097C3]/30 p-8 flex flex-col items-center justify-center gap-4 cursor-pointer hover:border-[#0097C3] transition-all duration-300 shadow-xl group" className="flex-1 bg-white text-[#1A1A1A] rounded-xl px-8 py-4 font-bold text-sm tracking-widest uppercase shadow-lg hover:bg-gray-100 transition-all text-center border-2 border-transparent"
> >
<div className="w-16 h-16 bg-[#0097C3]/10 rounded-full flex items-center justify-center group-hover:scale-110 transition-transform"> Take Photo
<svg className="w-8 h-8 text-[#0097C3]" fill="none" viewBox="0 0 24 24" stroke="currentColor"> </button>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" />
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
</div>
<div className="text-center">
<p className="text-xl font-bold text-black uppercase tracking-widest">Take a Photo</p>
<p className="text-gray-500 text-sm mt-1">Capture using your camera</p>
</div>
</div>
{/* Upload Photo Card */} {/* Upload Photo Card */}
<div <button
onClick={() => document.getElementById('uploadInput').click()} onClick={() => document.getElementById('uploadInput').click()}
className="bg-white border-2 border-dashed border-[#0097C3]/30 p-8 flex flex-col items-center justify-center gap-4 cursor-pointer hover:border-[#0097C3] transition-all duration-300 shadow-xl group" className="flex-1 bg-[#1A1A1A] text-white border border-gray-700 rounded-xl px-8 py-4 font-bold text-sm tracking-widest uppercase shadow-lg hover:bg-black transition-all text-center"
> >
<div className="w-16 h-16 bg-[#0097C3]/10 rounded-full flex items-center justify-center group-hover:scale-110 transition-transform"> Upload Photo
<svg className="w-8 h-8 text-[#0097C3]" fill="none" viewBox="0 0 24 24" stroke="currentColor"> </button>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" /> <input
</svg> type="file"
</div> id="uploadInput"
<div className="text-center"> accept="image/*"
<p className="text-xl font-bold text-black uppercase tracking-widest">Upload Photo</p> className="hidden"
<p className="text-gray-500 text-sm mt-1">Select from your gallery</p> onChange={handleFileUpload}
</div> />
<input
type="file"
id="uploadInput"
accept="image/*"
className="hidden"
onChange={handleFileUpload}
/>
</div>
</div> </div>
{/* Admin Link */} {/* Admin Link */}
<div className="mt-8"> <div className="mt-8">
<button <button
onClick={() => navigate('/login')} onClick={() => navigate('/login')}
className="text-gray-400 hover:text-[#0097C3] transition-colors text-xs uppercase tracking-widest font-bold" className="text-gray-400 hover:text-[limelite-red] transition-colors text-xs uppercase tracking-widest font-bold"
> >
Admin Login Admin Login
</button> </button>
@@ -521,7 +504,7 @@ const App = () => {
<div className="absolute bottom-12 left-0 right-0 flex justify-center items-center z-20"> <div className="absolute bottom-12 left-0 right-0 flex justify-center items-center z-20">
<button <button
onClick={handleCaptureskin} onClick={handleCaptureskin}
className="transform active:scale-95 transition-all cursor-pointer bg-[#0097C3] w-36 h-18 py-4 px-10 rounded-full shadow-[0_0_20px_rgba(0,151,195,0.3)] flex items-center justify-center border-none" className="transform active:scale-95 transition-all cursor-pointer bg-[limelite-red] w-36 h-18 py-4 px-10 rounded-full shadow-[0_0_20px_rgba(0,151,195,0.3)] flex items-center justify-center border-none"
> >
<IoMdAperture className="w-12 h-12 text-white" /> <IoMdAperture className="w-12 h-12 text-white" />
</button> </button>
@@ -545,8 +528,8 @@ const App = () => {
{/* Scanning Animation only when loading */} {/* Scanning Animation only when loading */}
{isLoading && ( {isLoading && (
<div className="absolute inset-0 z-20 pointer-events-none overflow-hidden"> <div className="absolute inset-0 z-20 pointer-events-none overflow-hidden">
<div className="w-full h-[2px] bg-[#0097C3] shadow-[0_0_20px_rgba(0,151,195,0.8)] absolute top-0 animate-[scan_3s_linear_infinite]"></div> <div className="w-full h-[2px] bg-[limelite-red] shadow-[0_0_20px_rgba(0,151,195,0.8)] absolute top-0 animate-[scan_3s_linear_infinite]"></div>
<div className="w-full h-32 bg-gradient-to-t from-[#0097C3]/20 to-transparent absolute top-0 -translate-y-full animate-[scanTrace_3s_linear_infinite]"></div> <div className="w-full h-32 bg-gradient-to-t from-[limelite-red]/20 to-transparent absolute top-0 -translate-y-full animate-[scanTrace_3s_linear_infinite]"></div>
</div> </div>
)} )}
@@ -570,7 +553,7 @@ const App = () => {
<button <button
onClick={handleSubmitClick} onClick={handleSubmitClick}
disabled={isLoading} disabled={isLoading}
className="h-14 w-20 bg-[#0097C3] text-white rounded-none flex items-center justify-center shadow-lg hover:bg-[#007ba0] transition-all active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed" className="h-14 w-20 bg-[limelite-red] text-white rounded-none flex items-center justify-center shadow-lg hover:bg-[limelite-maroon] transition-all active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed"
aria-label="Confirm" aria-label="Confirm"
> >
<svg xmlns="http://www.w3.org/2000/svg" className="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg xmlns="http://www.w3.org/2000/svg" className="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
@@ -590,7 +573,7 @@ const App = () => {
<div className="fixed inset-0 z-[100] flex items-center justify-center bg-black/80 backdrop-blur-sm p-6 animate-[fadeIn_0.2s_ease-out]"> <div className="fixed inset-0 z-[100] flex items-center justify-center bg-black/80 backdrop-blur-sm p-6 animate-[fadeIn_0.2s_ease-out]">
<div className="bg-white rounded-none shadow-2xl w-full max-w-sm p-8 text-center"> <div className="bg-white rounded-none shadow-2xl w-full max-w-sm p-8 text-center">
<div className="w-16 h-16 bg-cyan-100 rounded-full flex items-center justify-center mx-auto mb-6"> <div className="w-16 h-16 bg-cyan-100 rounded-full flex items-center justify-center mx-auto mb-6">
<svg className="w-8 h-8 text-[#0097C3]" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg className="w-8 h-8 text-[limelite-red]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg> </svg>
</div> </div>
@@ -603,7 +586,7 @@ const App = () => {
</p> </p>
<button <button
onClick={handleRetakeClick} onClick={handleRetakeClick}
className="w-full bg-[#0097C3] text-white font-bold py-4 px-6 rounded-none hover:bg-[#007ba0] transition-all active:scale-95 uppercase tracking-widest text-sm" className="w-full bg-[limelite-red] text-white font-bold py-4 px-6 rounded-none hover:bg-[limelite-maroon] transition-all active:scale-95 uppercase tracking-widest text-sm"
> >
Retake Photo Retake Photo
</button> </button>
+9 -9
View File
@@ -101,7 +101,7 @@ const DashboardPage = () => {
return ( return (
<div className="flex h-screen bg-[#F8F9FA] font-sans"> <div className="flex h-screen bg-[#F8F9FA] font-sans">
{/* Sidebar */} {/* Sidebar */}
<aside className="w-64 bg-[#0097C3] text-white flex flex-col shrink-0"> <aside className="w-64 bg-[limelite-red] text-white flex flex-col shrink-0">
<div className="p-6 mb-4"> <div className="p-6 mb-4">
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="LIMELITE" className="h-10 w-auto brightness-0 invert" /> <img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="LIMELITE" className="h-10 w-auto brightness-0 invert" />
</div> </div>
@@ -109,7 +109,7 @@ const DashboardPage = () => {
<nav className="flex-1 px-0 mt-4"> <nav className="flex-1 px-0 mt-4">
<div <div
onClick={() => setActiveTab('reports')} onClick={() => setActiveTab('reports')}
className={`flex items-center gap-3 px-6 py-4 cursor-pointer transition-colors ${activeTab === 'reports' ? 'bg-white text-[#0097C3]' : 'text-white hover:bg-white/10'}`} className={`flex items-center gap-3 px-6 py-4 cursor-pointer transition-colors ${activeTab === 'reports' ? 'bg-white text-[limelite-red]' : 'text-white hover:bg-white/10'}`}
> >
<HiOutlineDocumentText className="text-xl" /> <HiOutlineDocumentText className="text-xl" />
<span className="font-bold uppercase tracking-wider text-xs">Reports</span> <span className="font-bold uppercase tracking-wider text-xs">Reports</span>
@@ -126,14 +126,14 @@ const DashboardPage = () => {
<div className="px-0 space-y-0 mb-6 border-t border-white/10"> <div className="px-0 space-y-0 mb-6 border-t border-white/10">
<div <div
onClick={() => setActiveTab('settings')} onClick={() => setActiveTab('settings')}
className={`flex items-center gap-3 px-6 py-4 cursor-pointer transition-colors ${activeTab === 'settings' ? 'bg-white text-[#0097C3]' : 'text-white hover:bg-white/10'}`} className={`flex items-center gap-3 px-6 py-4 cursor-pointer transition-colors ${activeTab === 'settings' ? 'bg-white text-[limelite-red]' : 'text-white hover:bg-white/10'}`}
> >
<FiSettings className="text-xl" /> <FiSettings className="text-xl" />
<span className="font-bold uppercase tracking-wider text-xs">Settings</span> <span className="font-bold uppercase tracking-wider text-xs">Settings</span>
</div> </div>
<div className="hover:bg-white/10 text-white flex items-center gap-3 px-6 py-5 transition-colors cursor-pointer border-t border-white/10"> <div className="hover:bg-white/10 text-white flex items-center gap-3 px-6 py-5 transition-colors cursor-pointer border-t border-white/10">
<div className="flex items-center gap-3 w-full"> <div className="flex items-center gap-3 w-full">
<div className="w-10 h-10 bg-[#0086ad] rounded-full flex items-center justify-center overflow-hidden border border-white/30 text-white font-bold text-sm"> <div className="w-10 h-10 bg-[limelite-maroon] rounded-full flex items-center justify-center overflow-hidden border border-white/30 text-white font-bold text-sm">
LA LA
</div> </div>
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
@@ -166,7 +166,7 @@ const DashboardPage = () => {
<input <input
type="text" type="text"
placeholder="Search" placeholder="Search"
className="w-full bg-gray-50 border border-gray-200 rounded-lg py-2 pl-10 pr-4 focus:outline-none focus:ring-1 focus:ring-[#0097C3] text-sm text-gray-900" className="w-full bg-gray-50 border border-gray-200 rounded-lg py-2 pl-10 pr-4 focus:outline-none focus:ring-1 focus:ring-[limelite-red] text-sm text-gray-900"
value={searchTerm} value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)} onChange={(e) => setSearchTerm(e.target.value)}
/> />
@@ -199,7 +199,7 @@ const DashboardPage = () => {
<td className="px-6 py-4 text-sm text-gray-500 font-medium">{(currentPage - 1) * ITEMS_PER_PAGE + index + 1}</td> <td className="px-6 py-4 text-sm text-gray-500 font-medium">{(currentPage - 1) * ITEMS_PER_PAGE + index + 1}</td>
<td className="px-6 py-4 text-sm font-medium text-gray-700">{report.name}</td> <td className="px-6 py-4 text-sm font-medium text-gray-700">{report.name}</td>
<td className="px-6 py-4 text-sm text-gray-500">{report.phone}</td> <td className="px-6 py-4 text-sm text-gray-500">{report.phone}</td>
<td className="px-6 py-4 text-sm text-[#0097C3] font-semibold truncate max-w-[200px]"> <td className="px-6 py-4 text-sm text-[limelite-red] font-semibold truncate max-w-[200px]">
<a href={report.link} target="_blank" rel="noopener noreferrer" className="hover:underline"> <a href={report.link} target="_blank" rel="noopener noreferrer" className="hover:underline">
{report.link ? report.link.substring(report.link.indexOf('result')) : '-'} {report.link ? report.link.substring(report.link.indexOf('result')) : '-'}
</a> </a>
@@ -244,7 +244,7 @@ const DashboardPage = () => {
<label className="text-sm font-bold text-gray-700 uppercase">Site Name</label> <label className="text-sm font-bold text-gray-700 uppercase">Site Name</label>
<input <input
type="text" type="text"
className="col-span-2 border-b-2 py-2 focus:outline-none focus:border-[#0097C3] transition-colors" className="col-span-2 border-b-2 py-2 focus:outline-none focus:border-[limelite-red] transition-colors"
value={settings.siteName} value={settings.siteName}
onChange={(e) => setSettings({ ...settings, siteName: e.target.value })} onChange={(e) => setSettings({ ...settings, siteName: e.target.value })}
/> />
@@ -280,14 +280,14 @@ const DashboardPage = () => {
</div> </div>
<button <button
onClick={() => setSettings({ ...settings, autoArchive: !settings.autoArchive })} onClick={() => setSettings({ ...settings, autoArchive: !settings.autoArchive })}
className={`w-12 h-6 rounded-full transition-colors relative ${settings.autoArchive ? 'bg-[#0097C3]' : 'bg-gray-300'}`} className={`w-12 h-6 rounded-full transition-colors relative ${settings.autoArchive ? 'bg-[limelite-red]' : 'bg-gray-300'}`}
> >
<div className={`absolute top-1 bg-white w-4 h-4 rounded-full transition-transform ${settings.autoArchive ? 'translate-x-7' : 'translate-x-1'}`}></div> <div className={`absolute top-1 bg-white w-4 h-4 rounded-full transition-transform ${settings.autoArchive ? 'translate-x-7' : 'translate-x-1'}`}></div>
</button> </button>
</div> </div>
<div className="pt-6"> <div className="pt-6">
<button className="bg-[#0097C3] text-white px-8 py-3 font-bold uppercase tracking-widest hover:bg-[#007ba0] transition-colors"> <button className="bg-[limelite-red] text-white px-8 py-3 font-bold uppercase tracking-widest hover:bg-[limelite-maroon] transition-colors">
Save Changes Save Changes
</button> </button>
</div> </div>
+5 -5
View File
@@ -23,12 +23,12 @@ const LoginPage = () => {
<div className="min-h-screen bg-[#18181b] flex items-center justify-center p-4 font-sans"> <div className="min-h-screen bg-[#18181b] flex items-center justify-center p-4 font-sans">
<div className="bg-white w-full max-w-md p-10 shadow-2xl rounded-none"> <div className="bg-white w-full max-w-md p-10 shadow-2xl rounded-none">
<div className="flex flex-col items-center mb-10"> <div className="flex flex-col items-center mb-10">
<div className="bg-[#0097C3] p-4 mb-6"> <div className="bg-[limelite-red] p-4 mb-6">
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite" className="h-8 brightness-0 invert" /> <img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite" className="h-8 brightness-0 invert" />
</div> </div>
</div> </div>
{error && <p className="text-[#0097C3] text-sm font-bold text-center mb-6 animate-shake">{error}</p>} {error && <p className="text-[limelite-red] text-sm font-bold text-center mb-6 animate-shake">{error}</p>}
<form onSubmit={handleSubmit} className="space-y-6"> <form onSubmit={handleSubmit} className="space-y-6">
<div> <div>
@@ -36,7 +36,7 @@ const LoginPage = () => {
<input <input
type="email" type="email"
required required
className="w-full border-b-2 border-gray-200 py-3 focus:outline-none focus:border-[#0097C3] transition-colors text-black" className="w-full border-b-2 border-gray-200 py-3 focus:outline-none focus:border-[limelite-red] transition-colors text-black"
placeholder="olivia@limelite.com" placeholder="olivia@limelite.com"
value={credentials.email} value={credentials.email}
onChange={(e) => setCredentials({ ...credentials, email: e.target.value })} onChange={(e) => setCredentials({ ...credentials, email: e.target.value })}
@@ -48,7 +48,7 @@ const LoginPage = () => {
<input <input
type={showPassword ? "text" : "password"} type={showPassword ? "text" : "password"}
required required
className="w-full border-b-2 border-gray-200 py-3 pr-10 focus:outline-none focus:border-[#0097C3] transition-colors text-black" className="w-full border-b-2 border-gray-200 py-3 pr-10 focus:outline-none focus:border-[limelite-red] transition-colors text-black"
placeholder="••••••••" placeholder="••••••••"
value={credentials.password} value={credentials.password}
onChange={(e) => setCredentials({ ...credentials, password: e.target.value })} onChange={(e) => setCredentials({ ...credentials, password: e.target.value })}
@@ -64,7 +64,7 @@ const LoginPage = () => {
</div> </div>
<button <button
type="submit" type="submit"
className="w-full bg-[#0097C3] text-white py-4 font-bold uppercase tracking-widest hover:bg-[#007ba0] transition-colors mt-4" className="w-full bg-[limelite-red] text-white py-4 font-bold uppercase tracking-widest hover:bg-[limelite-maroon] transition-colors mt-4"
> >
Login Login
</button> </button>
+1 -1
View File
@@ -105,7 +105,7 @@ const UploadAnalysis = ({ originalImageUrl }) => {
fontSize: "16px", fontSize: "16px",
cursor: "pointer", cursor: "pointer",
borderRadius: "8px", borderRadius: "8px",
backgroundColor: "#0097C3", backgroundColor: "limelite-red",
border: "none", border: "none",
color: "white", color: "white",
}} }}
+8
View File
@@ -6,8 +6,16 @@ module.exports = {
], ],
theme: { theme: {
extend: { extend: {
colors: {
limelite: {
red: '#D12E33',
dark: '#1A0505',
maroon: '#4A1515',
}
},
fontFamily: { fontFamily: {
sans: ['"Albert Sans"', 'sans-serif'], sans: ['"Albert Sans"', 'sans-serif'],
serif: ['"Playfair Display"', 'serif'],
}, },
}, },
}, },