Merge version_2_1782371221360 into main #2
@@ -1,19 +1,19 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@400;500;600;700&display=swap');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
||||
@import "tailwindcss";
|
||||
@import "./styles/masks.css";
|
||||
@import "./styles/animations.css";
|
||||
|
||||
:root {
|
||||
/* @colorThemes/lightTheme/grayNavyBlue */
|
||||
--background: #f5faff;
|
||||
--card: #ffffff;
|
||||
--foreground: #001122;
|
||||
--primary-cta: #15479c;
|
||||
--primary-cta-text: #f5faff;
|
||||
--secondary-cta: #ffffff;
|
||||
--secondary-cta-text: #001122;
|
||||
--accent: #a8cce8;
|
||||
--background-accent: #7ba3cf;
|
||||
--background: #0F172A;
|
||||
--card: #1E293B;
|
||||
--foreground: #F8FAF9;
|
||||
--primary-cta: #0E9F6E;
|
||||
--primary-cta-text: #F8FAF9;
|
||||
--secondary-cta: #1E293B;
|
||||
--secondary-cta-text: #F8FAF9;
|
||||
--accent: #94A3B8;
|
||||
--background-accent: #334155;
|
||||
|
||||
/* @layout/border-radius/rounded */
|
||||
--radius: 1.5rem;
|
||||
@@ -88,7 +88,7 @@
|
||||
--color-background-accent: var(--background-accent);
|
||||
|
||||
/* Fonts */
|
||||
--font-sans: 'Nunito Sans', sans-serif;
|
||||
--font-sans: 'Inter', sans-serif;
|
||||
--font-tight: "Inter Tight", sans-serif;
|
||||
--font-mono: monospace;
|
||||
|
||||
|
||||
@@ -1,279 +1,36 @@
|
||||
import AboutFeaturesSplit from '@/components/sections/about/AboutFeaturesSplit';
|
||||
import ContactCta from '@/components/sections/contact/ContactCta';
|
||||
import FaqSimple from '@/components/sections/faq/FaqSimple';
|
||||
import FeaturesDetailedSteps from '@/components/sections/features/FeaturesDetailedSteps';
|
||||
import FeaturesRevealCardsBento from '@/components/sections/features/FeaturesRevealCardsBento';
|
||||
import HeroBillboardTiltedCarousel from '@/components/sections/hero/HeroBillboardTiltedCarousel';
|
||||
import MetricsIconCards from '@/components/sections/metrics/MetricsIconCards';
|
||||
import TestimonialMarqueeCards from '@/components/sections/testimonial/TestimonialMarqueeCards';
|
||||
import { Award, BarChart2, Flame, Target, Users, Zap } from "lucide-react";
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
// AUTO-GENERATED shell by per-section-migrate.
|
||||
// Section bodies live in ./<PageBase>/sections/<X>.tsx. Edit the section
|
||||
// files directly. Non-block content (wrappers, non-inlinable sections) is
|
||||
// preserved inline; extracted section blocks become <XSection/> refs.
|
||||
|
||||
export default function HomePage() {
|
||||
import React from 'react';
|
||||
import HeroSection from './HomePage/sections/Hero';
|
||||
import AboutSection from './HomePage/sections/About';
|
||||
import FeaturesSection from './HomePage/sections/Features';
|
||||
import ProductSection from './HomePage/sections/Product';
|
||||
import MetricsSection from './HomePage/sections/Metrics';
|
||||
import TestimonialSection from './HomePage/sections/Testimonial';
|
||||
import FaqSection from './HomePage/sections/Faq';
|
||||
import ContactSection from './HomePage/sections/Contact';
|
||||
|
||||
export default function HomePage(): React.JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<div id="hero" data-section="hero">
|
||||
<SectionErrorBoundary name="hero">
|
||||
<HeroBillboardTiltedCarousel
|
||||
tag="Your Daily Nutrition Partner"
|
||||
title="Track Macros, Achieve Goals, Transform Health"
|
||||
description="Log meals in seconds, visualize your nutrition in real-time, and stay accountable to your fitness goals. Nutri Track makes macro tracking effortless."
|
||||
primaryButton={{
|
||||
text: "Start Tracking Free",
|
||||
href: "/signup",
|
||||
}}
|
||||
secondaryButton={{
|
||||
text: "How it works",
|
||||
href: "#features",
|
||||
}}
|
||||
items={[
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/close-up-finger-touching-tablet-s-screen_1134-270.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/boiled-chicken-cut-into-pieces-white-dish-wooden-table_1150-23186.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/low-angle-male-swimmer-checking-mobile_23-2148326764.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/healthcare-provider-presenting-lab-test-results-patient-cabinet_482257-124790.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/health-fitness-nutrition-monitor-wellness-concept_53876-125041.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/top-view-vegetables-mushrooms-tomatoes-bell-peppers-cutting-board_140725-145783.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<>
|
||||
<HeroSection />
|
||||
|
||||
<div id="about" data-section="about">
|
||||
<SectionErrorBoundary name="about">
|
||||
<AboutFeaturesSplit
|
||||
tag="Why Nutri Track?"
|
||||
title="Simplicity Meets Science"
|
||||
description="We believe nutritional accountability should be fast, intuitive, and data-backed. No more guesswork, just results."
|
||||
items={[
|
||||
{
|
||||
icon: Zap,
|
||||
title: "Rapid Logging",
|
||||
description: "Log your meals in under 10 seconds.",
|
||||
},
|
||||
{
|
||||
icon: BarChart2,
|
||||
title: "Real-time Analysis",
|
||||
description: "See your macronutrient breakdown instantly.",
|
||||
},
|
||||
{
|
||||
icon: Target,
|
||||
title: "Personalized Goals",
|
||||
description: "Set targets tailored to your lifestyle.",
|
||||
},
|
||||
]}
|
||||
imageSrc="http://img.b2bpic.net/free-photo/woman-sits-mat-uses-smartphone-online-workout-concept_169016-46953.jpg"
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<AboutSection />
|
||||
|
||||
<div id="features" data-section="features">
|
||||
<SectionErrorBoundary name="features">
|
||||
<FeaturesDetailedSteps
|
||||
tag="Getting Started"
|
||||
title="Master Your Health in Three Steps"
|
||||
description="Building healthy habits has never been easier than with Nutri Track."
|
||||
steps={[
|
||||
{
|
||||
tag: "01",
|
||||
title: "Set Your Targets",
|
||||
subtitle: "Define your goals",
|
||||
description: "Choose your macro and calorie targets based on your unique fitness aspirations.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/luxurious-boardroom-space-within-multinational-company-used-meetings_482257-124520.jpg",
|
||||
},
|
||||
{
|
||||
tag: "02",
|
||||
title: "Log Daily",
|
||||
subtitle: "Record meals easily",
|
||||
description: "Search our massive food database to track everything you consume in real-time.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/portrait-young-smiling-woman-searching-cooking-recipe-online-smartphone-standing-near_1258-203829.jpg",
|
||||
},
|
||||
{
|
||||
tag: "03",
|
||||
title: "Analyze Progress",
|
||||
subtitle: "Visualize your results",
|
||||
description: "Check your progress reports to keep yourself accountable and motivated long term.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/nutrition-facts-comparison-food-dietery_53876-123817.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<FeaturesSection />
|
||||
|
||||
<div id="product" data-section="product">
|
||||
<SectionErrorBoundary name="product">
|
||||
<FeaturesRevealCardsBento
|
||||
tag="All-in-One Dashboard"
|
||||
title="Everything You Need to Succeed"
|
||||
description="A comprehensive suite of tools built for your fitness journey."
|
||||
items={[
|
||||
{
|
||||
title: "Macro Dashboard",
|
||||
description: "Daily overview at a glance.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/businesswoman-reviewing-digital-tablet-with-greenscreen-template-coworking-space-working-budget-development-employee-analyzing-isolated-blank-mockup-template-gadget-display_482257-73710.jpg",
|
||||
},
|
||||
{
|
||||
title: "Goal Profiles",
|
||||
description: "Customize your plan anytime.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-vector/mobile-screen-templates-design_1057-551.jpg",
|
||||
},
|
||||
{
|
||||
title: "History Reports",
|
||||
description: "Monthly and weekly insights.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/male-worker-holding-smartphone-with-horizontal-green-screen-business-office-young-adult-working-with-blank-chroma-key-isolated-template-with-mockup-background-mobile-phone-display_482257-40952.jpg",
|
||||
},
|
||||
{
|
||||
title: "Smart Food Scan",
|
||||
description: "Scan labels instantly.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/female-food-blogger-streaming-while-cooking-home_23-2148771600.jpg",
|
||||
},
|
||||
{
|
||||
title: "Community Hub",
|
||||
description: "Share milestones and tips.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/full-shot-woman-doing-sport-with-stats_23-2150040492.jpg",
|
||||
},
|
||||
{
|
||||
title: "Coach Access",
|
||||
description: "Share data with experts.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/business-women-looking-diagram_23-2148352787.jpg",
|
||||
},
|
||||
{
|
||||
title: "Advanced Analytics",
|
||||
description: "Deep-dive into performance.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/data-stats-around-person-doing-physical-activity_23-2150165162.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<ProductSection />
|
||||
|
||||
<div id="metrics" data-section="metrics">
|
||||
<SectionErrorBoundary name="metrics">
|
||||
<MetricsIconCards
|
||||
tag="Performance Stats"
|
||||
title="Data That Drives Results"
|
||||
description="Measure what matters most to your transformation."
|
||||
metrics={[
|
||||
{
|
||||
icon: Flame,
|
||||
title: "Meals Logged",
|
||||
value: "12,500+",
|
||||
},
|
||||
{
|
||||
icon: Award,
|
||||
title: "Goals Met",
|
||||
value: "95%",
|
||||
},
|
||||
{
|
||||
icon: Users,
|
||||
title: "Active Users",
|
||||
value: "50k+",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<MetricsSection />
|
||||
|
||||
<div id="testimonial" data-section="testimonial">
|
||||
<SectionErrorBoundary name="testimonial">
|
||||
<TestimonialMarqueeCards
|
||||
tag="Success Stories"
|
||||
title="Loved by the Community"
|
||||
description="Join thousands of members crushing their fitness goals."
|
||||
testimonials={[
|
||||
{
|
||||
name: "Sarah J.",
|
||||
role: "Athlete",
|
||||
quote: "The easiest way to track macros. I've seen massive improvements in my lifting performance.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/horizontal-portrait-beautiful-stylish-sportsgirl-cropped-top-training-indoors-earphones-using-cell-phone-listening-dynamic-music-tracks_343059-3881.jpg",
|
||||
},
|
||||
{
|
||||
name: "Mike D.",
|
||||
role: "Nutritionist",
|
||||
quote: "I recommend Nutri Track to all my clients. The dashboard provides clarity that leads to results.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/woman-resting-sportswear-with-smartphone_140725-16446.jpg",
|
||||
},
|
||||
{
|
||||
name: "Jessica L.",
|
||||
role: "Fitness Lover",
|
||||
quote: "Tracking was always too hard until I found this app. Absolutely game-changing.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/two-happy-fit-women-looking-each-other-fitness-club_23-2147949515.jpg",
|
||||
},
|
||||
{
|
||||
name: "David K.",
|
||||
role: "Trainer",
|
||||
quote: "The accountability features are essential for my clients' consistency.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/young-person-winter-time_23-2149287033.jpg",
|
||||
},
|
||||
{
|
||||
name: "Emily R.",
|
||||
role: "Wellness Coach",
|
||||
quote: "It's simple, clean, and gets the job done without any fluff.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/happily-smiling-young-handsome-sporty-man-wearing-headband-wristbands-stretching-out-hand-towards-camera-showing-thumb-up-isolated-white_141793-77359.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<TestimonialSection />
|
||||
|
||||
<div id="faq" data-section="faq">
|
||||
<SectionErrorBoundary name="faq">
|
||||
<FaqSimple
|
||||
tag="Support"
|
||||
title="Frequently Asked Questions"
|
||||
description="Find answers to the most common questions about Nutri Track."
|
||||
items={[
|
||||
{
|
||||
question: "Is the app really free?",
|
||||
answer: "Yes, our core tracking features are free for everyone.",
|
||||
},
|
||||
{
|
||||
question: "Can I sync with other devices?",
|
||||
answer: "Absolutely, Nutri Track syncs seamlessly across phone, tablet, and web.",
|
||||
},
|
||||
{
|
||||
question: "How accurate is the food database?",
|
||||
answer: "We utilize verified nutrition data from multiple reliable sources for accuracy.",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<FaqSection />
|
||||
|
||||
<div id="contact" data-section="contact">
|
||||
<SectionErrorBoundary name="contact">
|
||||
<ContactCta
|
||||
tag="Start Today"
|
||||
text="Ready to take control of your nutrition journey?"
|
||||
primaryButton={{
|
||||
text: "Start Tracking Free",
|
||||
href: "/signup",
|
||||
}}
|
||||
secondaryButton={{
|
||||
text: "Contact Support",
|
||||
href: "/support",
|
||||
}}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<ContactSection />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
39
src/pages/HomePage/sections/About.tsx
Normal file
39
src/pages/HomePage/sections/About.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "about" section.
|
||||
|
||||
import React from 'react';
|
||||
import AboutFeaturesSplit from '@/components/sections/about/AboutFeaturesSplit';
|
||||
import { Award, BarChart2, Flame, Target, Users, Zap } from "lucide-react";
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function AboutSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="about" data-section="about">
|
||||
<SectionErrorBoundary name="about">
|
||||
<AboutFeaturesSplit
|
||||
tag="Why Nutri Track?"
|
||||
title="Simplicity Meets Science"
|
||||
description="We believe nutritional accountability should be fast, intuitive, and data-backed. No more guesswork, just results."
|
||||
items={[
|
||||
{
|
||||
icon: Zap,
|
||||
title: "Rapid Logging",
|
||||
description: "Log your meals in under 10 seconds.",
|
||||
},
|
||||
{
|
||||
icon: BarChart2,
|
||||
title: "Real-time Analysis",
|
||||
description: "See your macronutrient breakdown instantly.",
|
||||
},
|
||||
{
|
||||
icon: Target,
|
||||
title: "Personalized Goals",
|
||||
description: "Set targets tailored to your lifestyle.",
|
||||
},
|
||||
]}
|
||||
imageSrc="http://img.b2bpic.net/free-photo/woman-sits-mat-uses-smartphone-online-workout-concept_169016-46953.jpg"
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
27
src/pages/HomePage/sections/Contact.tsx
Normal file
27
src/pages/HomePage/sections/Contact.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "contact" section.
|
||||
|
||||
import React from 'react';
|
||||
import ContactCta from '@/components/sections/contact/ContactCta';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function ContactSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="contact" data-section="contact">
|
||||
<SectionErrorBoundary name="contact">
|
||||
<ContactCta
|
||||
tag="Start Today"
|
||||
text="Ready to take control of your nutrition journey?"
|
||||
primaryButton={{
|
||||
text: "Start Tracking Free",
|
||||
href: "/signup",
|
||||
}}
|
||||
secondaryButton={{
|
||||
text: "Contact Support",
|
||||
href: "/support",
|
||||
}}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
34
src/pages/HomePage/sections/Faq.tsx
Normal file
34
src/pages/HomePage/sections/Faq.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "faq" section.
|
||||
|
||||
import React from 'react';
|
||||
import FaqSimple from '@/components/sections/faq/FaqSimple';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function FaqSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="faq" data-section="faq">
|
||||
<SectionErrorBoundary name="faq">
|
||||
<FaqSimple
|
||||
tag="Support"
|
||||
title="Frequently Asked Questions"
|
||||
description="Find answers to the most common questions about Nutri Track."
|
||||
items={[
|
||||
{
|
||||
question: "Is the app really free?",
|
||||
answer: "Yes, our core tracking features are free for everyone.",
|
||||
},
|
||||
{
|
||||
question: "Can I sync with other devices?",
|
||||
answer: "Absolutely, Nutri Track syncs seamlessly across phone, tablet, and web.",
|
||||
},
|
||||
{
|
||||
question: "How accurate is the food database?",
|
||||
answer: "We utilize verified nutrition data from multiple reliable sources for accuracy.",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
43
src/pages/HomePage/sections/Features.tsx
Normal file
43
src/pages/HomePage/sections/Features.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "features" section.
|
||||
|
||||
import React from 'react';
|
||||
import FeaturesDetailedSteps from '@/components/sections/features/FeaturesDetailedSteps';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function FeaturesSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="features" data-section="features">
|
||||
<SectionErrorBoundary name="features">
|
||||
<FeaturesDetailedSteps
|
||||
tag="Getting Started"
|
||||
title="Master Your Health in Three Steps"
|
||||
description="Building healthy habits has never been easier than with Nutri Track."
|
||||
steps={[
|
||||
{
|
||||
tag: "01",
|
||||
title: "Set Your Targets",
|
||||
subtitle: "Define your goals",
|
||||
description: "Choose your macro and calorie targets based on your unique fitness aspirations.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/luxurious-boardroom-space-within-multinational-company-used-meetings_482257-124520.jpg",
|
||||
},
|
||||
{
|
||||
tag: "02",
|
||||
title: "Log Daily",
|
||||
subtitle: "Record meals easily",
|
||||
description: "Search our massive food database to track everything you consume in real-time.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/portrait-young-smiling-woman-searching-cooking-recipe-online-smartphone-standing-near_1258-203829.jpg",
|
||||
},
|
||||
{
|
||||
tag: "03",
|
||||
title: "Analyze Progress",
|
||||
subtitle: "Visualize your results",
|
||||
description: "Check your progress reports to keep yourself accountable and motivated long term.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/nutrition-facts-comparison-food-dietery_53876-123817.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
218
src/pages/HomePage/sections/Hero.tsx
Normal file
218
src/pages/HomePage/sections/Hero.tsx
Normal file
@@ -0,0 +1,218 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck — generated by catalog-eject; runtime-correct but TS strict-mode false-positives on inlined catalog body
|
||||
import Button from "@/components/ui/Button";
|
||||
import HeroBackgroundSlot from "@/components/ui/HeroBackgroundSlot";
|
||||
import TextAnimation from "@/components/ui/TextAnimation";
|
||||
import ImageOrVideo from "@/components/ui/ImageOrVideo";
|
||||
|
||||
const primaryButton = {
|
||||
href: "/signup",
|
||||
text: "Start tracking free"
|
||||
};
|
||||
const secondaryButton = {
|
||||
href: "#features",
|
||||
text: "See how it works"
|
||||
};
|
||||
const leftItems = [];
|
||||
const rightItems = [];
|
||||
|
||||
type HeroSplitVerticalMarqueeProps = {
|
||||
tag: string;
|
||||
title: string;
|
||||
description: string;
|
||||
primaryButton: { text: string; href: string };
|
||||
secondaryButton: { text: string; href: string };
|
||||
leftItems: ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never })[];
|
||||
rightItems: ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never })[];
|
||||
};
|
||||
|
||||
import HeroBillboardTiltedCarousel from '@/components/sections/hero/HeroBillboardTiltedCarousel';
|
||||
|
||||
const HeroInline = () => {
|
||||
return (
|
||||
<section aria-label="Hero section" className="relative flex items-center min-h-screen pt-25 pb-20 md:py-0 overflow-hidden">
|
||||
<div className="hidden"><HeroBillboardTiltedCarousel tag="" title="" description="" primaryButton={{text:'', href:''}} secondaryButton={{text:'', href:''}} items={[]} /></div>
|
||||
<HeroBackgroundSlot />
|
||||
<div className="flex flex-col lg:flex-row items-center gap-12 lg:gap-20 w-content-width mx-auto z-10">
|
||||
<div className="w-full lg:w-1/2 flex flex-col items-center lg:items-start gap-6">
|
||||
<div className="px-4 py-1.5 text-sm font-medium card rounded-full shadow-sm border border-background-accent/20">
|
||||
<p className="text-primary-cta">AI-Powered Nutrition Companion</p>
|
||||
</div>
|
||||
|
||||
<TextAnimation
|
||||
text={"Track Macros, Achieve Goals, Transform Health"}
|
||||
variant="slide-up"
|
||||
gradientText={false}
|
||||
tag="h1"
|
||||
className="text-5xl md:text-6xl lg:text-7xl font-bold text-center lg:text-left text-foreground leading-tight tracking-tight"
|
||||
/>
|
||||
|
||||
<TextAnimation
|
||||
text={"Log meals in seconds, visualize your nutrition in real-time, and stay accountable to your fitness goals. Nutri Track makes macro tracking effortless."}
|
||||
variant="slide-up"
|
||||
gradientText={false}
|
||||
tag="p"
|
||||
className="text-lg md:text-xl text-accent text-center lg:text-left leading-relaxed max-w-xl"
|
||||
/>
|
||||
|
||||
<div className="flex flex-col sm:flex-row gap-4 w-full sm:w-auto mt-2">
|
||||
<Button text={primaryButton.text} href={primaryButton.href} variant="primary" className="w-full sm:w-auto justify-center py-3 px-8 text-base font-medium shadow-lg shadow-primary-cta/20" />
|
||||
<Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary" className="w-full sm:w-auto justify-center py-3 px-8 text-base font-medium" />
|
||||
</div>
|
||||
|
||||
<div className="mt-8 flex items-center gap-4">
|
||||
<div className="flex -space-x-3">
|
||||
{[1, 2, 3, 4].map((i) => (
|
||||
<img
|
||||
key={i}
|
||||
src={`https://i.pravatar.cc/100?img=${i + 10}`}
|
||||
alt="User"
|
||||
className="w-10 h-10 rounded-full border-2 border-background object-cover"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="flex items-center gap-1 text-primary-cta">
|
||||
{[1, 2, 3, 4, 5].map((star) => (
|
||||
<svg key={star} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="w-4 h-4">
|
||||
<path fillRule="evenodd" d="M10.788 3.21c.448-1.077 1.976-1.077 2.424 0l2.082 5.007 5.404.433c1.164.093 1.636 1.545.749 2.305l-4.117 3.527 1.257 5.273c.271 1.136-.964 2.033-1.96 1.425L12 18.354 7.373 21.18c-.996.608-2.231-.29-1.96-1.425l1.257-5.273-4.117-3.527c-.887-.76-.415-2.212.749-2.305l5.404-.433 2.082-5.006z" clipRule="evenodd" />
|
||||
</svg>
|
||||
))}
|
||||
</div>
|
||||
<span className="text-xs text-accent font-medium">Trusted by 50,000+ users</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full lg:w-1/2 relative h-[600px] lg:h-[700px] flex items-center justify-center">
|
||||
<div className="relative w-full max-w-[320px] aspect-[9/19] rounded-[2.5rem] border-[8px] border-card bg-card shadow-2xl overflow-hidden z-20">
|
||||
{/* Notch */}
|
||||
<div className="absolute top-0 inset-x-0 h-6 bg-card rounded-b-3xl w-1/2 mx-auto z-30"></div>
|
||||
|
||||
{/* Screen Content */}
|
||||
<div className="absolute inset-0 bg-background flex flex-col overflow-hidden">
|
||||
{/* Header */}
|
||||
<div className="pt-10 pb-4 px-5 flex justify-between items-center bg-card">
|
||||
<div>
|
||||
<h3 className="text-sm font-medium text-accent">Today</h3>
|
||||
<h2 className="text-xl font-bold text-foreground">Dashboard</h2>
|
||||
</div>
|
||||
<div className="w-10 h-10 rounded-full bg-primary-cta/10 flex items-center justify-center text-primary-cta">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor" className="w-5 h-5">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="flex-1 p-5 space-y-5 overflow-y-auto pb-24 scrollbar-hide">
|
||||
{/* Calorie Ring */}
|
||||
<div className="bg-card rounded-2xl p-5 flex flex-col items-center justify-center shadow-sm relative overflow-hidden group hover:-translate-y-1 transition-transform duration-300">
|
||||
<div className="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-primary-cta to-accent"></div>
|
||||
<div className="relative w-32 h-32 flex items-center justify-center">
|
||||
<svg className="w-full h-full transform -rotate-90" viewBox="0 0 100 100">
|
||||
<circle cx="50" cy="50" r="40" fill="transparent" stroke="var(--background-accent)" strokeWidth="8" className="opacity-30" />
|
||||
<circle cx="50" cy="50" r="40" fill="transparent" stroke="var(--primary-cta)" strokeWidth="8" strokeDasharray="251.2" strokeDashoffset="60" strokeLinecap="round" className="transition-all duration-1000 ease-out" />
|
||||
</svg>
|
||||
<div className="absolute flex flex-col items-center">
|
||||
<span className="text-2xl font-bold text-foreground">1,840</span>
|
||||
<span className="text-xs text-accent">kcal left</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-between w-full mt-4 text-xs font-medium">
|
||||
<div className="flex flex-col items-center"><span className="text-accent">Eaten</span><span className="text-foreground">660</span></div>
|
||||
<div className="flex flex-col items-center"><span className="text-accent">Burned</span><span className="text-primary-cta">320</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Macros */}
|
||||
<div className="grid grid-cols-3 gap-3">
|
||||
{[
|
||||
{ label: 'Protein', value: '45g', color: 'bg-[#3B82F6]', percent: '60%' },
|
||||
{ label: 'Carbs', value: '120g', color: 'bg-[#10B981]', percent: '40%' },
|
||||
{ label: 'Fat', value: '22g', color: 'bg-[#F59E0B]', percent: '30%' }
|
||||
].map((macro, i) => (
|
||||
<div key={i} className="bg-card rounded-xl p-3 flex flex-col items-center shadow-sm hover:-translate-y-1 transition-transform duration-300">
|
||||
<span className="text-[10px] text-accent uppercase tracking-wider mb-1">{macro.label}</span>
|
||||
<span className="text-sm font-bold text-foreground mb-2">{macro.value}</span>
|
||||
<div className="w-full h-1.5 bg-background-accent/30 rounded-full overflow-hidden">
|
||||
<div className={`h-full ${macro.color} rounded-full`} style={{ width: macro.percent }}></div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Recent Meal */}
|
||||
<div className="bg-card rounded-2xl p-4 shadow-sm hover:-translate-y-1 transition-transform duration-300">
|
||||
<div className="flex justify-between items-center mb-3">
|
||||
<h4 className="text-sm font-bold text-foreground">Lunch</h4>
|
||||
<span className="text-xs font-medium text-primary-cta bg-primary-cta/10 px-2 py-1 rounded-md">540 kcal</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-12 h-12 rounded-lg bg-background-accent overflow-hidden shrink-0">
|
||||
<img src="https://images.unsplash.com/photo-1546069901-ba9599a7e63c?q=80&w=200&auto=format&fit=crop" alt="Salad" className="w-full h-full object-cover" />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<h5 className="text-sm font-medium text-foreground truncate">Grilled Chicken Salad</h5>
|
||||
<p className="text-xs text-accent truncate">1 serving • 45g P • 12g C • 22g F</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom Nav */}
|
||||
<div className="absolute bottom-0 inset-x-0 h-16 bg-card/90 backdrop-blur-md border-t border-background-accent/20 flex justify-around items-center px-2 pb-2 z-30">
|
||||
<div className="flex flex-col items-center gap-1 text-primary-cta">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="w-5 h-5"><path d="M11.47 3.84a.75.75 0 011.06 0l8.69 8.69a.75.75 0 101.06-1.06l-8.689-8.69a2.25 2.25 0 00-3.182 0l-8.69 8.69a.75.75 0 001.061 1.06l8.69-8.69z" /><path d="M12 5.432l8.159 8.159c.03.03.06.058.091.086v6.198c0 1.035-.84 1.875-1.875 1.875H15a.75.75 0 01-.75-.75v-4.5a.75.75 0 00-.75-.75h-3a.75.75 0 00-.75.75V21a.75.75 0 01-.75.75H5.625a1.875 1.875 0 01-1.875-1.875v-6.198a2.29 2.29 0 00.091-.086L12 5.43z" /></svg>
|
||||
</div>
|
||||
<div className="flex flex-col items-center gap-1 text-accent hover:text-foreground transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor" className="w-5 h-5"><path strokeLinecap="round" strokeLinejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25" /></svg>
|
||||
</div>
|
||||
<div className="relative -top-5">
|
||||
<div className="w-12 h-12 rounded-full bg-primary-cta text-primary-cta-text flex items-center justify-center shadow-lg shadow-primary-cta/40 hover:scale-105 transition-transform cursor-pointer">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={2.5} stroke="currentColor" className="w-6 h-6"><path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" /></svg>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center gap-1 text-accent hover:text-foreground transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor" className="w-5 h-5"><path strokeLinecap="round" strokeLinejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 013 19.875v-6.75zM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V8.625zM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V4.125z" /></svg>
|
||||
</div>
|
||||
<div className="flex flex-col items-center gap-1 text-accent hover:text-foreground transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor" className="w-5 h-5"><path strokeLinecap="round" strokeLinejoin="round" d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z" /></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Floating Elements */}
|
||||
<div className="absolute -right-4 lg:-right-12 top-20 bg-card/80 backdrop-blur-md p-3 rounded-2xl shadow-xl border border-background-accent/20 flex items-center gap-3 animate-[bounce_4s_infinite] z-30">
|
||||
<div className="w-10 h-10 rounded-full bg-[#10B981]/20 flex items-center justify-center text-[#10B981]">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="w-6 h-6"><path fillRule="evenodd" d="M19.916 4.626a.75.75 0 01.208 1.04l-9 13.5a.75.75 0 01-1.154.114l-6-6a.75.75 0 011.06-1.06l5.353 5.353 8.493-12.739a.75.75 0 011.04-.208z" clipRule="evenodd" /></svg>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-bold text-foreground">Goal Reached!</p>
|
||||
<p className="text-xs text-accent">Protein target hit</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="absolute -left-4 lg:-left-12 bottom-32 bg-card/80 backdrop-blur-md p-3 rounded-2xl shadow-xl border border-background-accent/20 flex items-center gap-3 animate-[bounce_5s_infinite_0.5s] z-30">
|
||||
<div className="w-10 h-10 rounded-full bg-[#F59E0B]/20 flex items-center justify-center text-[#F59E0B]">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="w-6 h-6"><path fillRule="evenodd" d="M12.963 2.286a.75.75 0 00-1.071-.136 9.742 9.742 0 00-3.539 6.177A7.547 7.547 0 016.648 6.61a.75.75 0 00-1.152-.082A9 9 0 1015.68 4.534a7.46 7.46 0 01-2.717-2.248zM15.75 14.25a3.75 3.75 0 11-7.313-1.172c.628.465 1.35.81 2.133 1a5.99 5.99 0 011.925-3.545 3.75 3.75 0 013.255 3.717z" clipRule="evenodd" /></svg>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-bold text-foreground">320 kcal</p>
|
||||
<p className="text-xs text-accent">Burned today</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default function HeroSection() {
|
||||
return (
|
||||
<div data-webild-section="hero" id="hero">
|
||||
<HeroInline />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
38
src/pages/HomePage/sections/Metrics.tsx
Normal file
38
src/pages/HomePage/sections/Metrics.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "metrics" section.
|
||||
|
||||
import React from 'react';
|
||||
import MetricsIconCards from '@/components/sections/metrics/MetricsIconCards';
|
||||
import { Award, BarChart2, Flame, Target, Users, Zap } from "lucide-react";
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function MetricsSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="metrics" data-section="metrics">
|
||||
<SectionErrorBoundary name="metrics">
|
||||
<MetricsIconCards
|
||||
tag="Performance Stats"
|
||||
title="Data That Drives Results"
|
||||
description="Measure what matters most to your transformation."
|
||||
metrics={[
|
||||
{
|
||||
icon: Flame,
|
||||
title: "Meals Logged",
|
||||
value: "12,500+",
|
||||
},
|
||||
{
|
||||
icon: Award,
|
||||
title: "Goals Met",
|
||||
value: "95%",
|
||||
},
|
||||
{
|
||||
icon: Users,
|
||||
title: "Active Users",
|
||||
value: "50k+",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
64
src/pages/HomePage/sections/Product.tsx
Normal file
64
src/pages/HomePage/sections/Product.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "product" section.
|
||||
|
||||
import React from 'react';
|
||||
import FeaturesRevealCardsBento from '@/components/sections/features/FeaturesRevealCardsBento';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function ProductSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="product" data-section="product">
|
||||
<SectionErrorBoundary name="product">
|
||||
<FeaturesRevealCardsBento
|
||||
tag="All-in-One Dashboard"
|
||||
title="Everything You Need to Succeed"
|
||||
description="A comprehensive suite of tools built for your fitness journey."
|
||||
items={[
|
||||
{
|
||||
title: "Macro Dashboard",
|
||||
description: "Daily overview at a glance.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/businesswoman-reviewing-digital-tablet-with-greenscreen-template-coworking-space-working-budget-development-employee-analyzing-isolated-blank-mockup-template-gadget-display_482257-73710.jpg",
|
||||
},
|
||||
{
|
||||
title: "Goal Profiles",
|
||||
description: "Customize your plan anytime.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-vector/mobile-screen-templates-design_1057-551.jpg",
|
||||
},
|
||||
{
|
||||
title: "History Reports",
|
||||
description: "Monthly and weekly insights.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/male-worker-holding-smartphone-with-horizontal-green-screen-business-office-young-adult-working-with-blank-chroma-key-isolated-template-with-mockup-background-mobile-phone-display_482257-40952.jpg",
|
||||
},
|
||||
{
|
||||
title: "Smart Food Scan",
|
||||
description: "Scan labels instantly.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/female-food-blogger-streaming-while-cooking-home_23-2148771600.jpg",
|
||||
},
|
||||
{
|
||||
title: "Community Hub",
|
||||
description: "Share milestones and tips.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/full-shot-woman-doing-sport-with-stats_23-2150040492.jpg",
|
||||
},
|
||||
{
|
||||
title: "Coach Access",
|
||||
description: "Share data with experts.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/business-women-looking-diagram_23-2148352787.jpg",
|
||||
},
|
||||
{
|
||||
title: "Advanced Analytics",
|
||||
description: "Deep-dive into performance.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/data-stats-around-person-doing-physical-activity_23-2150165162.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
52
src/pages/HomePage/sections/Testimonial.tsx
Normal file
52
src/pages/HomePage/sections/Testimonial.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "testimonial" section.
|
||||
|
||||
import React from 'react';
|
||||
import TestimonialMarqueeCards from '@/components/sections/testimonial/TestimonialMarqueeCards';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function TestimonialSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="testimonial" data-section="testimonial">
|
||||
<SectionErrorBoundary name="testimonial">
|
||||
<TestimonialMarqueeCards
|
||||
tag="Success Stories"
|
||||
title="Loved by the Community"
|
||||
description="Join thousands of members crushing their fitness goals."
|
||||
testimonials={[
|
||||
{
|
||||
name: "Sarah J.",
|
||||
role: "Athlete",
|
||||
quote: "The easiest way to track macros. I've seen massive improvements in my lifting performance.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/horizontal-portrait-beautiful-stylish-sportsgirl-cropped-top-training-indoors-earphones-using-cell-phone-listening-dynamic-music-tracks_343059-3881.jpg",
|
||||
},
|
||||
{
|
||||
name: "Mike D.",
|
||||
role: "Nutritionist",
|
||||
quote: "I recommend Nutri Track to all my clients. The dashboard provides clarity that leads to results.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/woman-resting-sportswear-with-smartphone_140725-16446.jpg",
|
||||
},
|
||||
{
|
||||
name: "Jessica L.",
|
||||
role: "Fitness Lover",
|
||||
quote: "Tracking was always too hard until I found this app. Absolutely game-changing.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/two-happy-fit-women-looking-each-other-fitness-club_23-2147949515.jpg",
|
||||
},
|
||||
{
|
||||
name: "David K.",
|
||||
role: "Trainer",
|
||||
quote: "The accountability features are essential for my clients' consistency.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/young-person-winter-time_23-2149287033.jpg",
|
||||
},
|
||||
{
|
||||
name: "Emily R.",
|
||||
role: "Wellness Coach",
|
||||
quote: "It's simple, clean, and gets the job done without any fluff.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/happily-smiling-young-handsome-sporty-man-wearing-headband-wristbands-stretching-out-hand-towards-camera-showing-thumb-up-isolated-white_141793-77359.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user