-
Explore
- {navLinks.map((link) => (
-
+
+
Explore
+ {NAV_LINKS.map((link) => (
+
{link.name}
))}
-
-
Connect
-
-
-
-
-
-
-
-
-
-
+
+
Connect
+
-
+
© {new Date().getFullYear()} Mani Candles Co. All rights reserved.
-
+
);
}
diff --git a/src/components/ScrollCandle.css b/src/components/ScrollCandle.css
new file mode 100644
index 0000000..8f03063
--- /dev/null
+++ b/src/components/ScrollCandle.css
@@ -0,0 +1,291 @@
+/* ─── ScrollCandle.css ───────────────────────────────────── */
+
+.scroll-candle-wrap {
+ position: fixed;
+ right: 28px;
+ bottom: 0px;
+ z-index: 999;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ pointer-events: none;
+ filter: drop-shadow(0 0 18px rgba(255, 160, 40, 0.35));
+}
+
+/* ── FLAME SYSTEM ─────────────────────────────────── */
+.candle-flame-wrap {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-bottom: -2px;
+}
+
+/* Outer glow halo */
+.flame-glow {
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 48px;
+ height: 48px;
+ border-radius: 50%;
+ background: radial-gradient(circle, rgba(255, 200, 50, 0.45) 0%, transparent 70%);
+ animation: glow-pulse 1.8s ease-in-out infinite alternate;
+ z-index: 0;
+}
+
+@keyframes glow-pulse {
+ 0% {
+ transform: translateX(-50%) scale(1);
+ opacity: 0.7;
+ }
+
+ 100% {
+ transform: translateX(-50%) scale(1.35);
+ opacity: 1;
+ }
+}
+
+/* Flame outer — large orange teardrop */
+.flame-outer {
+ position: relative;
+ z-index: 2;
+ width: 18px;
+ height: 34px;
+ background: linear-gradient(to top, #ff6a00, #ffaa00, #ffe066);
+ border-radius: 50% 50% 30% 30% / 60% 60% 40% 40%;
+ transform-origin: bottom center;
+ animation: flicker-outer 0.9s ease-in-out infinite alternate;
+ box-shadow:
+ 0 0 8px 3px rgba(255, 140, 0, 0.6),
+ 0 0 18px 6px rgba(255, 100, 0, 0.4);
+}
+
+@keyframes flicker-outer {
+ 0% {
+ transform: scaleX(1) scaleY(1) rotate(-2deg);
+ }
+
+ 25% {
+ transform: scaleX(0.88) scaleY(1.05) rotate(2deg);
+ }
+
+ 50% {
+ transform: scaleX(1.05) scaleY(0.95) rotate(-1deg);
+ }
+
+ 75% {
+ transform: scaleX(0.92) scaleY(1.08) rotate(3deg);
+ }
+
+ 100% {
+ transform: scaleX(1.02) scaleY(1.02) rotate(-2deg);
+ }
+}
+
+/* Flame inner — bright white-yellow core */
+.flame-inner {
+ position: absolute;
+ bottom: 4px;
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 3;
+ width: 8px;
+ height: 18px;
+ background: linear-gradient(to top, #fff8c5, #fff, rgba(255, 255, 255, 0));
+ border-radius: 50% 50% 30% 30% / 60% 60% 40% 40%;
+ animation: flicker-inner 0.7s ease-in-out infinite alternate;
+ opacity: 0.9;
+}
+
+@keyframes flicker-inner {
+ 0% {
+ transform: translateX(-50%) scaleX(1) scaleY(1);
+ }
+
+ 50% {
+ transform: translateX(-50%) scaleX(0.85) scaleY(1.1);
+ }
+
+ 100% {
+ transform: translateX(-50%) scaleX(1.1) scaleY(0.9);
+ }
+}
+
+/* ── SMOKE PARTICLES ─────────────────────────────── */
+.smoke-wrap {
+ position: absolute;
+ top: -18px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 20px;
+ height: 20px;
+ pointer-events: none;
+ z-index: 4;
+}
+
+.smoke-particle {
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ width: 4px;
+ height: 4px;
+ border-radius: 50%;
+ background: rgba(200, 180, 220, 0.45);
+ transform: translateX(-50%);
+ animation: smoke-rise 2.4s ease-out infinite;
+ opacity: 0;
+}
+
+.smoke-particle:nth-child(2) {
+ animation-delay: 0.8s;
+ left: 40%;
+}
+
+.smoke-particle:nth-child(3) {
+ animation-delay: 1.6s;
+ left: 60%;
+}
+
+@keyframes smoke-rise {
+ 0% {
+ transform: translateX(-50%) translateY(0) scale(0.6);
+ opacity: 0;
+ }
+
+ 20% {
+ opacity: 0.5;
+ }
+
+ 100% {
+ transform: translateX(-50%) translateY(-22px) scale(2);
+ opacity: 0;
+ }
+}
+
+/* ── WICK ──────────────────────────────────────────── */
+.candle-wick {
+ width: 2px;
+ height: 8px;
+ background: linear-gradient(to bottom, #3a2000, #1a0f00);
+ border-radius: 1px;
+ position: relative;
+ z-index: 2;
+ margin-bottom: -1px;
+}
+
+/* ── CANDLE BODY ──────────────────────────────────── */
+.candle-body {
+ position: relative;
+ width: 22px;
+ background: linear-gradient(to right,
+ #e8dcc8 0%,
+ #fdf6e3 25%,
+ #fff9f0 50%,
+ #fdf6e3 75%,
+ #d9cbb5 100%);
+ border-radius: 3px 3px 4px 4px;
+ transition: height 0.18s linear;
+ box-shadow:
+ inset -3px 0 6px rgba(0, 0, 0, 0.1),
+ inset 3px 0 4px rgba(255, 255, 255, 0.4);
+ overflow: visible;
+}
+
+/* Candle top melted rim */
+.candle-body::before {
+ content: '';
+ position: absolute;
+ top: -3px;
+ left: -2px;
+ right: -2px;
+ height: 6px;
+ background: radial-gradient(ellipse at center, #ffe8b0 0%, #e8d5a0 100%);
+ border-radius: 50%;
+ z-index: 1;
+}
+
+/* ── WAX DRIPS ──────────────────────────────────────── */
+.wax-drip {
+ position: absolute;
+ top: 2px;
+ width: 5px;
+ background: linear-gradient(to bottom, rgba(253, 246, 227, 0.95), rgba(232, 220, 200, 0.6));
+ border-radius: 0 0 4px 4px;
+ animation: drip-grow 4s ease-in-out infinite;
+}
+
+.wax-drip-1 {
+ left: -3px;
+ height: 14px;
+ animation-delay: 0s;
+ animation-duration: 4.5s;
+}
+
+.wax-drip-2 {
+ right: -3px;
+ height: 10px;
+ animation-delay: 1.2s;
+ animation-duration: 3.8s;
+}
+
+.wax-drip-3 {
+ left: 2px;
+ height: 18px;
+ animation-delay: 2.5s;
+ animation-duration: 5.2s;
+}
+
+@keyframes drip-grow {
+ 0% {
+ height: 6px;
+ opacity: 0.7;
+ }
+
+ 60% {
+ height: 20px;
+ opacity: 1;
+ }
+
+ 100% {
+ height: 6px;
+ opacity: 0.7;
+ }
+}
+
+/* ── CANDLE BASE / HOLDER ────────────────────────── */
+.candle-base {
+ width: 32px;
+ height: 10px;
+ background: linear-gradient(to bottom, #c8a96e, #a07840);
+ border-radius: 3px 3px 6px 6px;
+ box-shadow:
+ 0 3px 8px rgba(0, 0, 0, 0.3),
+ inset 0 1px 2px rgba(255, 200, 100, 0.4);
+ position: relative;
+}
+
+/* Holder shine */
+.candle-base::after {
+ content: '';
+ position: absolute;
+ top: 2px;
+ left: 5px;
+ width: 8px;
+ height: 3px;
+ background: rgba(255, 220, 140, 0.4);
+ border-radius: 50%;
+}
+
+/* ── SCROLL LABEL ───────────────────────────────── */
+.candle-scroll-label {
+ margin-top: 6px;
+ font-family: var(--font-script);
+ font-size: 0.68rem;
+ color: rgba(212, 162, 76, 0.7);
+ letter-spacing: 0.05em;
+ white-space: nowrap;
+ text-align: center;
+ transition: opacity 0.3s ease;
+}
\ No newline at end of file
diff --git a/src/components/ScrollCandle.tsx b/src/components/ScrollCandle.tsx
new file mode 100644
index 0000000..8ab3d6c
--- /dev/null
+++ b/src/components/ScrollCandle.tsx
@@ -0,0 +1,99 @@
+import { useEffect, useState } from "react";
+import "./ScrollCandle.css";
+
+// Space taken by flame + wick + base + label + bottom offset + header (ticker 36 + AppBar 76) + safety gap
+const NON_BODY_HEIGHT = 70 + 8 + 10 + 24 + 40 + 112 + 16;
+const CANDLE_MIN_HEIGHT = 14; // px — almost fully melted
+
+export function ScrollCandle() {
+ const [maxHeight, setMaxHeight] = useState(
+ () => Math.max(200, window.innerHeight - NON_BODY_HEIGHT)
+ );
+ const [candleHeight, setCandleHeight] = useState(
+ () => Math.max(200, window.innerHeight - NON_BODY_HEIGHT)
+ );
+ const [scrollPct, setScrollPct] = useState(0);
+
+ // Recalculate on resize
+ useEffect(() => {
+ const onResize = () => {
+ const newMax = Math.max(200, window.innerHeight - NON_BODY_HEIGHT);
+ setMaxHeight(newMax);
+ };
+ window.addEventListener("resize", onResize);
+ return () => window.removeEventListener("resize", onResize);
+ }, []);
+
+ useEffect(() => {
+ const handleScroll = () => {
+ const scrollTop = window.scrollY;
+ const docHeight = document.documentElement.scrollHeight - window.innerHeight;
+ const pct = docHeight > 0 ? Math.min(scrollTop / docHeight, 1) : 0;
+
+ setScrollPct(pct);
+ setCandleHeight(
+ Math.max(CANDLE_MIN_HEIGHT, maxHeight - pct * (maxHeight - CANDLE_MIN_HEIGHT))
+ );
+ };
+
+ window.addEventListener("scroll", handleScroll, { passive: true });
+ return () => window.removeEventListener("scroll", handleScroll);
+ }, [maxHeight]);
+
+ // Flame shrinks slightly as candle melts
+ const flameScale = 0.6 + (candleHeight / maxHeight) * 0.4;
+ // Label changes as candle melts
+ const label =
+ scrollPct < 0.15 ? "just lit" :
+ scrollPct < 0.45 ? "burning..." :
+ scrollPct < 0.75 ? "melting..." :
+ scrollPct < 0.92 ? "almost gone" :
+ "★ keep scrolling";
+
+ return (
+
+ {/* ── Flame ── */}
+
+ {/* Smoke */}
+
+
+ {/* Glow halo */}
+
+
+ {/* Outer flame */}
+
+
+
+ {/* ── Wick ── */}
+
+
+ {/* ── Candle Body (shrinks on scroll) ── */}
+
+
+ {/* ── Base / Holder ── */}
+
+
+ {/* ── Label ── */}
+
0.02 ? 1 : 0 }}
+ >
+ {label}
+
+
+ );
+}
diff --git a/src/index.css b/src/index.css
index 9c7bc2c..97a5c9a 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,176 +1,85 @@
@import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;500;600;700&family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400&family=Great+Vibes&family=Inter:wght@300;400;500;600&display=swap');
-@import "tailwindcss";
-@import "tw-animate-css";
-@plugin "@tailwindcss/typography";
-
-@custom-variant dark (&:is(.dark *));
-
-@theme inline {
- --color-background: hsl(var(--background));
- --color-foreground: hsl(var(--foreground));
- --color-border: hsl(var(--border));
- --color-input: hsl(var(--input));
- --color-ring: hsl(var(--ring));
-
- --color-card: hsl(var(--card));
- --color-card-foreground: hsl(var(--card-foreground));
- --color-card-border: hsl(var(--card-border));
-
- --color-popover: hsl(var(--popover));
- --color-popover-foreground: hsl(var(--popover-foreground));
- --color-popover-border: hsl(var(--popover-border));
-
- --color-primary: hsl(var(--primary));
- --color-primary-foreground: hsl(var(--primary-foreground));
- --color-primary-border: var(--primary-border);
-
- --color-secondary: hsl(var(--secondary));
- --color-secondary-foreground: hsl(var(--secondary-foreground));
- --color-secondary-border: var(--secondary-border);
-
- --color-muted: hsl(var(--muted));
- --color-muted-foreground: hsl(var(--muted-foreground));
- --color-muted-border: var(--muted-border);
-
- --color-accent: hsl(var(--accent));
- --color-accent-foreground: hsl(var(--accent-foreground));
- --color-accent-border: var(--accent-border);
-
- --color-destructive: hsl(var(--destructive));
- --color-destructive-foreground: hsl(var(--destructive-foreground));
- --color-destructive-border: var(--destructive-border);
-
- --color-chart-1: hsl(var(--chart-1));
- --color-chart-2: hsl(var(--chart-2));
- --color-chart-3: hsl(var(--chart-3));
- --color-chart-4: hsl(var(--chart-4));
- --color-chart-5: hsl(var(--chart-5));
-
- --color-sidebar: hsl(var(--sidebar));
- --color-sidebar-foreground: hsl(var(--sidebar-foreground));
- --color-sidebar-border: hsl(var(--sidebar-border));
- --color-sidebar-primary: hsl(var(--sidebar-primary));
- --color-sidebar-primary-foreground: hsl(var(--sidebar-primary-foreground));
- --color-sidebar-primary-border: var(--sidebar-primary-border);
- --color-sidebar-accent: hsl(var(--sidebar-accent));
- --color-sidebar-accent-foreground: hsl(var(--sidebar-accent-foreground));
- --color-sidebar-accent-border: var(--sidebar-accent-border);
- --color-sidebar-ring: hsl(var(--sidebar-ring));
-
- --font-sans: var(--app-font-sans);
- --font-serif: var(--app-font-serif);
- --font-display: var(--app-font-display);
- --font-script: var(--app-font-script);
- --font-mono: var(--app-font-mono);
-
- --radius-sm: calc(var(--radius) - 4px);
- --radius-md: calc(var(--radius) - 2px);
- --radius-lg: var(--radius);
- --radius-xl: calc(var(--radius) + 4px);
-}
+/* ─── CSS Custom Properties ─────────────────────────────── */
:root {
- --background: 272 68% 94%;
- --foreground: 272 65% 18%;
- --card: 272 68% 97%;
- --card-foreground: 272 65% 18%;
- --card-border: 272 40% 85%;
- --popover: 272 68% 97%;
- --popover-foreground: 272 65% 18%;
- --popover-border: 272 40% 85%;
- --primary: 272 65% 34%;
- --primary-foreground: 0 0% 100%;
- --secondary: 272 68% 87%;
- --secondary-foreground: 272 65% 25%;
- --muted: 272 40% 90%;
- --muted-foreground: 272 30% 50%;
- --accent: 38 59% 56%;
- --accent-foreground: 0 0% 100%;
- --destructive: 0 84% 60%;
- --destructive-foreground: 0 0% 100%;
- --border: 272 40% 82%;
- --input: 272 40% 82%;
- --ring: 272 65% 34%;
- --chart-1: 272 65% 34%;
- --chart-2: 38 59% 56%;
- --chart-3: 272 68% 70%;
- --chart-4: 44 100% 71%;
- --chart-5: 272 50% 55%;
- --sidebar: 272 68% 87%;
- --sidebar-foreground: 272 65% 18%;
- --sidebar-border: 272 40% 80%;
- --sidebar-primary: 272 65% 34%;
- --sidebar-primary-foreground: 0 0% 100%;
- --sidebar-accent: 38 59% 56%;
- --sidebar-accent-foreground: 0 0% 100%;
- --sidebar-ring: 272 65% 34%;
- --app-font-sans: 'Inter', sans-serif;
- --app-font-serif: 'Cormorant Garamond', serif;
- --app-font-display: 'Cinzel', serif;
- --app-font-script: 'Great Vibes', cursive;
- --app-font-mono: Menlo, monospace;
- --radius: 0.75rem;
+ --brand-purple: #5B1E8C;
+ --brand-purple-dark: #3A1260;
+ --brand-purple-mid: #7B3DB8;
+ --brand-lavender: #DCC6F2;
+ --brand-light-lavender:#EFE4FA;
+ --brand-card: #F8F2FD;
+ --brand-gold: #D4A24C;
+ --brand-gold-light: #FFD36B;
+ --brand-gold-core: #FFF3C4;
+ --brand-text: #2D0D52;
+ --brand-muted: #7B5A9E;
+ --brand-border: #D5BEF0;
- --brand-purple: #5B1E8C;
- --brand-lavender: #DCC6F2;
- --brand-light-lavender: #EFE4FA;
- --brand-gold: #D4A24C;
- --brand-flame-glow: #FFD36B;
- --brand-flame-core: #FFF3C4;
+ --font-sans: 'Inter', sans-serif;
+ --font-serif: 'Cormorant Garamond', serif;
+ --font-display: 'Cinzel', serif;
+ --font-script: 'Great Vibes', cursive;
}
-.dark {
- --background: 272 65% 10%;
- --foreground: 272 68% 94%;
- --card: 272 65% 15%;
- --card-foreground: 272 68% 94%;
- --card-border: 272 65% 25%;
- --popover: 272 65% 15%;
- --popover-foreground: 272 68% 94%;
- --popover-border: 272 65% 25%;
- --primary: 272 68% 87%;
- --primary-foreground: 272 65% 18%;
- --secondary: 272 65% 20%;
- --secondary-foreground: 272 68% 94%;
- --muted: 272 65% 20%;
- --muted-foreground: 272 40% 70%;
- --accent: 38 59% 56%;
- --accent-foreground: 0 0% 100%;
- --destructive: 0 84% 60%;
- --destructive-foreground: 0 0% 100%;
- --border: 272 65% 25%;
- --input: 272 65% 25%;
- --ring: 272 68% 87%;
- --chart-1: 272 68% 87%;
- --chart-2: 38 59% 56%;
- --chart-3: 272 68% 70%;
- --chart-4: 44 100% 71%;
- --chart-5: 272 50% 55%;
+/* ─── Reset / Base ───────────────────────────────────────── */
+*, *::before, *::after {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
}
-@layer base {
- * {
- @apply border-border;
- }
- body {
- @apply font-sans antialiased bg-background text-foreground;
- }
- h1, h2, h3, h4, h5, h6 {
- @apply font-serif;
- }
+html {
+ scroll-behavior: smooth;
}
+body {
+ font-family: var(--font-sans);
+ background-color: var(--brand-light-lavender);
+ color: var(--brand-text);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ line-height: 1.6;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-family: var(--font-serif);
+ line-height: 1.2;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+img {
+ max-width: 100%;
+ display: block;
+}
+
+/* ─── Keyframe Animations ────────────────────────────────── */
@keyframes flame-flicker {
- 0%, 100% {
- transform: scale(1) translateY(0);
- opacity: 0.9;
- }
- 50% {
- transform: scale(1.05) translateY(-2px);
- opacity: 1;
- }
+ 0%, 100% { transform: scale(1) translateY(0); opacity: 0.9; }
+ 50% { transform: scale(1.05) translateY(-2px); opacity: 1; }
}
+@keyframes fadeInUp {
+ from { opacity: 0; transform: translateY(24px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+/* ─── Global Utility Classes ─────────────────────────────── */
.animate-flame {
animation: flame-flicker 2s ease-in-out infinite alternate;
}
+
+.font-script {
+ font-family: var(--font-script);
+}
+
+.font-display {
+ font-family: var(--font-display);
+}
+
+.font-serif {
+ font-family: var(--font-serif);
+}
diff --git a/src/main.tsx b/src/main.tsx
index 696e0d2..8f85eee 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,5 +1,13 @@
import { createRoot } from "react-dom/client";
+import { ThemeProvider } from "@mui/material/styles";
+import CssBaseline from "@mui/material/CssBaseline";
import App from "./App";
+import theme from "./theme";
import "./index.css";
-createRoot(document.getElementById("root")!).render(
);
+createRoot(document.getElementById("root")!).render(
+
+
+
+
+);
diff --git a/src/pages/AboutPage.tsx b/src/pages/AboutPage.tsx
index f08be70..16d86ab 100644
--- a/src/pages/AboutPage.tsx
+++ b/src/pages/AboutPage.tsx
@@ -1,139 +1,105 @@
import { motion } from "framer-motion";
import { Droplets, Flame, HeartHandshake } from "lucide-react";
+import Box from "@mui/material/Box";
+import Container from "@mui/material/Container";
+import "./about.css";
const logoPath = "/opengraph.jpg";
+const fadeInUp = {
+ hidden: { opacity: 0, y: 30 },
+ visible: { opacity: 1, y: 0, transition: { duration: 0.8, ease: "easeOut" } },
+};
+
+const stagger = {
+ visible: { transition: { staggerChildren: 0.2 } },
+};
+
export default function AboutPage() {
- const fadeInUp = {
- hidden: { opacity: 0, y: 30 },
- visible: { opacity: 1, y: 0, transition: { duration: 0.8, ease: "easeOut" } },
- };
-
- const stagger = {
- visible: { transition: { staggerChildren: 0.2 } },
- };
-
return (
-
- {/* Hero */}
-
-
-
- The Light Behind the Wax
-
-
-
- Mani Candles Co. is a small handmade candle brand crafted with love, natural ingredients, and intention. Every candle is poured by hand in small batches, designed to bring warmth, luxury, and a touch of romance into your sacred spaces.
-
-
+
+ {/* ── Hero ── */}
+
+
+
+ The Light Behind the Wax
+
+
+ Mani Candles Co. is a small handmade candle brand crafted with love, natural ingredients, and intention.
+ Every candle is poured by hand in small batches, designed to bring warmth, luxury, and a touch of romance
+ into your sacred spaces.
+
+
+
- {/* Brand Values */}
-
-
-
+ {/* ── Brand Values ── */}
+
+
+
{[
- {
- icon:
,
- title: "Handmade",
- desc: "We believe in the power of human touch. No machines, no mass production. Just careful hands pouring beautiful creations."
- },
- {
- icon:
,
- title: "Natural",
- desc: "Pure soy wax, lead-free cotton wicks, and premium fragrance oils infused with essential oils. Clean burns only."
- },
- {
- icon:
,
- title: "Heartmade",
- desc: "A candle is more than wax and scent. It's ambiance, memory, and comfort. We put our heart into every jar."
- }
- ].map((val, i) => (
+ { Icon: HeartHandshake, title: "Handmade", desc: "We believe in the power of human touch. No machines, no mass production. Just careful hands pouring beautiful creations." },
+ { Icon: Droplets, title: "Natural", desc: "Pure soy wax, lead-free cotton wicks, and premium fragrance oils infused with essential oils. Clean burns only." },
+ { Icon: Flame, title: "Heartmade", desc: "A candle is more than wax and scent. It's ambiance, memory, and comfort. We put our heart into every jar." },
+ ].map(({ Icon, title, desc }, i) => (
- {val.icon}
- {val.title}
- {val.desc}
+
+ {title}
+ {desc}
))}
-
+
- {/* Meet the Maker */}
-
-
-
-
-
-
-
-
-
- Meet the Maker
-
-
-
- What started as a quiet evening hobby quickly blossomed into a deep passion for the alchemy of scent and light.
-
-
- I wanted to create more than just candles; I wanted to craft experiences. The flicker of the flame, the slow release of carefully blended perfumes—these elements have the power to transform a chaotic day into a moment of pure serenity.
-
-
- Every Mani candle is a piece of my heart, poured in small batches to ensure that the luxury you experience is entirely personal and authentically handmade.
-
-
- With love,
-
-
-
-
+ {/* ── Meet the Maker ── */}
+
+
+
+
+
+
+
+
+
+
+ Meet the Maker
+
+ What started as a quiet evening hobby quickly blossomed into a deep passion for the alchemy of scent and light.
+ I wanted to create more than just candles; I wanted to craft experiences. The flicker of the flame, the slow release of carefully blended perfumes—these elements have the power to transform a chaotic day into a moment of pure serenity.
+ Every Mani candle is a piece of my heart, poured in small batches to ensure that the luxury you experience is entirely personal and authentically handmade.
+ With love,
+
+
+
- {/* Process Timeline */}
-
-
-
- Our Process
- The journey of a Mani Candle.
-
+ {/* ── Process Timeline ── */}
+
+
+ Our Process
+ The journey of a Mani Candle.
-
+
{[
{ step: "01", title: "Sourcing", desc: "We select only the finest natural soy wax and premium, phthalate-free fragrances." },
{ step: "02", title: "Blending", desc: "Fragrances are meticulously mixed at the exact temperature for optimal throw." },
@@ -143,24 +109,22 @@ export default function AboutPage() {
].map((item, i) => (
-
- {item.step}
-
-
-
{item.title}
-
{item.desc}
+
{item.step}
+
+
{item.title}
+
{item.desc}
))}
-
+
-
+
);
}
diff --git a/src/pages/ContactPage.tsx b/src/pages/ContactPage.tsx
index 1e95468..605de4c 100644
--- a/src/pages/ContactPage.tsx
+++ b/src/pages/ContactPage.tsx
@@ -1,6 +1,15 @@
import { motion } from "framer-motion";
import { Mail, MapPin, Phone, Instagram } from "lucide-react";
+import { HeartHandshake } from "lucide-react";
import { useState } from "react";
+import Box from "@mui/material/Box";
+import Container from "@mui/material/Container";
+import "./contact.css";
+
+const fadeInUp = {
+ hidden: { opacity: 0, y: 30 },
+ visible: { opacity: 1, y: 0, transition: { duration: 0.8, ease: "easeOut" } },
+};
export default function ContactPage() {
const [formStatus, setFormStatus] = useState<"idle" | "submitting" | "success">("idle");
@@ -8,197 +17,117 @@ export default function ContactPage() {
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
setFormStatus("submitting");
- // Simulate network request
- setTimeout(() => {
- setFormStatus("success");
- }, 1500);
- };
-
- const fadeInUp = {
- hidden: { opacity: 0, y: 30 },
- visible: { opacity: 1, y: 0, transition: { duration: 0.8, ease: "easeOut" } },
+ setTimeout(() => setFormStatus("success"), 1500);
};
return (
-
-
-
- Get in Touch
-
- Whether you have a question about an order, wholesale inquiries, or simply want to share how much you love your new candle, we'd love to hear from you.
-
-
-
+
+ {/* ── Hero ── */}
+
+
+
+ Get in Touch
+ Whether you have a question about an order, wholesale inquiries, or simply want to share how much you love your new candle, we'd love to hear from you.
+
+
+
-
-
-
- {/* Contact Info */}
-
-
-
Contact Information
-
-
-
-
+ {/* ── Contact Body ── */}
+
+
+
+ {/* Info Panel */}
+
+ Contact Information
+
+ {[
+ { Icon: Mail, label: "Email", value:
hello@manicandles.co },
+ { Icon: Phone, label: "Phone", value: <>Available Mon–Fri, 9am–5pm EST
+1 (555) 123-4567> },
+ { Icon: MapPin, label: "Studio", value: <>New York, NY
(By appointment only)> },
+ ].map(({ Icon, label, value }) => (
+
-
-
-
-
-
-
-
Phone
-
- Available Mon-Fri, 9am - 5pm EST
- +1 (555) 123-4567
-
-
-
-
-
-
-
-
-
-
Studio
-
- New York, NY
- (By appointment only)
-
-
-
+ ))}
-
-
-
Follow Our Journey
-
- Join our community on Instagram for behind-the-scenes peeks, styling inspiration, and launch announcements.
-
-
-
- @manicandles.co
-
-
-
+
+
Follow Our Journey
+
Join our community on Instagram for behind-the-scenes peeks, styling inspiration, and launch announcements.
+
+
+ @manicandles.co
+
+
+
- {/* Form */}
-
-
- Send a Message
-
- {formStatus === "success" ? (
-
-
-
-
- Thank you!
-
- Your message has been received. We will get back to you as soon as possible.
-
-
-
- ) : (
-
- )}
-
-
+
+
Thank you!
+
Your message has been received. We will get back to you as soon as possible.
+
+
+ ) : (
+ <>
+
Send a Message
+
+ >
+ )}
+
+
+
-
-
- "May the light of our candles bring peace to your mind and warmth to your soul."
-
+ {/* ── Closing Quote ── */}
+
+ "May the light of our candles bring peace to your mind and warmth to your soul."
-
+
);
-}
-
-// Ensure HeartHandshake is imported
-import { HeartHandshake } from "lucide-react";
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/pages/ProductsPage.tsx b/src/pages/ProductsPage.tsx
index 29558ac..f02287a 100644
--- a/src/pages/ProductsPage.tsx
+++ b/src/pages/ProductsPage.tsx
@@ -1,5 +1,7 @@
import { motion } from "framer-motion";
import { useState } from "react";
+import Box from "@mui/material/Box";
+import Container from "@mui/material/Container";
import birthdayImage from "@/assets/images/product-birthday.png";
import eucalyptusImage from "@/assets/images/product-eucalyptus.png";
import jasmineImage from "@/assets/images/product-jasmine.png";
@@ -8,124 +10,56 @@ import linenImage from "@/assets/images/product-linen.png";
import oudImage from "@/assets/images/product-oud.png";
import roseImage from "@/assets/images/product-rose.png";
import sandalwoodImage from "@/assets/images/product-sandalwood.png";
+import "./products.css";
const PRODUCTS = [
- {
- id: 1,
- name: "Lavender Dream",
- scent: "Calming French Lavender, Vanilla, & Bergamot",
- price: "$28",
- image: lavenderImage,
- category: "Floral",
- },
- {
- id: 2,
- name: "Rose & Vanilla",
- scent: "Damask Rose, Sweet Vanilla bean, & Amber",
- price: "$32",
- image: roseImage,
- category: "Floral",
- },
- {
- id: 3,
- name: "Eucalyptus Mint",
- scent: "Fresh Eucalyptus, Spearmint, & Cedar",
- price: "$28",
- image: eucalyptusImage,
- category: "Fresh",
- },
- {
- id: 4,
- name: "Oud & Amber",
- scent: "Rich Oud Wood, Warm Amber, & Dark Musk",
- price: "$36",
- image: oudImage,
- category: "Woody",
- },
- {
- id: 5,
- name: "Jasmine Night",
- scent: "Night-blooming Jasmine, Ylang Ylang, & Sandalwood",
- price: "$30",
- image: jasmineImage,
- category: "Floral",
- },
- {
- id: 6,
- name: "Sandalwood Cedar",
- scent: "Indian Sandalwood, Cedarwood, & Patchouli",
- price: "$34",
- image: sandalwoodImage,
- category: "Woody",
- },
- {
- id: 7,
- name: "Fresh Linen",
- scent: "Crisp Cotton, White Tea, & Lily of the Valley",
- price: "$26",
- image: linenImage,
- category: "Fresh",
- },
- {
- id: 8,
- name: "Birthday Cake",
- scent: "Vanilla Buttercream, Sugar Spun, & Joy",
- price: "$28",
- image: birthdayImage,
- category: "Sweet",
- },
+ { id: 1, name: "Lavender Dream", scent: "Calming French Lavender, Vanilla, & Bergamot", price: "$28", image: lavenderImage, category: "Floral" },
+ { id: 2, name: "Rose & Vanilla", scent: "Damask Rose, Sweet Vanilla Bean, & Amber", price: "$32", image: roseImage, category: "Floral" },
+ { id: 3, name: "Eucalyptus Mint", scent: "Fresh Eucalyptus, Spearmint, & Cedar", price: "$28", image: eucalyptusImage, category: "Fresh" },
+ { id: 4, name: "Oud & Amber", scent: "Rich Oud Wood, Warm Amber, & Dark Musk", price: "$36", image: oudImage, category: "Woody" },
+ { id: 5, name: "Jasmine Night", scent: "Night-blooming Jasmine, Ylang Ylang, & Sandalwood", price: "$30", image: jasmineImage, category: "Floral" },
+ { id: 6, name: "Sandalwood Cedar", scent: "Indian Sandalwood, Cedarwood, & Patchouli", price: "$34", image: sandalwoodImage, category: "Woody" },
+ { id: 7, name: "Fresh Linen", scent: "Crisp Cotton, White Tea, & Lily of the Valley", price: "$26", image: linenImage, category: "Fresh" },
+ { id: 8, name: "Birthday Cake", scent: "Vanilla Buttercream, Sugar Spun, & Joy", price: "$28", image: birthdayImage, category: "Sweet" },
];
export default function ProductsPage() {
const [filter, setFilter] = useState("All");
-
const categories = ["All", ...Array.from(new Set(PRODUCTS.map((p) => p.category)))];
-
- const filteredProducts = filter === "All" ? PRODUCTS : PRODUCTS.filter(p => p.category === filter);
-
- const fadeInUp = {
- hidden: { opacity: 0, y: 20 },
- visible: { opacity: 1, y: 0, transition: { duration: 0.6 } },
- };
+ const filteredProducts = filter === "All" ? PRODUCTS : PRODUCTS.filter((p) => p.category === filter);
return (
-
-
-
- Our Collection
-
- Each candle is meticulously hand-poured with natural soy wax and premium fragrance oils, designed to elevate your everyday rituals.
-
-
-
+
+ {/* ── Hero ── */}
+
+
+
+ Our Collection
+ Each candle is meticulously hand-poured with natural soy wax and premium fragrance oils, designed to elevate your everyday rituals.
+
+
+
-
-
- {/* Filters */}
-
+
+ {/* Filter Bar */}
+
{categories.map((cat) => (
@@ -133,45 +67,34 @@ export default function ProductsPage() {
{/* Grid */}
-
+
{filteredProducts.map((product, index) => (
-
-

-
-
+
+

+
+
-
+
-
{product.name}
-
- {product.scent}
-
+
{product.name}
+
{product.scent}
-
{product.price}
+
{product.price}
))}
-
+
-
+
);
}
diff --git a/src/pages/about.css b/src/pages/about.css
new file mode 100644
index 0000000..95fe746
--- /dev/null
+++ b/src/pages/about.css
@@ -0,0 +1,229 @@
+/* ─── about.css ──────────────────────────────────────────── */
+
+/* HERO */
+.about-hero {
+ padding: 6rem 1.5rem;
+ background: var(--brand-card);
+ text-align: center;
+}
+
+.about-hero h1 {
+ font-family: var(--font-serif);
+ font-size: clamp(2.5rem, 6vw, 4.5rem);
+ color: var(--brand-purple);
+ margin-bottom: 1rem;
+}
+
+.about-hero p {
+ font-family: var(--font-sans);
+ font-size: 1.1rem;
+ color: var(--brand-muted);
+ line-height: 1.8;
+ max-width: 680px;
+ margin: 0 auto;
+}
+
+/* BRAND VALUES */
+.about-values {
+ padding: 6rem 1.5rem;
+ background: var(--brand-light-lavender);
+}
+
+.values-grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 2rem;
+ max-width: 1100px;
+ margin: 0 auto;
+}
+
+@media (min-width: 768px) {
+ .values-grid { grid-template-columns: 1fr 1fr 1fr; }
+}
+
+.value-card {
+ text-align: center;
+ padding: 2.5rem;
+ background: var(--brand-card);
+ border-radius: 0.75rem;
+ border: 1px solid rgba(213,190,240,0.5);
+ box-shadow: 0 2px 12px rgba(91,30,140,0.06);
+ transition: box-shadow 0.3s ease;
+}
+
+.value-card:hover {
+ box-shadow: 0 6px 24px rgba(91,30,140,0.12);
+}
+
+.value-icon {
+ color: var(--brand-gold);
+ display: flex;
+ justify-content: center;
+ margin-bottom: 1.5rem;
+}
+
+.value-card h3 {
+ font-family: var(--font-serif);
+ font-size: 1.5rem;
+ color: var(--brand-purple);
+ margin-bottom: 0.75rem;
+}
+
+.value-card p {
+ font-family: var(--font-sans);
+ color: var(--brand-muted);
+ line-height: 1.7;
+}
+
+/* MEET THE MAKER */
+.about-maker {
+ padding: 6rem 1.5rem;
+ background: var(--brand-purple);
+ color: #ffffff;
+ position: relative;
+ overflow: hidden;
+}
+
+.maker-gradient-overlay {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(to right, transparent, rgba(91,30,140,0.5));
+ mix-blend-mode: overlay;
+}
+
+.maker-grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 4rem;
+ align-items: center;
+ max-width: 1100px;
+ margin: 0 auto;
+ position: relative;
+ z-index: 1;
+}
+
+@media (min-width: 1024px) {
+ .maker-grid { grid-template-columns: 1fr 1fr; }
+}
+
+.maker-img-wrap {
+ aspect-ratio: 1;
+ border-radius: 1rem;
+ overflow: hidden;
+ box-shadow: 0 20px 60px rgba(0,0,0,0.3);
+ position: relative;
+}
+
+.maker-img-wrap img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.maker-img-ring {
+ position: absolute;
+ inset: 0;
+ border-radius: 1rem;
+ box-shadow: inset 0 0 0 1px rgba(255,255,255,0.2);
+}
+
+.maker-content h2 {
+ font-family: var(--font-serif);
+ font-size: clamp(2rem, 4vw, 3rem);
+ color: #ffffff;
+ margin-bottom: 0.75rem;
+}
+
+.maker-divider {
+ width: 80px;
+ height: 4px;
+ background: var(--brand-gold);
+ border-radius: 2px;
+ margin-bottom: 2rem;
+}
+
+.maker-content p {
+ font-family: var(--font-sans);
+ font-size: 1.05rem;
+ line-height: 1.8;
+ color: rgba(255,255,255,0.88);
+ margin-bottom: 1.25rem;
+}
+
+.maker-signature {
+ font-family: var(--font-script);
+ font-size: 2.25rem;
+ color: var(--brand-gold);
+ margin-top: 1.5rem;
+ display: block;
+}
+
+/* PROCESS TIMELINE */
+.about-process {
+ padding: 6rem 1.5rem;
+ background: var(--brand-light-lavender);
+}
+
+.about-process h2 {
+ font-family: var(--font-serif);
+ font-size: clamp(2rem, 4vw, 2.8rem);
+ color: var(--brand-purple);
+ text-align: center;
+ margin-bottom: 0.5rem;
+}
+
+.about-process .subtitle {
+ font-family: var(--font-sans);
+ color: var(--brand-muted);
+ text-align: center;
+ margin-bottom: 5rem;
+}
+
+.timeline {
+ display: flex;
+ flex-direction: column;
+ gap: 3rem;
+ max-width: 900px;
+ margin: 0 auto;
+}
+
+.timeline-item {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+@media (min-width: 640px) {
+ .timeline-item {
+ flex-direction: row;
+ align-items: center;
+ gap: 3rem;
+ }
+}
+
+.timeline-step {
+ font-family: var(--font-serif);
+ font-size: 3.5rem;
+ color: rgba(212,162,76,0.3);
+ font-weight: 300;
+ min-width: 80px;
+ line-height: 1;
+}
+
+.timeline-body {
+ flex: 1;
+ padding-bottom: 2rem;
+ border-bottom: 1px solid rgba(213,190,240,0.5);
+}
+
+.timeline-body h3 {
+ font-family: var(--font-serif);
+ font-size: 1.4rem;
+ color: var(--brand-purple);
+ margin-bottom: 0.4rem;
+}
+
+.timeline-body p {
+ font-family: var(--font-sans);
+ color: var(--brand-muted);
+}
diff --git a/src/pages/contact.css b/src/pages/contact.css
new file mode 100644
index 0000000..838bc71
--- /dev/null
+++ b/src/pages/contact.css
@@ -0,0 +1,316 @@
+/* ─── contact.css ────────────────────────────────────────── */
+
+/* HERO */
+.contact-hero {
+ padding: 6rem 1.5rem;
+ background: var(--brand-card);
+ text-align: center;
+}
+
+.contact-hero h1 {
+ font-family: var(--font-serif);
+ font-size: clamp(2.5rem, 6vw, 4rem);
+ color: var(--brand-purple);
+ margin-bottom: 1rem;
+}
+
+.contact-hero p {
+ font-family: var(--font-sans);
+ font-size: 1.05rem;
+ color: var(--brand-muted);
+ line-height: 1.8;
+ max-width: 640px;
+ margin: 0 auto 2rem;
+}
+
+/* CONTACT BODY */
+.contact-body {
+ padding: 5rem 1.5rem;
+ background: var(--brand-light-lavender);
+}
+
+.contact-grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 4rem;
+ max-width: 1100px;
+ margin: 0 auto;
+}
+
+@media (min-width: 1024px) {
+ .contact-grid { grid-template-columns: 1fr 1fr; }
+}
+
+/* INFO PANEL */
+.contact-info-panel {
+ display: flex;
+ flex-direction: column;
+ gap: 2.5rem;
+}
+
+.contact-info-panel h2 {
+ font-family: var(--font-serif);
+ font-size: 1.9rem;
+ color: var(--brand-purple);
+}
+
+.contact-info-list {
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+}
+
+.contact-info-item {
+ display: flex;
+ align-items: flex-start;
+ gap: 1rem;
+}
+
+.contact-info-icon {
+ width: 48px;
+ height: 48px;
+ border-radius: 50%;
+ background: rgba(220,198,242,0.5);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--brand-purple);
+ flex-shrink: 0;
+}
+
+.contact-info-label {
+ font-family: var(--font-display);
+ font-size: 0.65rem;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--brand-purple);
+ margin-bottom: 0.25rem;
+}
+
+.contact-info-value {
+ font-family: var(--font-sans);
+ color: var(--brand-muted);
+ font-size: 0.95rem;
+ line-height: 1.6;
+}
+
+.contact-info-value a {
+ color: var(--brand-muted);
+ text-decoration: none;
+ transition: color 0.3s ease;
+}
+
+.contact-info-value a:hover {
+ color: var(--brand-gold);
+}
+
+/* SOCIAL BOX */
+.contact-social-box {
+ padding: 2rem;
+ background: var(--brand-card);
+ border-radius: 0.75rem;
+ border: 1px solid var(--brand-border);
+}
+
+.contact-social-box h3 {
+ font-family: var(--font-serif);
+ font-size: 1.5rem;
+ color: var(--brand-purple);
+ margin-bottom: 0.5rem;
+}
+
+.contact-social-box p {
+ font-family: var(--font-sans);
+ color: var(--brand-muted);
+ margin-bottom: 1.25rem;
+ font-size: 0.9rem;
+ line-height: 1.6;
+}
+
+.contact-ig-link {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ color: var(--brand-purple);
+ font-family: var(--font-sans);
+ font-weight: 500;
+ text-decoration: none;
+ transition: color 0.3s ease;
+}
+
+.contact-ig-link:hover {
+ color: var(--brand-gold);
+}
+
+/* FORM PANEL */
+.contact-form-panel {
+ background: #ffffff;
+ border-radius: 0px;
+ padding: 3rem;
+ box-shadow: 0 12px 40px rgba(91,30,140,0.1);
+ border: 1px solid rgba(213,190,240,0.4);
+ position: relative;
+}
+
+.contact-form-top-bar {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 4px;
+ background: linear-gradient(to right, var(--brand-purple), var(--brand-gold), var(--brand-purple));
+ border-radius: 0;
+}
+
+.contact-form-panel h2 {
+ font-family: var(--font-serif);
+ font-size: 1.9rem;
+ color: var(--brand-purple);
+ margin-bottom: 2rem;
+}
+
+.form-row {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 1.25rem;
+ margin-bottom: 1.25rem;
+}
+
+@media (min-width: 640px) {
+ .form-row { grid-template-columns: 1fr 1fr; }
+}
+
+.form-field {
+ display: flex;
+ flex-direction: column;
+ gap: 0.4rem;
+ margin-bottom: 1.25rem;
+}
+
+.form-label {
+ font-family: var(--font-display);
+ font-size: 0.65rem;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--brand-purple);
+}
+
+.form-input,
+.form-textarea {
+ width: 100%;
+ padding: 0.85rem 1rem;
+ background: var(--brand-light-lavender);
+ border: 1px solid var(--brand-border);
+ font-family: var(--font-sans);
+ font-size: 0.95rem;
+ color: var(--brand-text);
+ outline: none;
+ transition: border-color 0.3s ease, box-shadow 0.3s ease;
+ border-radius: 0;
+ box-sizing: border-box;
+}
+
+.form-input:focus,
+.form-textarea:focus {
+ border-color: var(--brand-gold);
+ box-shadow: 0 0 0 2px rgba(212,162,76,0.15);
+}
+
+.form-textarea {
+ resize: none;
+ height: 140px;
+}
+
+.form-submit {
+ width: 100%;
+ padding: 1rem;
+ background: var(--brand-purple);
+ color: #ffffff;
+ font-family: var(--font-display);
+ font-size: 0.72rem;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ border: none;
+ cursor: pointer;
+ transition: background 0.3s ease;
+ margin-top: 0.5rem;
+}
+
+.form-submit:hover:not(:disabled) {
+ background: var(--brand-gold);
+}
+
+.form-submit:disabled {
+ opacity: 0.7;
+ cursor: not-allowed;
+}
+
+/* SUCCESS STATE */
+.contact-success {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ padding: 4rem 0;
+}
+
+.success-icon-wrap {
+ width: 64px;
+ height: 64px;
+ border-radius: 50%;
+ background: #f0fdf4;
+ color: #16a34a;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 1.5rem;
+}
+
+.contact-success h3 {
+ font-family: var(--font-serif);
+ font-size: 1.75rem;
+ color: var(--brand-purple);
+ margin-bottom: 0.5rem;
+}
+
+.contact-success p {
+ font-family: var(--font-sans);
+ color: var(--brand-muted);
+}
+
+.send-another-btn {
+ margin-top: 2rem;
+ background: none;
+ border: none;
+ border-bottom: 1px solid var(--brand-gold);
+ padding-bottom: 3px;
+ font-family: var(--font-display);
+ font-size: 0.72rem;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--brand-gold);
+ cursor: pointer;
+ transition: color 0.3s ease;
+}
+
+.send-another-btn:hover {
+ color: var(--brand-purple);
+ border-color: var(--brand-purple);
+}
+
+/* CLOSING QUOTE */
+.contact-quote {
+ padding: 4rem 1.5rem;
+ text-align: center;
+ background: var(--brand-light-lavender);
+}
+
+.contact-quote p {
+ font-family: var(--font-script);
+ font-size: clamp(1.5rem, 3vw, 2rem);
+ color: var(--brand-purple);
+ max-width: 640px;
+ margin: 0 auto;
+ line-height: 1.6;
+}
diff --git a/src/pages/home.css b/src/pages/home.css
new file mode 100644
index 0000000..e114088
--- /dev/null
+++ b/src/pages/home.css
@@ -0,0 +1,386 @@
+/* ─── home.css ───────────────────────────────────────────── */
+
+/* HERO */
+.home-hero {
+ position: relative;
+ min-height: 90vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ overflow: hidden;
+ padding: 5rem 1.5rem;
+ text-align: center;
+}
+
+.home-hero-bg {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(to bottom, rgba(220,198,242,0.4), var(--brand-light-lavender));
+ z-index: -1;
+}
+
+.home-hero-logo-wrap {
+ width: 140px;
+ height: 140px;
+ border-radius: 50%;
+ overflow: hidden;
+ border: 4px solid rgba(212,162,76,0.35);
+ box-shadow: 0 0 40px rgba(212,162,76,0.25);
+ position: relative;
+ margin: 0 auto 2rem;
+}
+
+.home-hero-flame {
+ position: absolute;
+ top: -12px;
+ right: -12px;
+ color: var(--brand-gold);
+}
+
+.home-hero h1 {
+ font-family: var(--font-serif);
+ font-size: clamp(2.5rem, 7vw, 5.5rem);
+ color: var(--brand-purple);
+ margin-bottom: 1rem;
+ drop-shadow: 0 2px 8px rgba(91,30,140,0.15);
+}
+
+.home-hero-tagline {
+ font-family: var(--font-script);
+ font-size: clamp(1.75rem, 4vw, 3rem);
+ color: var(--brand-gold);
+ margin-bottom: 3rem;
+ display: block;
+}
+
+.hero-cta {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 1rem 2.5rem;
+ background: var(--brand-purple);
+ color: #ffffff;
+ font-family: var(--font-display);
+ font-size: 0.78rem;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ text-decoration: none;
+ border: 1px solid transparent;
+ transition: background 0.4s ease, border-color 0.4s ease, color 0.4s ease, box-shadow 0.4s ease;
+}
+
+.hero-cta:hover {
+ background: transparent;
+ color: var(--brand-purple);
+ border-color: var(--brand-gold);
+ box-shadow: 0 0 20px rgba(212,162,76,0.35);
+}
+
+/* PHILOSOPHY */
+.home-philosophy {
+ padding: 6rem 1.5rem;
+ background: var(--brand-card);
+}
+
+.home-philosophy h2 {
+ font-family: var(--font-serif);
+ font-size: clamp(2rem, 4vw, 3rem);
+ color: var(--brand-purple);
+ text-align: center;
+ margin-bottom: 0.75rem;
+}
+
+.section-divider {
+ width: 96px;
+ height: 4px;
+ background: var(--brand-gold);
+ margin: 0 auto 4rem;
+ border-radius: 2px;
+}
+
+.philosophy-grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 2.5rem;
+ max-width: 1100px;
+ margin: 0 auto;
+}
+
+@media (min-width: 768px) {
+ .philosophy-grid { grid-template-columns: 1fr 1fr 1fr; }
+}
+
+.philosophy-card {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ padding: 2.5rem;
+ border-radius: 1rem;
+ transition: background 0.4s ease;
+}
+
+.philosophy-card:hover {
+ background: rgba(220,198,242,0.3);
+}
+
+.philosophy-icon-wrap {
+ width: 64px;
+ height: 64px;
+ border-radius: 50%;
+ background: rgba(220,198,242,0.5);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--brand-purple);
+ margin-bottom: 1.5rem;
+}
+
+.philosophy-card h3 {
+ font-family: var(--font-display);
+ font-size: 1.1rem;
+ letter-spacing: 0.1em;
+ color: var(--brand-purple);
+ margin-bottom: 0.75rem;
+}
+
+.philosophy-card p {
+ font-family: var(--font-sans);
+ color: var(--brand-muted);
+ line-height: 1.7;
+}
+
+/* FEATURED PRODUCTS */
+.home-products {
+ padding: 6rem 1.5rem;
+ background: var(--brand-light-lavender);
+}
+
+.home-products-header {
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+ margin-bottom: 4rem;
+}
+
+@media (min-width: 768px) {
+ .home-products-header {
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: flex-end;
+ }
+}
+
+.home-products h2 {
+ font-family: var(--font-serif);
+ font-size: clamp(2rem, 4vw, 3rem);
+ color: var(--brand-purple);
+ margin-bottom: 0.5rem;
+}
+
+.view-all-link {
+ font-family: var(--font-display);
+ font-size: 0.72rem;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--brand-gold);
+ text-decoration: none;
+ border-bottom: 1px solid transparent;
+ padding-bottom: 2px;
+ transition: color 0.3s ease, border-color 0.3s ease;
+ white-space: nowrap;
+}
+
+.view-all-link:hover {
+ color: var(--brand-purple);
+ border-color: var(--brand-purple);
+}
+
+.product-grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 2rem;
+ max-width: 1280px;
+ margin: 0 auto;
+}
+
+@media (min-width: 600px) { .product-grid { grid-template-columns: 1fr 1fr; } }
+@media (min-width: 1024px) { .product-grid { grid-template-columns: repeat(4, 1fr); } }
+
+.product-card {
+ cursor: pointer;
+}
+
+.product-img-wrap {
+ position: relative;
+ aspect-ratio: 1 / 1;
+ overflow: hidden;
+ background: var(--brand-card);
+ border-radius: 4px;
+ margin-bottom: 1.25rem;
+}
+
+.product-img-wrap img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 0.7s ease;
+}
+
+.product-card:hover .product-img-wrap img {
+ transform: scale(1.05);
+}
+
+.product-overlay {
+ position: absolute;
+ inset: 0;
+ background: rgba(91,30,140,0.22);
+ opacity: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ backdrop-filter: blur(2px);
+ transition: opacity 0.5s ease;
+}
+
+.product-card:hover .product-overlay {
+ opacity: 1;
+}
+
+.product-overlay-btn {
+ padding: 0.75rem 1.5rem;
+ background: rgba(239,228,250,0.92);
+ color: var(--brand-purple);
+ font-family: var(--font-display);
+ font-size: 0.72rem;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ border: none;
+ cursor: pointer;
+ transform: translateY(16px);
+ transition: transform 0.5s ease, background 0.3s ease;
+}
+
+.product-card:hover .product-overlay-btn {
+ transform: translateY(0);
+}
+
+.product-name {
+ font-family: var(--font-serif);
+ font-size: 1.4rem;
+ color: var(--brand-purple);
+ margin-bottom: 0.25rem;
+}
+
+.product-price {
+ font-family: var(--font-sans);
+ color: var(--brand-gold);
+ font-weight: 500;
+}
+
+/* QUOTE BANNER */
+.home-quote {
+ padding: 8rem 1.5rem;
+ background: var(--brand-purple);
+ position: relative;
+ overflow: hidden;
+ text-align: center;
+}
+
+.home-quote-texture {
+ position: absolute;
+ inset: 0;
+ background-image: url('https://www.transparenttextures.com/patterns/stardust.png');
+ opacity: 0.1;
+}
+
+.home-quote blockquote {
+ font-family: var(--font-serif);
+ font-style: italic;
+ font-size: clamp(1.4rem, 3.5vw, 2.5rem);
+ color: #ffffff;
+ line-height: 1.6;
+ max-width: 900px;
+ margin: 1.5rem auto 2rem;
+ position: relative;
+ z-index: 1;
+}
+
+.home-quote-divider {
+ width: 64px;
+ height: 1px;
+ background: var(--brand-gold);
+ margin: 0 auto;
+ position: relative;
+ z-index: 1;
+}
+
+/* NEWSLETTER */
+.home-newsletter {
+ padding: 6rem 1.5rem;
+ background: var(--brand-card);
+ text-align: center;
+}
+
+.home-newsletter h2 {
+ font-family: var(--font-serif);
+ font-size: clamp(1.8rem, 3.5vw, 2.5rem);
+ color: var(--brand-purple);
+ margin-bottom: 0.75rem;
+}
+
+.home-newsletter p {
+ font-family: var(--font-sans);
+ color: var(--brand-muted);
+ margin-bottom: 2rem;
+ max-width: 520px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.newsletter-form {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ max-width: 440px;
+ margin: 0 auto;
+}
+
+@media (min-width: 480px) {
+ .newsletter-form { flex-direction: row; }
+}
+
+.newsletter-input {
+ flex: 1;
+ padding: 0.85rem 1.25rem;
+ background: var(--brand-light-lavender);
+ border: 1px solid var(--brand-border);
+ font-family: var(--font-sans);
+ font-size: 0.95rem;
+ outline: none;
+ transition: border-color 0.3s ease;
+}
+
+.newsletter-input:focus {
+ border-color: var(--brand-gold);
+ box-shadow: 0 0 0 2px rgba(212,162,76,0.15);
+}
+
+.newsletter-btn {
+ padding: 0.85rem 2rem;
+ background: var(--brand-purple);
+ color: #ffffff;
+ font-family: var(--font-display);
+ font-size: 0.72rem;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ border: none;
+ cursor: pointer;
+ transition: background 0.3s ease;
+ white-space: nowrap;
+}
+
+.newsletter-btn:hover {
+ background: var(--brand-gold);
+}
diff --git a/src/pages/home.tsx b/src/pages/home.tsx
index cf5a3a5..eee0f25 100644
--- a/src/pages/home.tsx
+++ b/src/pages/home.tsx
@@ -1,154 +1,96 @@
import { motion } from "framer-motion";
import { Link } from "wouter";
import { Flame, Heart, Leaf, Sparkles } from "lucide-react";
+import Box from "@mui/material/Box";
+import Container from "@mui/material/Container";
import lavenderImage from "@/assets/images/product-lavender.png";
import roseImage from "@/assets/images/product-rose.png";
import eucalyptusImage from "@/assets/images/product-eucalyptus.png";
import oudImage from "@/assets/images/product-oud.png";
+import "./home.css";
const logoPath = "/opengraph.jpg";
+const fadeInUp = {
+ hidden: { opacity: 0, y: 40 },
+ visible: { opacity: 1, y: 0, transition: { duration: 0.8, ease: "easeOut" } },
+};
+
+const stagger = {
+ visible: { transition: { staggerChildren: 0.2 } },
+};
+
export default function Home() {
- const fadeInUp = {
- hidden: { opacity: 0, y: 40 },
- visible: { opacity: 1, y: 0, transition: { duration: 0.8, ease: "easeOut" } },
- };
-
- const stagger = {
- visible: { transition: { staggerChildren: 0.2 } },
- };
-
return (
-
- {/* Hero Section */}
-
-
-
-
-
-
-

+
+ {/* ── Hero ── */}
+
+
+
+
+
+
-
-
+
+
-
- Mani Candles Co.
-
+
Mani Candles Co.
-
+
Handmade • Natural • Heartmade
-
+
-
- Shop the Collection
-
+ Shop the Collection
- {/* Why Mani Section */}
-
-
-
-
- The Mani Philosophy
-
-
+ {/* ── Philosophy ── */}
+
+
+
+ The Mani Philosophy
+
-
-
-
-
-
- Natural
-
- Crafted with pure soy wax and essential oils. Clean burns that respect your home and our earth.
-
-
-
-
-
-
-
- Handmade
-
- Poured by hand in small batches to ensure unparalleled quality and attention to detail.
-
-
-
-
-
-
-
- Heartmade
-
- Every candle is infused with love and intention, designed to bring warmth to your sacred spaces.
-
-
+
+ {[
+ { Icon: Leaf, title: "Natural", desc: "Crafted with pure soy wax and essential oils. Clean burns that respect your home and our earth." },
+ { Icon: Sparkles, title: "Handmade", desc: "Poured by hand in small batches to ensure unparalleled quality and attention to detail." },
+ { Icon: Heart, title: "Heartmade", desc: "Every candle is infused with love and intention, designed to bring warmth to your sacred spaces." },
+ ].map(({ Icon, title, desc }, i) => (
+
+
+ {title}
+ {desc}
+
+ ))}
-
+
- {/* Featured Products */}
-
-
-
+ {/* ── Featured Products ── */}
+
+
+
-
Curated Favorites
-
+
Curated Favorites
+
-
- View All Candles
-
+ View All Candles
-
+
{[
{ id: 1, name: "Lavender Dream", image: lavenderImage, price: "$28" },
{ id: 2, name: "Rose & Vanilla", image: roseImage, price: "$32" },
@@ -157,82 +99,49 @@ export default function Home() {
].map((product, i) => (
-
-

-
-
- Quick Add
-
+
+

+
+
-
{product.name}
-
{product.price}
+
{product.name}
+
{product.price}
))}
-
+
- {/* Quote Section */}
-
-
-
-
-
+ {/* ── Quote ── */}
+
+
+
+
+
"A candle loses nothing by lighting another candle. It only makes the room warmer, brighter, and more beautiful."
-
-
+
+
- {/* Newsletter */}
-
+
);
}
diff --git a/src/pages/products.css b/src/pages/products.css
new file mode 100644
index 0000000..9568a5e
--- /dev/null
+++ b/src/pages/products.css
@@ -0,0 +1,173 @@
+/* ─── products.css ───────────────────────────────────────── */
+
+/* HERO */
+.products-hero {
+ padding: 6rem 1.5rem;
+ background: var(--brand-card);
+ text-align: center;
+}
+
+.products-hero h1 {
+ font-family: var(--font-serif);
+ font-size: clamp(2.5rem, 6vw, 4rem);
+ color: var(--brand-purple);
+ margin-bottom: 1rem;
+}
+
+.products-hero p {
+ font-family: var(--font-sans);
+ font-size: 1.05rem;
+ color: var(--brand-muted);
+ line-height: 1.8;
+ max-width: 640px;
+ margin: 0 auto 2rem;
+}
+
+/* FILTERS */
+.products-body {
+ padding: 5rem 1.5rem;
+ background: var(--brand-light-lavender);
+}
+
+.filter-bar {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 1rem;
+ margin-bottom: 4rem;
+}
+
+.filter-btn {
+ font-family: var(--font-display);
+ font-size: 0.72rem;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ padding: 0.5rem 1.5rem;
+ background: none;
+ border: none;
+ border-bottom: 2px solid transparent;
+ color: var(--brand-muted);
+ cursor: pointer;
+ transition: color 0.3s ease, border-color 0.3s ease;
+}
+
+.filter-btn:hover {
+ color: var(--brand-purple);
+}
+
+.filter-btn.active {
+ color: var(--brand-purple);
+ border-bottom-color: var(--brand-gold);
+}
+
+/* PRODUCT GRID */
+.products-grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 3rem 2rem;
+ max-width: 1280px;
+ margin: 0 auto;
+}
+
+@media (min-width: 640px) { .products-grid { grid-template-columns: 1fr 1fr; } }
+@media (min-width: 1024px) { .products-grid { grid-template-columns: repeat(4, 1fr); } }
+
+.prod-card {
+ display: flex;
+ flex-direction: column;
+ cursor: pointer;
+}
+
+.prod-img-wrap {
+ position: relative;
+ aspect-ratio: 4 / 5;
+ overflow: hidden;
+ background: var(--brand-card);
+ border: 1px solid var(--brand-border);
+ margin-bottom: 1.25rem;
+}
+
+.prod-img-wrap img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 1s ease;
+}
+
+.prod-card:hover .prod-img-wrap img {
+ transform: scale(1.05);
+}
+
+.prod-overlay {
+ position: absolute;
+ inset: 0;
+ background: rgba(91,30,140,0.3);
+ opacity: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ backdrop-filter: blur(2px);
+ transition: opacity 0.5s ease;
+}
+
+.prod-card:hover .prod-overlay {
+ opacity: 1;
+}
+
+.prod-overlay-btn {
+ padding: 0.75rem 2rem;
+ background: var(--brand-light-lavender);
+ color: var(--brand-purple);
+ font-family: var(--font-display);
+ font-size: 0.72rem;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ border: none;
+ cursor: pointer;
+ transform: translateY(32px);
+ transition: transform 0.5s ease, background 0.3s ease, color 0.3s ease;
+ box-shadow: 0 4px 16px rgba(0,0,0,0.15);
+}
+
+.prod-card:hover .prod-overlay-btn {
+ transform: translateY(0);
+}
+
+.prod-overlay-btn:hover {
+ background: var(--brand-gold);
+ color: #ffffff;
+}
+
+.prod-info {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+}
+
+.prod-name {
+ font-family: var(--font-serif);
+ font-size: 1.4rem;
+ color: var(--brand-purple);
+ margin-bottom: 0.25rem;
+}
+
+.prod-scent {
+ font-family: var(--font-sans);
+ font-size: 0.85rem;
+ color: var(--brand-muted);
+ line-height: 1.5;
+ margin-bottom: 0.75rem;
+ /* two-line clamp */
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.prod-price {
+ font-family: var(--font-sans);
+ font-weight: 500;
+ font-size: 1.05rem;
+ color: var(--brand-gold);
+}
diff --git a/src/theme.ts b/src/theme.ts
new file mode 100644
index 0000000..9a5438d
--- /dev/null
+++ b/src/theme.ts
@@ -0,0 +1,63 @@
+import { createTheme } from "@mui/material/styles";
+
+const theme = createTheme({
+ palette: {
+ mode: "light",
+ primary: {
+ main: "#5B1E8C", // deep brand purple
+ light: "#DCC6F2", // lavender
+ dark: "#3A1260",
+ contrastText: "#ffffff",
+ },
+ secondary: {
+ main: "#D4A24C", // brand gold / accent
+ light: "#FFD36B",
+ dark: "#A07830",
+ contrastText: "#ffffff",
+ },
+ background: {
+ default: "#EFE4FA", // light lavender bg
+ paper: "#F8F2FD", // card bg
+ },
+ text: {
+ primary: "#2D0D52",
+ secondary: "#7B5A9E",
+ },
+ divider: "#D5BEF0",
+ },
+ typography: {
+ fontFamily: "'Inter', sans-serif",
+ h1: { fontFamily: "'Cormorant Garamond', serif" },
+ h2: { fontFamily: "'Cormorant Garamond', serif" },
+ h3: { fontFamily: "'Cormorant Garamond', serif" },
+ h4: { fontFamily: "'Cormorant Garamond', serif" },
+ h5: { fontFamily: "'Cormorant Garamond', serif" },
+ h6: { fontFamily: "'Cormorant Garamond', serif" },
+ subtitle1: { fontFamily: "'Cinzel', serif" },
+ subtitle2: { fontFamily: "'Cinzel', serif" },
+ },
+ shape: {
+ borderRadius: 12,
+ },
+ components: {
+ MuiButton: {
+ styleOverrides: {
+ root: {
+ textTransform: "none",
+ borderRadius: 0,
+ fontFamily: "'Cinzel', serif",
+ letterSpacing: "0.15em",
+ },
+ },
+ },
+ MuiAppBar: {
+ styleOverrides: {
+ root: {
+ boxShadow: "none",
+ },
+ },
+ },
+ },
+});
+
+export default theme;
diff --git a/vite.config.ts b/vite.config.ts
index f03fa0d..5bdd3c5 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,13 +1,12 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
-import tailwindcss from "@tailwindcss/vite";
import path from "path";
import { fileURLToPath } from "url";
const projectRoot = fileURLToPath(new URL(".", import.meta.url));
export default defineConfig({
- plugins: [react(), tailwindcss()],
+ plugins: [react()],
resolve: {
alias: {
"@": path.resolve(projectRoot, "src"),