diff --git a/src/App.tsx b/src/App.tsx index a0ed1f7..92c3dcd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,4 @@ import { Switch, Route, Router as WouterRouter } from "wouter"; -import { Toaster } from "@/components/ui/toaster"; -import { TooltipProvider } from "@/components/ui/tooltip"; import NotFound from "@/pages/not-found"; import { Layout } from "@/components/Layout"; @@ -23,14 +21,11 @@ function Router() { function App() { return ( - - - - - - - - + + + + + ); } diff --git a/src/components/Layout.css b/src/components/Layout.css new file mode 100644 index 0000000..1612ad1 --- /dev/null +++ b/src/components/Layout.css @@ -0,0 +1,366 @@ +/* ─── Layout.css — Header & Footer ──────────────────────── */ + +/* ══════════════════════════════════════════════════════════ + MARQUEE / TICKER BAR +══════════════════════════════════════════════════════════ */ +.ticker-bar { + background: var(--brand-purple-dark); + border-bottom: 1px solid rgba(212,162,76,0.25); + height: 36px; + overflow: hidden; + display: flex; + align-items: center; +} + +.ticker-track { + display: flex; + align-items: center; + gap: 0; + animation: ticker-scroll 28s linear infinite; + white-space: nowrap; + will-change: transform; +} + +.ticker-track:hover { + animation-play-state: paused; +} + +@keyframes ticker-scroll { + 0% { transform: translateX(0); } + 100% { transform: translateX(-50%); } +} + +.ticker-item { + display: inline-flex; + align-items: center; + gap: 0.6rem; + font-family: var(--font-display); + font-size: 0.62rem; + letter-spacing: 0.2em; + text-transform: uppercase; + color: rgba(255,255,255,0.85); + padding: 0 2.5rem; +} + +.ticker-dot { + width: 5px; + height: 5px; + border-radius: 50%; + background: var(--brand-gold); + flex-shrink: 0; + display: inline-block; +} + +/* ══════════════════════════════════════════════════════════ + LOGO +══════════════════════════════════════════════════════════ */ +.logo-text { + font-family: var(--font-script); + font-size: 2rem; + color: #ffffff; + transition: color 0.3s ease; + line-height: 1; +} +.logo-text:hover { color: var(--brand-gold-light); } + +.logo-img-wrap { + width: 44px; + height: 44px; + border-radius: 50%; + overflow: hidden; + border: 2px solid transparent; + transition: border-color 0.3s ease; +} +.logo-img-wrap:hover { border-color: var(--brand-gold); } + +/* ══════════════════════════════════════════════════════════ + NAV ITEM WITH DROPDOWN +══════════════════════════════════════════════════════════ */ +.nav-item { + position: relative; +} + +.nav-link { + font-family: var(--font-display); + font-size: 0.72rem; + letter-spacing: 0.2em; + text-transform: uppercase; + color: #ffffff; + text-decoration: none; + padding-bottom: 2px; + border-bottom: 2px solid transparent; + transition: border-color 0.3s ease, color 0.3s ease; + display: inline-flex; + align-items: center; + gap: 5px; + cursor: pointer; + background: none; + border-left: none; + border-right: none; + border-top: none; +} + +.nav-link:hover { + color: var(--brand-gold-light); + border-bottom-color: rgba(212,162,76,0.6); +} + +.nav-link.active { + color: var(--brand-gold-light); + border-bottom-color: var(--brand-gold); + border-bottom-width: 2.5px; + text-shadow: + 0 0 12px rgba(255,211,107,0.9), + 0 0 24px rgba(212,162,76,0.5); + font-weight: 600; + background: rgba(212,162,76,0.12); + border-radius: 4px; + padding: 3px 10px 5px; +} + +.nav-chevron { + transition: transform 0.25s ease; + opacity: 0.75; +} + +.nav-item:hover .nav-chevron { + transform: rotate(180deg); + opacity: 1; +} + +/* DROPDOWN PANEL */ +.nav-dropdown { + position: absolute; + top: calc(100% + 18px); + left: 50%; + transform: translateX(-50%) translateY(-8px); + min-width: 200px; + background: rgba(45, 13, 82, 0.96); + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + border: 1px solid rgba(212,162,76,0.2); + border-radius: 8px; + padding: 0.6rem 0; + opacity: 0; + pointer-events: none; + transition: opacity 0.2s ease, transform 0.25s ease; + box-shadow: 0 16px 40px rgba(0,0,0,0.35); + z-index: 200; +} + +/* Arrow notch */ +.nav-dropdown::before { + content: ''; + position: absolute; + top: -7px; + left: 50%; + transform: translateX(-50%); + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid rgba(212,162,76,0.25); +} + +.nav-dropdown::after { + content: ''; + position: absolute; + top: -6px; + left: 50%; + transform: translateX(-50%); + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid rgba(45,13,82,0.96); +} + +.nav-item:hover .nav-dropdown { + opacity: 1; + pointer-events: auto; + transform: translateX(-50%) translateY(0); +} + +.dropdown-item { + display: flex; + align-items: center; + gap: 0.6rem; + padding: 0.65rem 1.25rem; + font-family: var(--font-sans); + font-size: 0.83rem; + color: rgba(255,255,255,0.78); + text-decoration: none; + transition: background 0.2s ease, color 0.2s ease, padding-left 0.2s ease; + white-space: nowrap; +} + +.dropdown-item:hover { + background: rgba(212,162,76,0.12); + color: var(--brand-gold-light); + padding-left: 1.6rem; +} + +.dropdown-divider { + height: 1px; + background: rgba(255,255,255,0.08); + margin: 0.4rem 0; +} + +/* ══════════════════════════════════════════════════════════ + MOBILE TOGGLE +══════════════════════════════════════════════════════════ */ +.mobile-toggle { + background: none; + border: none; + color: #ffffff; + cursor: pointer; + display: flex; + align-items: center; + padding: 4px; + transition: color 0.3s ease; +} +.mobile-toggle:hover { color: var(--brand-gold-light); } + +/* ══════════════════════════════════════════════════════════ + MOBILE DRAWER +══════════════════════════════════════════════════════════ */ +.mobile-menu { + background: rgba(45, 13, 82, 0.97); + backdrop-filter: blur(16px); + border-bottom: 1px solid rgba(212, 162, 76, 0.2); + padding: 1.5rem; + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.mobile-nav-section { + display: flex; + flex-direction: column; +} + +.mobile-nav-link { + font-family: var(--font-display); + font-size: 0.85rem; + letter-spacing: 0.2em; + text-transform: uppercase; + color: #ffffff; + text-decoration: none; + padding: 0.8rem 0.5rem; + border-bottom: 1px solid rgba(255,255,255,0.07); + transition: color 0.3s ease, padding-left 0.2s ease; + display: block; +} + +.mobile-nav-link:hover { + color: var(--brand-gold-light); + padding-left: 0.75rem; +} + +.mobile-nav-link.active { + color: var(--brand-gold); + padding-left: 0.75rem; + text-shadow: 0 0 10px rgba(255,211,107,0.7); + font-weight: 600; +} + +.mobile-dropdown-items { + display: flex; + flex-direction: column; + padding: 0.25rem 0 0.5rem 1rem; + gap: 0.1rem; + border-bottom: 1px solid rgba(255,255,255,0.07); +} + +.mobile-dropdown-item { + font-family: var(--font-sans); + font-size: 0.82rem; + color: rgba(255,255,255,0.6); + text-decoration: none; + padding: 0.4rem 0.5rem; + transition: color 0.2s ease; +} + +.mobile-dropdown-item:hover { + color: var(--brand-gold-light); +} + +/* ══════════════════════════════════════════════════════════ + FOOTER +══════════════════════════════════════════════════════════ */ +.site-footer { + background: var(--brand-purple-dark); + color: #ffffff; + padding: 4rem 1.5rem; + margin-top: 5rem; +} + +.footer-inner { + max-width: 1280px; + margin: 0 auto; + display: grid; + grid-template-columns: 1fr; + gap: 3rem; + text-align: center; +} + +@media (min-width: 768px) { + .footer-inner { + grid-template-columns: 1fr 1fr 1fr; + text-align: left; + } +} + +.footer-col { + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; +} + +@media (min-width: 768px) { + .footer-col { align-items: flex-start; } +} + +.footer-tagline { + font-family: var(--font-serif); + font-style: italic; + font-size: 1.1rem; + color: rgba(255,255,255,0.7); +} + +.footer-heading { + font-family: var(--font-display); + font-size: 0.7rem; + letter-spacing: 0.25em; + text-transform: uppercase; + color: var(--brand-gold); + margin-bottom: 0.5rem; +} + +.footer-link { + color: rgba(255,255,255,0.75); + font-size: 0.9rem; + text-decoration: none; + transition: color 0.3s ease; +} +.footer-link:hover { color: var(--brand-gold-light); } + +.social-btn { + width: 40px; + height: 40px; + border-radius: 50%; + background: rgba(255,255,255,0.08); + display: flex; + align-items: center; + justify-content: center; + color: #ffffff; + text-decoration: none; + transition: background 0.3s ease, color 0.3s ease; +} +.social-btn:hover { + background: var(--brand-gold); + color: var(--brand-purple-dark); +} + +.footer-copy { + font-size: 0.78rem; + color: rgba(255,255,255,0.4); + margin-top: 1rem; +} diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 096e53f..6ff6fca 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -1,19 +1,71 @@ import { Link, useLocation } from "wouter"; import { useState, useEffect } from "react"; import { motion, AnimatePresence } from "framer-motion"; -import { Menu, X, Instagram, Facebook, Twitter } from "lucide-react"; +import AppBar from "@mui/material/AppBar"; +import Toolbar from "@mui/material/Toolbar"; +import Box from "@mui/material/Box"; +import Container from "@mui/material/Container"; +import IconButton from "@mui/material/IconButton"; +import { Menu, X, Instagram, Facebook, Twitter, ChevronDown, Flame, Sparkles, Star } from "lucide-react"; +import { ScrollCandle } from "./ScrollCandle"; +import "./Layout.css"; const logoPath = "/opengraph.jpg"; +// ── Ticker messages ────────────────────────────────────── +const TICKER_ITEMS = [ + { icon: , text: "Free shipping on orders over $50" }, + { icon: , text: "New Collection — Summer Solstice" }, + { icon: , text: "Handpoured in small batches" }, + { icon: , text: "100% Natural Soy Wax" }, + { icon: , text: "Phthalate-free fragrance oils" }, + { icon: , text: "Gift wrapping available at checkout" }, +]; + +// ── Nav structure with dropdowns ───────────────────────── +const NAV_LINKS = [ + { name: "Home", path: "/", dropdown: null }, + { + name: "Products", + path: "/products", + dropdown: [ + { label: "All Collections", path: "/products" }, + null, // divider + { label: "Floral Scents", path: "/products" }, + { label: "Fresh Scents", path: "/products" }, + { label: "Woody Scents", path: "/products" }, + { label: "Sweet Scents", path: "/products" }, + ], + }, + { + name: "About", + path: "/about", + dropdown: [ + { label: "Our Story", path: "/about" }, + { label: "Our Process", path: "/about" }, + { label: "Meet the Maker", path: "/about" }, + ], + }, + { + name: "Contact", + path: "/contact", + dropdown: [ + { label: "Send a Message", path: "/contact" }, + { label: "Wholesale Inquiries", path: "/contact" }, + null, + { label: "Follow on Instagram", path: "/contact" }, + ], + }, +]; + export function Layout({ children }: { children: React.ReactNode }) { const [location] = useLocation(); const [scrolled, setScrolled] = useState(false); const [mobileMenuOpen, setMobileMenuOpen] = useState(false); + const [mobileOpenSection, setMobileOpenSection] = useState(null); useEffect(() => { - const handleScroll = () => { - setScrolled(window.scrollY > 20); - }; + const handleScroll = () => setScrolled(window.scrollY > 20); window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }, []); @@ -21,83 +73,181 @@ export function Layout({ children }: { children: React.ReactNode }) { useEffect(() => { window.scrollTo(0, 0); setMobileMenuOpen(false); + setMobileOpenSection(null); }, [location]); - const navLinks = [ - { name: "Home", path: "/" }, - { name: "Products", path: "/products" }, - { name: "About", path: "/about" }, - { name: "Contact", path: "/contact" }, - ]; + // Duplicate ticker items to create seamless loop + const allTickerItems = [...TICKER_ITEMS, ...TICKER_ITEMS]; return ( -
-
+ + {/* ── Ticker Bar ── */} + -
- -
- Mani Candles Co. Logo -
- - Mani Candles +
+ {allTickerItems.map((item, i) => ( + + + {item.icon} + {item.text} - - - - - + ))}
+ + {/* ── Main AppBar ── */} + + + + {/* Logo */} + +
+ Mani Candles Co. Logo +
+ Mani Candles + + + {/* Desktop Nav */} + + {NAV_LINKS.map((link) => ( +
+ + {link.name} + {link.dropdown && } + + + {/* Dropdown */} + {link.dropdown && ( +
+ {link.dropdown.map((item, idx) => + item === null ? ( +
+ ) : ( + + {item.label} + + ) + )} +
+ )} +
+ ))} + + + {/* Mobile Toggle */} + setMobileMenuOpen(!mobileMenuOpen)} + > + {mobileMenuOpen ? : } + + + + + {/* Mobile Drawer */} {mobileMenuOpen && ( -
- {navLinks.map((link) => ( - - {link.name} - - ))} -
+ {NAV_LINKS.map((link) => ( +
+ {link.dropdown ? ( + <> + + + {mobileOpenSection === link.name && ( + + {link.dropdown.map((item, i) => + item === null ? ( +
+ ) : ( + + {item.label} + + ) + )} + + )} + + + ) : ( + + {link.name} + + )} +
+ ))}
)}
-
+ -
+ {/* ── Page Content — offset for ticker + appbar ── */} + -
+ -