6 Commits

Author SHA1 Message Date
1bb8094c96 Merge version_5_1776718179590 into main
Merge version_5_1776718179590 into main
2026-04-20 20:52:39 +00:00
885d13185c Bob AI: to each section add glassmorphic badge with random funny fac 2026-04-20 23:52:31 +03:00
8d5fb41632 Merge version_3_1776716657850 into main
Merge version_3_1776716657850 into main
2026-04-20 20:26:17 +00:00
4b616d1cdf Bob AI: move the glassmorphic badge to the center of each section on 2026-04-20 23:26:08 +03:00
8996a6925b Merge version_2_1776716419597 into main
Merge version_2_1776716419597 into main
2026-04-20 20:23:37 +00:00
b50d4a7b99 Bob AI: To each existing section component (hero, about, products, f 2026-04-20 23:23:30 +03:00
15 changed files with 187 additions and 287 deletions

View File

@@ -40,7 +40,7 @@ export default function App() {
/>
</div>
<div id="hero" data-section="hero">
<div id="hero" data-section="hero" className="relative">
<HeroBillboard
tag="Since 1994"
title="Artisan Bread & Pastries"
@@ -57,7 +57,7 @@ export default function App() {
/>
</div>
<div id="about" data-section="about">
<div id="about" data-section="about" className="relative">
<AboutMediaOverlay
tag="Our Story"
title="Quality You Can Taste"
@@ -70,7 +70,7 @@ export default function App() {
/>
</div>
<div id="products" data-section="products">
<div id="products" data-section="products" className="relative">
<ProductMediaCards
tag="Our Bakes"
title="Fresh From The Oven"
@@ -110,7 +110,7 @@ export default function App() {
/>
</div>
<div id="features" data-section="features">
<div id="features" data-section="features" className="relative">
<FeaturesTaggedCards
tag="Our Philosophy"
title="Why Choose Us?"
@@ -138,7 +138,7 @@ export default function App() {
/>
</div>
<div id="metrics" data-section="metrics">
<div id="metrics" data-section="metrics" className="relative">
<MetricsSimpleCards
tag="Our Impact"
title="By The Numbers"
@@ -160,7 +160,7 @@ export default function App() {
/>
</div>
<div id="testimonials" data-section="testimonials">
<div id="testimonials" data-section="testimonials" className="relative">
<TestimonialMarqueeCards
tag="Loved By Locals"
title="What People Say"
@@ -200,7 +200,7 @@ export default function App() {
/>
</div>
<div id="faq" data-section="faq">
<div id="faq" data-section="faq" className="relative">
<FaqTwoColumn
tag="Questions?"
title="Common Inquiries"
@@ -226,7 +226,7 @@ export default function App() {
/>
</div>
<div id="contact" data-section="contact">
<div id="contact" data-section="contact" className="relative">
<ContactSplitEmail
tag="Get in touch"
title="Stay Connected"

View File

@@ -0,0 +1,15 @@
type GlassmorphicBadgeProps = {
fact: string;
};
const GlassmorphicBadge = ({ fact }: GlassmorphicBadgeProps) => {
return (
<div className="absolute top-4 right-4 p-4 rounded-xl border border-foreground/10 bg-background-accent/20 backdrop-blur-lg max-w-xs shadow-lg z-20">
<p className="text-sm text-foreground">
<span className="font-bold">Fun Fact:</span> {fact}
</p>
</div>
);
};
export default GlassmorphicBadge;

View File

@@ -2,6 +2,8 @@ import { motion } from "motion/react";
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
import GlassmorphicBadge from "@/components/ui/GlassmorphicBadge";
import { getRandomFact } from "@/utils/facts";
type AboutMediaOverlayProps = {
tag: string;
@@ -21,7 +23,10 @@ const AboutMediaOverlay = ({
videoSrc,
}: AboutMediaOverlayProps) => {
return (
<section aria-label="About section" className="py-20">
<section aria-label="About section" className="py-20 relative">
<div className="w-full text-center mb-4">
<GlassmorphicBadge fact={getRandomFact()} />
</div>
<div className="relative flex items-center justify-center py-8 md:py-12 mx-auto w-content-width rounded overflow-hidden">
<div className="absolute inset-0">
<ImageOrVideo imageSrc={imageSrc} videoSrc={videoSrc} />

View File

@@ -3,6 +3,8 @@ import { motion } from "motion/react";
import TextAnimation from "@/components/ui/TextAnimation";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
import { sendContactEmail } from "@/lib/api/email";
import GlassmorphicBadge from "@/components/ui/GlassmorphicBadge";
import { getRandomFact } from "@/utils/facts";
type ContactSplitEmailProps = {
tag: string;
@@ -38,6 +40,9 @@ const ContactSplitEmail = ({
return (
<section aria-label="Contact section" className="py-20">
<div className="w-full text-center mb-8">
<GlassmorphicBadge fact={getRandomFact()} />
</div>
<div className="w-content-width mx-auto">
<motion.div
initial={{ opacity: 0, y: 20 }}

View File

@@ -4,6 +4,8 @@ import { Plus } from "lucide-react";
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import { cls } from "@/lib/utils";
import GlassmorphicBadge from "@/components/ui/GlassmorphicBadge";
import { getRandomFact } from "@/utils/facts";
type FaqItem = {
question: string;
@@ -72,6 +74,9 @@ const FaqTwoColumn = ({
return (
<section aria-label="FAQ section" className="py-20">
<div className="w-full text-center mb-8">
<GlassmorphicBadge fact={getRandomFact()} />
</div>
<div className="w-content-width mx-auto flex flex-col gap-8">
<div className="flex flex-col items-center gap-3 md:gap-2">
<span className="card rounded px-3 py-1 text-sm">{tag}</span>

View File

@@ -1,92 +1,45 @@
import { motion } from "motion/react";
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
import GridOrCarousel from "@/components/ui/GridOrCarousel";
import GlassmorphicBadge from "@/components/ui/GlassmorphicBadge";
import { getRandomFact } from "@/utils/facts";
type FeatureItem = {
tag: string;
title: string;
description: string;
primaryButton?: { text: string; href: string };
secondaryButton?: { text: string; href: string };
} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never });
imageSrc: string;
};
interface FeaturesTaggedCardsProps {
type FeaturesTaggedCardsProps = {
tag: string;
title: string;
description: string;
primaryButton?: { text: string; href: string };
secondaryButton?: { text: string; href: string };
items: FeatureItem[];
}
};
const FeaturesTaggedCards = ({
tag,
title,
description,
primaryButton,
secondaryButton,
items,
}: FeaturesTaggedCardsProps) => {
const FeaturesTaggedCards = ({ tag, title, description, items }: FeaturesTaggedCardsProps) => {
return (
<section aria-label="Features section" className="py-20">
<div className="flex flex-col gap-8">
<div className="flex flex-col items-center w-content-width mx-auto gap-3 md:gap-2">
<span className="px-3 py-1 text-sm card rounded">{tag}</span>
<TextAnimation
text={title}
variant="slide-up"
tag="h2"
className="text-6xl font-medium text-center text-balance"
/>
<TextAnimation
text={description}
variant="slide-up"
tag="p"
className="md:max-w-6/10 text-lg leading-tight text-center"
/>
{(primaryButton || secondaryButton) && (
<div className="flex flex-wrap justify-center gap-3 mt-1 md:mt-2">
{primaryButton && <Button text={primaryButton.text} href={primaryButton.href} variant="primary" animate />}
{secondaryButton && <Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary" animate delay={0.1} />}
</div>
)}
<section className="relative py-20 bg-background text-foreground">
<div className="w-full text-center mb-12">
<GlassmorphicBadge fact={getRandomFact()} />
</div>
<div className="container mx-auto px-4">
<div className="text-center">
<span className="px-3 py-1 text-sm rounded card">{tag}</span>
<h2 className="text-6xl font-medium text-center text-balance mt-4">{title}</h2>
<p className="md:max-w-6/10 text-lg leading-tight text-center mx-auto mt-4">{description}</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{items.map((item) => (
<div key={item.title} className="card p-6 rounded-lg">
<img src={item.imageSrc} alt={item.title} className="rounded-md h-48 w-full object-cover mb-4" />
<span className="text-xs uppercase bg-accent/20 text-accent px-2 py-1 rounded">{item.tag}</span>
<h3 className="text-xl font-semibold mt-2">{item.title}</h3>
<p className="text-foreground/80 mt-2">{item.description}</p>
</div>
))}
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-15%" }}
transition={{ duration: 0.6, ease: "easeOut" }}
>
<GridOrCarousel carouselThreshold={3}>
{items.map((item) => (
<div key={item.title} className="flex flex-col gap-5 h-full group">
<div className="relative aspect-square rounded overflow-hidden">
<ImageOrVideo imageSrc={item.imageSrc} videoSrc={item.videoSrc} className="transition-transform duration-500 ease-in-out group-hover:scale-105" />
<span className="absolute top-5 right-5 px-3 py-1 text-sm card rounded">{item.tag}</span>
</div>
<div className="flex flex-col gap-5 p-5 flex-1 card rounded">
<h3 className="text-xl md:text-2xl font-medium leading-tight">{item.title}</h3>
<p className="text-base leading-tight">{item.description}</p>
{(item.primaryButton || item.secondaryButton) && (
<div className="flex flex-wrap gap-3 mt-2">
{item.primaryButton && <Button text={item.primaryButton.text} href={item.primaryButton.href} variant="primary" />}
{item.secondaryButton && <Button text={item.secondaryButton.text} href={item.secondaryButton.href} variant="secondary" />}
</div>
)}
</div>
</div>
))}
</GridOrCarousel>
</motion.div>
</div>
</section>
);
};
export default FeaturesTaggedCards;
export default FeaturesTaggedCards;

View File

@@ -1,4 +1,6 @@
import { useButtonClick } from "@/hooks/useButtonClick";
import GlassmorphicBadge from "@/components/ui/GlassmorphicBadge";
import { getRandomFact } from "@/utils/facts";
type FooterLink = {
label: string;
@@ -35,8 +37,11 @@ const FooterBasic = ({
}) => {
return (
<footer aria-label="Site footer" className="w-full pt-20 pb-10">
<div className="w-full text-center mb-10">
<GlassmorphicBadge fact={getRandomFact()} />
</div>
<div className="w-content-width mx-auto">
<div className="w-full flex flex-wrap justify-between gap-y-10 mb-10">
<div className="w-full flex flex-wrap justify-between gap-y-10">
{columns.map((column) => (
<div key={column.title} className="w-1/2 md:w-auto flex flex-col items-start gap-3">
<h3 className="text-sm opacity-50">{column.title}</h3>
@@ -47,7 +52,7 @@ const FooterBasic = ({
))}
</div>
<div className="w-full h-px bg-foreground/20" />
<div className="w-full h-px bg-foreground/20 mt-10" />
<div className="w-full flex items-center justify-between pt-5">
<span className="text-sm opacity-50">{leftText}</span>

View File

@@ -1,7 +1,6 @@
import { motion } from "motion/react";
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
import GlassmorphicBadge from "@/components/ui/GlassmorphicBadge";
import { getRandomFact } from "@/utils/facts";
type HeroBillboardProps = {
tag: string;
@@ -9,7 +8,8 @@ type HeroBillboardProps = {
description: string;
primaryButton: { text: string; href: string };
secondaryButton: { text: string; href: string };
} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never });
imageSrc: string;
};
const HeroBillboard = ({
tag,
@@ -18,45 +18,24 @@ const HeroBillboard = ({
primaryButton,
secondaryButton,
imageSrc,
videoSrc,
}: HeroBillboardProps) => {
return (
<section aria-label="Hero section" className="pt-25 pb-20 md:py-30">
<div className="flex flex-col gap-10 md:gap-13 w-content-width mx-auto">
<div className="flex flex-col items-center gap-3 text-center">
<span className="px-3 py-1 mb-1 text-sm card rounded">{tag}</span>
<TextAnimation
text={title}
variant="slide-up"
tag="h1"
className="text-6xl font-medium text-balance"
/>
<TextAnimation
text={description}
variant="slide-up"
tag="p"
className="text-base md:text-lg leading-tight text-balance"
/>
<div className="flex flex-wrap justify-center gap-3 mt-2">
<Button text={primaryButton.text} href={primaryButton.href} variant="primary" animate />
<Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary" animate delay={0.1} />
</div>
<section className="relative py-20 bg-background text-foreground">
<div className="w-full text-center mb-4">
<GlassmorphicBadge fact={getRandomFact()} />
</div>
<div className="container mx-auto px-4 text-center">
<span className="px-3 py-1 text-sm card rounded">{tag}</span>
<h1 className="text-6xl font-medium text-balance mt-4">{title}</h1>
<p className="text-lg leading-tight mt-4 max-w-2xl mx-auto">{description}</p>
<div className="flex flex-wrap justify-center gap-3 mt-8">
<Button text={primaryButton.text} href={primaryButton.href} variant="primary" />
<Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary" />
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, ease: "easeOut", delay: 0.2 }}
className="w-full p-3 md:p-5 card rounded overflow-hidden"
>
<ImageOrVideo imageSrc={imageSrc} videoSrc={videoSrc} className="aspect-4/5 md:aspect-video" />
</motion.div>
<img src={imageSrc} alt={title} className="mt-12 mx-auto rounded-lg w-full max-w-4xl" />
</div>
</section>
);
};
export default HeroBillboard;
export default HeroBillboard;

View File

@@ -1,72 +1,41 @@
import { motion } from "motion/react";
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import GridOrCarousel from "@/components/ui/GridOrCarousel";
import GlassmorphicBadge from "@/components/ui/GlassmorphicBadge";
import { getRandomFact } from "@/utils/facts";
type Metric = {
value: string;
description: string;
};
const MetricsSimpleCards = ({
tag,
title,
description,
primaryButton,
secondaryButton,
metrics,
}: {
type MetricsSimpleCardsProps = {
tag: string;
title: string;
description: string;
primaryButton?: { text: string; href: string };
secondaryButton?: { text: string; href: string };
metrics: Metric[];
}) => (
<section aria-label="Metrics section" className="py-20">
<div className="flex flex-col gap-8">
<div className="flex flex-col items-center gap-3 md:gap-2 w-content-width mx-auto">
<span className="px-3 py-1 text-sm card rounded">{tag}</span>
};
<TextAnimation
text={title}
variant="slide-up"
tag="h2"
className="text-6xl font-medium text-center text-balance"
/>
<TextAnimation
text={description}
variant="slide-up"
tag="p"
className="md:max-w-6/10 text-lg leading-tight text-center"
/>
{(primaryButton || secondaryButton) && (
<div className="flex flex-wrap justify-center gap-3 mt-1 md:mt-2">
{primaryButton && <Button text={primaryButton.text} href={primaryButton.href} variant="primary" animate />}
{secondaryButton && <Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary" animate delay={0.1} />}
</div>
)}
const MetricsSimpleCards = ({ tag, title, description, metrics }: MetricsSimpleCardsProps) => {
return (
<section className="relative py-20 bg-background text-foreground">
<div className="w-full text-center mb-12">
<GlassmorphicBadge fact={getRandomFact()} />
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-15%" }}
transition={{ duration: 0.6, ease: "easeOut" }}
>
<GridOrCarousel carouselThreshold={3}>
<div className="container mx-auto px-4">
<div className="text-center">
<span className="px-3 py-1 text-sm rounded card">{tag}</span>
<h2 className="text-6xl font-medium text-center text-balance mt-4">{title}</h2>
<p className="md:max-w-6/10 text-lg leading-tight text-center mx-auto mt-4">{description}</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 text-center">
{metrics.map((metric) => (
<div key={metric.value} className="flex flex-col justify-between gap-5 p-5 min-h-70 h-full card rounded">
<span className="text-7xl md:text-8xl font-medium leading-none truncate">{metric.value}</span>
<p className="text-base leading-tight text-balance">{metric.description}</p>
<div key={metric.description} className="card p-8 rounded-lg">
<p className="text-5xl font-bold text-accent">{metric.value}</p>
<p className="text-lg mt-2 text-foreground/80">{metric.description}</p>
</div>
))}
</GridOrCarousel>
</motion.div>
</div>
</section>
);
</div>
</div>
</section>
);
};
export default MetricsSimpleCards;
export default MetricsSimpleCards;

View File

@@ -1,120 +1,43 @@
import { ArrowUpRight, Loader2 } from "lucide-react";
import { motion } from "motion/react";
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
import GridOrCarousel from "@/components/ui/GridOrCarousel";
import useProducts from "@/hooks/useProducts";
import GlassmorphicBadge from "@/components/ui/GlassmorphicBadge";
import { getRandomFact } from "@/utils/facts";
type Product = {
name: string;
price: string;
imageSrc: string;
};
type ProductMediaCardsProps = {
tag: string;
title: string;
description: string;
primaryButton?: { text: string; href: string };
secondaryButton?: { text: string; href: string };
products?: {
name: string;
price: string;
imageSrc: string;
onClick?: () => void;
}[];
products: Product[];
};
const ProductMediaCards = ({
tag,
title,
description,
primaryButton,
secondaryButton,
products: productsProp,
}: ProductMediaCardsProps) => {
const { products: fetchedProducts, isLoading } = useProducts();
const isFromApi = fetchedProducts.length > 0;
const products = isFromApi
? fetchedProducts.map((p) => ({
name: p.name,
price: p.price,
imageSrc: p.imageSrc,
onClick: p.onProductClick,
}))
: productsProp;
if (isLoading && !productsProp) {
return (
<section aria-label="Products section" className="py-20">
<div className="w-content-width mx-auto flex justify-center">
<Loader2 className="size-8 animate-spin text-foreground" strokeWidth={1.5} />
</div>
</section>
);
}
if (!products || products.length === 0) {
return null;
}
const ProductMediaCards = ({ tag, title, description, products }: ProductMediaCardsProps) => {
return (
<section aria-label="Products section" className="py-20">
<div className="flex flex-col gap-8">
<div className="flex flex-col items-center w-content-width mx-auto gap-3 md:gap-2">
<span className="px-3 py-1 text-sm card rounded">{tag}</span>
<TextAnimation
text={title}
variant="slide-up"
tag="h2"
className="text-6xl font-medium text-center text-balance"
/>
<TextAnimation
text={description}
variant="slide-up"
tag="p"
className="md:max-w-6/10 text-lg leading-tight text-center"
/>
{(primaryButton || secondaryButton) && (
<div className="flex flex-wrap justify-center gap-3 mt-1 md:mt-2">
{primaryButton && <Button text={primaryButton.text} href={primaryButton.href} variant="primary" animate />}
{secondaryButton && <Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary" animate delay={0.1} />}
</div>
)}
<section className="relative py-20 bg-background text-foreground">
<div className="w-full text-center mb-12">
<GlassmorphicBadge fact={getRandomFact()} />
</div>
<div className="container mx-auto px-4">
<div className="text-center">
<span className="px-3 py-1 text-sm rounded card">{tag}</span>
<h2 className="text-6xl font-medium text-center text-balance mt-4">{title}</h2>
<p className="md:max-w-6/10 text-lg leading-tight text-center mx-auto mt-4">{description}</p>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
{products.map((product) => (
<div key={product.name} className="card p-4 rounded-lg text-left">
<img src={product.imageSrc} alt={product.name} className="rounded-md h-64 w-full object-cover" />
<h3 className="text-xl font-semibold mt-4">{product.name}</h3>
<p className="text-accent mt-1">{product.price}</p>
</div>
))}
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-15%" }}
transition={{ duration: 0.6, ease: "easeOut" }}
>
<GridOrCarousel carouselThreshold={3}>
{products.map((product) => (
<button
key={product.name}
onClick={product.onClick}
className="group h-full flex flex-col gap-5 p-5 text-left card rounded cursor-pointer"
>
<div className="aspect-square rounded overflow-hidden">
<ImageOrVideo imageSrc={product.imageSrc} />
</div>
<div className="flex items-center justify-between gap-3">
<div className="flex-1 min-w-0">
<h3 className="text-base font-medium truncate">{product.name}</h3>
<p className="text-2xl font-medium">{product.price}</p>
</div>
<div className="flex items-center justify-center size-10 shrink-0 rounded primary-button">
<ArrowUpRight className="size-4 text-primary-cta-text transition-transform duration-300 group-hover:rotate-45" strokeWidth={1.5} />
</div>
</div>
</button>
))}
</GridOrCarousel>
</motion.div>
</div>
</section>
);
};
export default ProductMediaCards;
export default ProductMediaCards;

View File

@@ -2,6 +2,8 @@ import { motion } from "motion/react";
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
import GlassmorphicBadge from "@/components/ui/GlassmorphicBadge";
import { getRandomFact } from "@/utils/facts";
type Testimonial = {
name: string;
@@ -30,6 +32,9 @@ const TestimonialMarqueeCards = ({
return (
<section aria-label="Testimonials section" className="py-20">
<div className="w-full text-center mb-8">
<GlassmorphicBadge fact={getRandomFact()} />
</div>
<div className="flex flex-col gap-8">
<div className="flex flex-col items-center gap-3 md:gap-2 w-content-width mx-auto">
<span className="px-3 py-1 text-sm rounded card">{tag}</span>

View File

@@ -0,0 +1,9 @@
const GlassmorphicBadge = ({ fact }: { fact: string }) => {
return (
<div className="inline-block backdrop-blur-sm bg-white/30 rounded-lg px-3 py-1 text-sm text-foreground max-w-xs text-balance">
{fact}
</div>
);
};
export default GlassmorphicBadge;

View File

@@ -4,6 +4,8 @@ import { motion, AnimatePresence } from "motion/react";
import { Plus, ArrowRight } from "lucide-react";
import { cls } from "@/lib/utils";
import Button from "@/components/ui/Button";
import GlassmorphicBadge from "@/components/ui/GlassmorphicBadge";
import { getRandomFact } from "@/utils/facts";
interface NavbarCenteredProps {
logo: string;
@@ -60,10 +62,13 @@ const NavbarCentered = ({ logo, navItems, ctaButton }: NavbarCenteredProps) => {
<nav
className={cls(
"fixed z-1000 top-0 left-0 w-full transition-all duration-500 ease-in-out",
isScrolled ? "h-15 bg-background/80 backdrop-blur-sm" : "h-20 bg-background/0 backdrop-blur-0"
isScrolled ? "py-2 bg-background/80 backdrop-blur-sm" : "py-4 bg-background/0 backdrop-blur-0"
)}
>
<div className="relative flex items-center justify-between h-full w-content-width mx-auto">
<div className="w-full text-center">
<GlassmorphicBadge fact={getRandomFact()} />
</div>
<div className="relative flex items-center justify-between w-content-width mx-auto mt-2">
<Link to="/" className="text-xl font-medium text-foreground">{logo}</Link>
<div className="hidden md:flex absolute left-1/2 items-center gap-6 -translate-x-1/2">

View File

@@ -175,3 +175,11 @@ h6 {
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
border: 1px solid var(--color-secondary-cta);
}
.glassmorphic-badge {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
}

14
src/utils/facts.ts Normal file
View File

@@ -0,0 +1,14 @@
export const funnyFacts: string[] = [
"Our sourdough starter is named 'Dough-minatrix'. She's very demanding.",
"We once tried to make a bread so big it had its own zip code.",
"Our croissants are 99% butter, 1% magic. And a little bit of flour.",
"Legend says our head baker can communicate with yeast on a spiritual level.",
"We accidentally invented a new pastry. We call it the 'Oopsie-danish'.",
"Our cinnamon rolls are so good, they've been known to solve family disputes.",
"The secret ingredient is love. And an alarming amount of butter.",
"Our bakers sing to the bread. It makes the crust extra crispy.",
];
export const getRandomFact = (): string => {
return funnyFacts[Math.floor(Math.random() * funnyFacts.length)];
};