feat: Implement responsive navigation system with mobile hamburger menu
- Add mobile-first navigation with hamburger menu and top-right controls - Implement accordion-style mobile menu matching sidebar structure - Add theme toggle and accessibility buttons to mobile header - Update responsive breakpoints to lg: (1024px) for better tablet/desktop split - Hide sidebar on mobile, show primary nav on desktop - Update content padding to use proportional CHORUS spacing system - Fix logo centering in 3D canvas with proper origin calculations - Lighten header and bottom dock transparency to 80% - Add route-aware navigation state management - Include visual aid modal accessible from mobile menu 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -35,9 +35,9 @@ export default function RootLayout({
|
||||
<html lang="en" className="dark h-full">
|
||||
<body className={`${interTight.variable} ${inconsolata.variable} ${exo.variable} h-full bg-white text-carbon-950 antialiased dark:bg-carbon-950 dark:text-white`}>
|
||||
<Sidebar />
|
||||
<div className="md:pl-64">
|
||||
<div className="lg:pl-64">
|
||||
<Header />
|
||||
<main className="pt-20 md:pt-24 dark:bg-mulberry-950 light:bg-white min-h-screen pb-16 md:pb-0">
|
||||
<main className="pt-chorus-xl md:pt-chorus-xxl dark:bg-mulberry-950 light:bg-white min-h-screen pb-16 md:pb-0">
|
||||
{children}
|
||||
</main>
|
||||
<Footer />
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function BottomDock() {
|
||||
return (
|
||||
<>
|
||||
{/* Bottom Dock */}
|
||||
<div className="fixed inset-x-0 bottom-0 z-40 hidden items-center justify-between gap-chorus-md border-t border-nickel-200 bg-white/90 p-chorus-md backdrop-blur md:flex dark:border-mulberry-800 dark:bg-mulberry-950/90">
|
||||
<div className="fixed inset-x-0 bottom-0 z-40 hidden items-center justify-between gap-chorus-md border-t border-nickel-200 bg-white/80 p-chorus-md backdrop-blur md:flex dark:border-mulberry-800 dark:bg-mulberry-950/80">
|
||||
<div className="flex items-center gap-chorus-sm">
|
||||
{/* Theme Toggle */}
|
||||
<button
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
interface BreadcrumbItem {
|
||||
label: string;
|
||||
href: string;
|
||||
current?: boolean;
|
||||
}
|
||||
|
||||
const Breadcrumb = () => {
|
||||
const pathname = usePathname();
|
||||
|
||||
// Define route mappings for better labels
|
||||
const routeLabels: Record<string, string> = {
|
||||
'/': 'Brand Overview',
|
||||
'/identity': 'Brand Identity',
|
||||
'/usage': 'Usage Guidelines',
|
||||
'/visual-identity': 'Visual Identity',
|
||||
'/logo': 'Logo System',
|
||||
'/typography': 'Typography',
|
||||
'/colors': 'Color Palette',
|
||||
'/iconography': 'Iconography',
|
||||
'/accessibility': 'Accessibility',
|
||||
'/components': 'Components',
|
||||
'/motion': 'Motion System',
|
||||
'/implementation': 'Implementation',
|
||||
'/culture': 'Culture',
|
||||
'/communications': 'Language Support',
|
||||
'/public-relations': 'Public Relations',
|
||||
'/investor-relations': 'Investor Relations',
|
||||
'/collaborators': 'Collaborators',
|
||||
'/social-media': 'Social Media',
|
||||
};
|
||||
|
||||
// Define category mappings for grouping
|
||||
const categoryMappings: Record<string, string> = {
|
||||
'/': 'Overview',
|
||||
'/identity': 'Overview',
|
||||
'/usage': 'Overview',
|
||||
'/visual-identity': 'Visual Identity',
|
||||
'/logo': 'Visual Identity',
|
||||
'/typography': 'Visual Identity',
|
||||
'/colors': 'Visual Identity',
|
||||
'/iconography': 'Visual Identity',
|
||||
'/accessibility': 'Visual Identity',
|
||||
'/components': 'Visual Identity',
|
||||
'/motion': 'Visual Identity',
|
||||
'/implementation': 'Visual Identity',
|
||||
'/culture': 'Communications',
|
||||
'/communications': 'Communications',
|
||||
'/public-relations': 'Communications',
|
||||
'/investor-relations': 'Communications',
|
||||
'/collaborators': 'Communications',
|
||||
'/social-media': 'Communications',
|
||||
};
|
||||
|
||||
const generateBreadcrumbs = (): BreadcrumbItem[] => {
|
||||
const breadcrumbs: BreadcrumbItem[] = [];
|
||||
|
||||
// Always start with Home
|
||||
breadcrumbs.push({
|
||||
label: 'Brand Guide',
|
||||
href: '/',
|
||||
current: pathname === '/',
|
||||
});
|
||||
|
||||
// If we're not on home page, add the current page
|
||||
if (pathname !== '/') {
|
||||
const category = categoryMappings[pathname];
|
||||
const pageLabel = routeLabels[pathname] ||
|
||||
pathname.replace('/', '').split('-').map(word =>
|
||||
word.charAt(0).toUpperCase() + word.slice(1)
|
||||
).join(' ');
|
||||
|
||||
// Add category if it's different from current page and not "Overview"
|
||||
if (category && category !== pageLabel && category !== 'Overview') {
|
||||
breadcrumbs.push({
|
||||
label: category,
|
||||
href: '#', // Categories are not directly navigable
|
||||
});
|
||||
}
|
||||
|
||||
// Add current page
|
||||
breadcrumbs.push({
|
||||
label: pageLabel,
|
||||
href: pathname,
|
||||
current: true,
|
||||
});
|
||||
}
|
||||
|
||||
return breadcrumbs;
|
||||
};
|
||||
|
||||
const breadcrumbs = generateBreadcrumbs();
|
||||
|
||||
return (
|
||||
<nav className="flex items-center px-chorus-sm secondary-nav breadcrumbs" aria-label="Breadcrumb">
|
||||
<ol className="flex items-center space-x-chorus-xs">
|
||||
{breadcrumbs.map((item, index) => (
|
||||
<li key={`${item.href}-${index}`} className="flex items-center">
|
||||
{index > 0 && (
|
||||
<svg
|
||||
className="text-carbon-500 dark:text-mulberry-400 mr-chorus-xs w-4 h-4"
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path fillRule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clipRule="evenodd" />
|
||||
</svg>
|
||||
)}
|
||||
{item.current ? (
|
||||
<span
|
||||
className="text-carbon-800 dark:text-mulberry-200 font-medium text-sm"
|
||||
aria-current="page"
|
||||
>
|
||||
{item.label}
|
||||
</span>
|
||||
) : item.href === '#' ? (
|
||||
<span className="text-carbon-600 dark:text-mulberry-300 text-sm">
|
||||
{item.label}
|
||||
</span>
|
||||
) : (
|
||||
<Link
|
||||
href={item.href}
|
||||
className="text-carbon-600 hover:text-mulberry-950 dark:text-mulberry-300 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1 text-sm underline-offset-4 hover:underline"
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
export default Breadcrumb;
|
||||
@@ -1,66 +1,472 @@
|
||||
|
||||
import React from 'react';
|
||||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import ThreeLogo from './ThreeLogo';
|
||||
import Breadcrumb from './Breadcrumb';
|
||||
|
||||
// Mobile accordion menu component
|
||||
interface MobileAccordionMenuProps {
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
const MobileAccordionMenu = ({ onClose }: MobileAccordionMenuProps) => {
|
||||
const pathname = usePathname();
|
||||
const [expandedSections, setExpandedSections] = useState<string[]>(['overview']);
|
||||
|
||||
// Same navigation structure as Sidebar
|
||||
const navCategories = [
|
||||
{
|
||||
id: 'overview',
|
||||
label: 'Overview',
|
||||
icon: 'Navigation/House_01',
|
||||
items: [
|
||||
{ href: '/', section: 'overview', icon: 'Navigation/House_01', label: 'Brand Overview' },
|
||||
{ href: '/identity', section: 'identity', icon: 'User/User_01', label: 'Brand Identity' },
|
||||
{ href: '/usage', section: 'usage', icon: 'Interface/Book', label: 'Usage Guidelines' },
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'visual-identity',
|
||||
label: 'Visual Identity',
|
||||
icon: 'Interface/Main_Component',
|
||||
items: [
|
||||
{ href: '/visual-identity', section: 'visual-identity', icon: 'Interface/Main_Component', label: 'Visual Identity' },
|
||||
{ href: '/logo', section: 'logo', icon: 'Interface/Star', label: 'Logo System' },
|
||||
{ href: '/typography', section: 'typography', icon: 'Edit/Text', label: 'Typography' },
|
||||
{ href: '/colors', section: 'colors', icon: 'Edit/Swatches_Palette', label: 'Color Palette' },
|
||||
{ href: '/iconography', section: 'iconography', icon: 'Interface/Main_Component', label: 'Iconography' },
|
||||
{ href: '/accessibility', section: 'accessibility', icon: 'Interface/Heart_01', label: 'Accessibility' },
|
||||
{ href: '/components', section: 'components', icon: 'Interface/Settings', label: 'Components' },
|
||||
{ href: '/motion', section: 'motion', icon: 'Interface/Link', label: 'Motion System' },
|
||||
{ href: '/implementation', section: 'implementation', icon: 'File/File_Code', label: 'Implementation' },
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'communications',
|
||||
label: 'Communications',
|
||||
icon: 'Communication/Chat',
|
||||
items: [
|
||||
{ href: '/culture', section: 'culture', icon: 'Environment/Bulb', label: 'Culture' },
|
||||
{ href: '/communications', section: 'communications', icon: 'Communication/Chat', label: 'Language Support' },
|
||||
{ href: '/public-relations', section: 'public-relations', icon: 'Communication/Paper_Plane', label: 'Public Relations' },
|
||||
{ href: '/investor-relations', section: 'investor-relations', icon: 'Interface/Chart_Line', label: 'Investor Relations' },
|
||||
{ href: '/collaborators', section: 'collaborators', icon: 'User/Users_Group', label: 'Collaborators' },
|
||||
{ href: '/social-media', section: 'social-media', icon: 'Communication/Share_iOS_Export', label: 'Social Media' },
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const toggleSection = (sectionId: string) => {
|
||||
setExpandedSections(prev =>
|
||||
prev.includes(sectionId)
|
||||
? prev.filter(id => id !== sectionId)
|
||||
: [sectionId]
|
||||
);
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
const currentCategory = navCategories.find(category =>
|
||||
category.items.some(item => item.href === pathname)
|
||||
);
|
||||
|
||||
if (currentCategory) {
|
||||
setExpandedSections([currentCategory.id]);
|
||||
}
|
||||
}, [pathname]);
|
||||
|
||||
const isCurrentPage = (href: string) => pathname === href;
|
||||
const isCategoryActive = (category: any) =>
|
||||
category.items.some((item: any) => item.href === pathname);
|
||||
|
||||
return (
|
||||
<nav className="p-chorus-md space-y-chorus-xs max-h-96 overflow-y-auto">
|
||||
{navCategories.map((category) => {
|
||||
const isExpanded = expandedSections.includes(category.id);
|
||||
const isActive = isCategoryActive(category);
|
||||
|
||||
return (
|
||||
<div key={category.id} className="space-y-chorus-xs">
|
||||
<button
|
||||
onClick={() => toggleSection(category.id)}
|
||||
className={`w-full group flex items-center justify-between gap-2 px-chorus-sm py-chorus-xs text-left transition-all duration-300 ease-out hover:bg-sand-50 hover:bg-opacity-30 hover:text-mulberry-950 dark:hover:bg-mulberry-900 dark:hover:bg-opacity-40 dark:hover:text-white ${
|
||||
isActive
|
||||
? 'bg-sand-100 text-mulberry-950 dark:bg-mulberry-800 dark:text-white font-medium'
|
||||
: 'text-carbon-700 dark:text-mulberry-300'
|
||||
}`}
|
||||
aria-expanded={isExpanded}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<img
|
||||
src={`/icons/coolicons.v4.1/coolicons PNG/Black/${category.icon}.png`}
|
||||
alt=""
|
||||
className="h-4 w-4 dark:hidden"
|
||||
/>
|
||||
<img
|
||||
src={`/icons/coolicons.v4.1/coolicons PNG/White/${category.icon}.png`}
|
||||
alt=""
|
||||
className="hidden h-4 w-4 dark:block"
|
||||
/>
|
||||
<span className="font-semibold">{category.label}</span>
|
||||
</div>
|
||||
|
||||
<svg
|
||||
className={`w-4 h-4 transition-transform duration-300 ${isExpanded ? 'rotate-90' : ''}`}
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path fillRule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clipRule="evenodd" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{isExpanded && (
|
||||
<div className="space-y-1 ml-6">
|
||||
{category.items.map((item) => (
|
||||
<Link
|
||||
key={item.section}
|
||||
href={item.href}
|
||||
onClick={onClose}
|
||||
className={`flex items-center gap-2 px-chorus-sm py-chorus-xs transition-all duration-300 ease-out hover:bg-sand-50 hover:bg-opacity-30 hover:text-mulberry-950 dark:hover:bg-mulberry-900 dark:hover:bg-opacity-40 dark:hover:text-white ${
|
||||
isCurrentPage(item.href)
|
||||
? 'bg-sand-50 text-mulberry-950 dark:bg-mulberry-900 dark:text-white font-medium border-l-2 border-mulberry-600 dark:border-mulberry-400'
|
||||
: 'text-carbon-600 dark:text-mulberry-400'
|
||||
}`}
|
||||
>
|
||||
<img
|
||||
src={`/icons/coolicons.v4.1/coolicons PNG/Black/${item.icon}.png`}
|
||||
alt=""
|
||||
className="h-3 w-3 dark:hidden"
|
||||
/>
|
||||
<img
|
||||
src={`/icons/coolicons.v4.1/coolicons PNG/White/${item.icon}.png`}
|
||||
alt=""
|
||||
className="hidden h-3 w-3 dark:block"
|
||||
/>
|
||||
<span className="text-sm">{item.label}</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
const Header = () => {
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
const [showVisualAid, setShowVisualAid] = useState(false);
|
||||
const [theme, setTheme] = useState<'light' | 'dark'>('dark');
|
||||
|
||||
// Theme toggle functionality
|
||||
React.useEffect(() => {
|
||||
const isDark = document.documentElement.classList.contains('dark');
|
||||
setTheme(isDark ? 'dark' : 'light');
|
||||
}, []);
|
||||
|
||||
const toggleTheme = () => {
|
||||
const newTheme = theme === 'dark' ? 'light' : 'dark';
|
||||
setTheme(newTheme);
|
||||
|
||||
if (newTheme === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
};
|
||||
return (
|
||||
<header className="fixed top-0 left-0 right-0 z-30 border-b border-nickel-200 bg-white/95 backdrop-blur dark:border-mulberry-800 dark:bg-mulberry-950/95 shadow-lg md:left-64">
|
||||
<div className="flex items-center">
|
||||
<header className="fixed top-0 left-0 right-0 z-30 bg-white/80 backdrop-blur dark:bg-mulberry-950/80 lg:left-64">
|
||||
<div className="flex items-center justify-between border-b dark:border-mulberry-800 border-nickel-200 shadow-lg">
|
||||
{/* Mobile layout - hamburger + logo on left, controls on right */}
|
||||
<div className="flex items-center justify-between w-full lg:hidden px-chorus-md py-chorus-sm">
|
||||
<div className="flex items-center gap-chorus-sm">
|
||||
<div className="flex items-center gap-chorus-sm px-chorus-sm py-chorus-sm">
|
||||
<ThreeLogo width={64} height={64} />
|
||||
<div>
|
||||
<div className="font-thin font-logo">CHORUS</div>
|
||||
<button
|
||||
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||
className="p-chorus-xs hover:bg-sand-100 dark:hover:bg-mulberry-800 transition-colors"
|
||||
aria-label="Toggle mobile menu"
|
||||
>
|
||||
<svg
|
||||
className="w-6 h-6 text-carbon-700 dark:text-mulberry-300"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d={mobileMenuOpen ? "M6 18L18 6M6 6l12 12" : "M4 6h16M4 12h16M4 18h16"}
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<div className="flex items-center gap-chorus-xs">
|
||||
<ThreeLogo width={32} height={32} />
|
||||
<span className="font-logo text-lg">CHORUS</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<ul className="primary-nav horizontal-menu md:flex items-center">
|
||||
<li className="menu-item">
|
||||
<div className="menu-item">Overview</div>
|
||||
{/* Mobile controls - theme toggle and visual aid */}
|
||||
<div className="flex items-center gap-chorus-xs">
|
||||
<button
|
||||
onClick={toggleTheme}
|
||||
className="p-chorus-xs hover:bg-sand-100 dark:hover:bg-mulberry-800 transition-colors"
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
<img
|
||||
src="/icons/coolicons.v4.1/coolicons PNG/Black/Environment/Moon.png"
|
||||
alt="Switch to Dark Mode"
|
||||
className="w-5 h-5 dark:hidden"
|
||||
/>
|
||||
<img
|
||||
src="/icons/coolicons.v4.1/coolicons PNG/White/Environment/Sun.png"
|
||||
alt="Switch to Light Mode"
|
||||
className="w-5 h-5 hidden dark:block"
|
||||
/>
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={() => setShowVisualAid(true)}
|
||||
className="p-chorus-xs hover:bg-sand-100 dark:hover:bg-mulberry-800 transition-colors"
|
||||
aria-label="Visual aid settings"
|
||||
>
|
||||
<svg className="h-5 w-5 text-carbon-700 dark:text-mulberry-300" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
|
||||
<path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z"/>
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Desktop primary navigation - hidden on mobile */}
|
||||
<nav className="primary-nav hidden lg:block">
|
||||
<ul className="horizontal-menu">
|
||||
<li className="dark:hover:bg-mulberry-700 hover:bg-sand-300">
|
||||
<div className="flex items-center gap-2 ml-chorus-sm">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Navigation/House_01.png" alt="" className="h-4 w-4 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Navigation/House_01.png" alt="" className="hidden h-4 w-4 dark:block" />
|
||||
<span>Overview</span>
|
||||
</div>
|
||||
<ul className="flyout-menu">
|
||||
<li className="menu-item"><Link href="/" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Brand Overview</Link></li>
|
||||
<li className="menu-item"><Link href="/identity" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Brand Identity</Link></li>
|
||||
<li className="menu-item"><Link href="/usage" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Usage Guidelines</Link></li>
|
||||
<li className="item">
|
||||
<Link href="/" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Navigation/House_01.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Navigation/House_01.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Brand Overview
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/identity" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/User/User_01.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/User/User_01.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Brand Identity
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/usage" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Interface/Book.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Interface/Book.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Usage Guidelines
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li className="menu-item">
|
||||
<div className="menu-item">Visual Identity</div>
|
||||
<li className="dark:hover:bg-mulberry-700 hover:bg-sand-300">
|
||||
<div className="flex items-center gap-2 ml-chorus-sm">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Interface/Main_Component.png" alt="" className="h-4 w-4 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Interface/Main_Component.png" alt="" className="hidden h-4 w-4 dark:block" />
|
||||
<span>Visual Identity</span>
|
||||
|
||||
</div>
|
||||
<ul className="flyout-menu">
|
||||
<li className="menu-item"><Link href="/visual-identity" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Visual Identity</Link></li>
|
||||
<li className="menu-item"><Link href="/logo" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Logo System</Link></li>
|
||||
<li className="menu-item"><Link href="/typography" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Typography</Link></li>
|
||||
<li className="menu-item"><Link href="/colors" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Color Palette</Link></li>
|
||||
<li className="menu-item"><Link href="/iconography" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Iconography</Link></li>
|
||||
<li className="menu-item"><Link href="/accessibility" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Accessibility</Link></li>
|
||||
<li className="menu-item"><Link href="/components" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Components</Link></li>
|
||||
<li className="menu-item"><Link href="/motion" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Motion System</Link></li>
|
||||
<li className="menu-item"><Link href="/implementation" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Implementation</Link></li>
|
||||
<li className="">
|
||||
<Link href="/visual-identity" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Interface/Main_Component.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Interface/Main_Component.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Visual Identity
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/logo" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Interface/Star.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Interface/Star.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Logo System
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/typography" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Edit/Text.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Edit/Text.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Typography
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/colors" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Edit/Swatches_Palette.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Edit/Swatches_Palette.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Color Palette
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/iconography" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Interface/Main_Component.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Interface/Main_Component.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Iconography
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/accessibility" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Interface/Heart_01.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Interface/Heart_01.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Accessibility
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/components" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Interface/Settings.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Interface/Settings.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Components
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/motion" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Interface/Link.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Interface/Link.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Motion System
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/implementation" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/File/File_Code.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/File/File_Code.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Implementation
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li className="menu-item">
|
||||
<div className="menu-item">Communications</div>
|
||||
<li className="dark:hover:bg-mulberry-700 hover:bg-sand-300">
|
||||
<div className="flex items-center gap-2 ml-chorus-sm">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Communication/Chat.png" alt="" className="h-4 w-4 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Communication/Chat.png" alt="" className="hidden h-4 w-4 dark:block" />
|
||||
<span>Communications</span>
|
||||
|
||||
</div>
|
||||
<ul className="flyout-menu">
|
||||
<li className="menu-item"><Link href="/culture" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Culture</Link></li>
|
||||
<li className="menu-item"><Link href="/communications" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Language Support</Link></li>
|
||||
<li className="menu-item"><Link href="/public-relations" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Public Relations</Link></li>
|
||||
<li className="menu-item"><Link href="/investor-relations" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Investor Relations</Link></li>
|
||||
<li className="menu-item"><Link href="/collaborators" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Collaborators</Link></li>
|
||||
<li className="menu-item"><Link href="/social-media" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Social Media</Link></li>
|
||||
<li className="">
|
||||
<Link href="/culture" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Environment/Bulb.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Environment/Bulb.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Culture
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/communications" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Communication/Chat.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Communication/Chat.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Language Support
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/public-relations" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Communication/Paper_Plane.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Communication/Paper_Plane.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Public Relations
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/investor-relations" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Interface/Chart_Line.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Interface/Chart_Line.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Investor Relations
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/collaborators" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/User/Users_Group.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/User/Users_Group.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Collaborators
|
||||
</Link>
|
||||
</li>
|
||||
<li className="item">
|
||||
<Link href="/social-media" className="dark:hover:bg-mulberry-700 hover:bg-sand-300 transition-all duration-300 ease-out flex items-center gap-2">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Communication/Share_iOS_Export.png" alt="" className="h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Communication/Share_iOS_Export.png" alt="" className="hidden h-3 w-3 dark:block" />
|
||||
Social Media
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
{/* Breadcrumb - always visible */}
|
||||
<div className="">
|
||||
<Breadcrumb />
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<nav className="flex items-center space-x-chorus-xs px-chorus-xs py-chorus-xs">
|
||||
<Link href="/" className="text-carbon-800 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:text-white transition-all duration-300 ease-out hover:translate-x-1">Home</Link>
|
||||
<span className="text-carbon-500 dark:text-mulberry-400">/</span>
|
||||
<span className="text-carbon-800 dark:text-mulberry-200">Brand Guide</span>
|
||||
</nav>
|
||||
|
||||
{/* Mobile accordion menu - only visible when hamburger is clicked */}
|
||||
{mobileMenuOpen && (
|
||||
<div className="lg:hidden bg-white/95 dark:bg-mulberry-950/95 backdrop-blur border-t border-nickel-200 dark:border-mulberry-800">
|
||||
<MobileAccordionMenu onClose={() => setMobileMenuOpen(false)} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Visual Aid Modal - same as BottomDock */}
|
||||
{showVisualAid && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm">
|
||||
<div className="relative bg-white dark:bg-mulberry-950 border border-nickel-200 dark:border-mulberry-800 max-w-lg w-full mx-4 p-chorus-lg shadow-xl">
|
||||
<div className="flex items-center justify-between mb-chorus-md">
|
||||
<h3 className="text-h3 text-carbon-950 dark:text-white">Visual Aid Settings</h3>
|
||||
<button
|
||||
onClick={() => setShowVisualAid(false)}
|
||||
className="text-carbon-600 hover:text-carbon-950 dark:text-gray-400 dark:hover:text-white"
|
||||
>
|
||||
<svg className="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<path d="M18 6L6 18M6 6L18 18"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-chorus-md">
|
||||
<p className="text-sm text-carbon-600 dark:text-mulberry-300">
|
||||
Adjust the visual appearance for different color vision conditions. These settings affect the Möbius ring logo materials while preserving the overall design integrity.
|
||||
</p>
|
||||
|
||||
<div className="space-y-chorus-sm">
|
||||
<h4 className="text-h4 text-carbon-950 dark:text-white">Color Vision Support</h4>
|
||||
<p className="text-sm text-carbon-600 dark:text-mulberry-300 mb-2">
|
||||
8-color CHORUS system adaptations that preserve brand integrity while ensuring accessibility
|
||||
</p>
|
||||
<div className="grid grid-cols-1 gap-2">
|
||||
<button className="p-chorus-sm text-left border border-nickel-200 dark:border-mulberry-800 hover:bg-nickel-50 dark:hover:bg-mulberry-900 transition-colors">
|
||||
<strong>Default Vision</strong><br />
|
||||
<small className="text-carbon-600 dark:text-mulberry-300">Standard CHORUS 8-color system</small>
|
||||
</button>
|
||||
<button className="p-chorus-sm text-left border border-nickel-200 dark:border-mulberry-800 hover:bg-nickel-50 dark:hover:bg-mulberry-900 transition-colors">
|
||||
<strong>Protanopia (Red-blind)</strong><br />
|
||||
<small className="text-carbon-600 dark:text-mulberry-300">Ocean/Sand adaptations</small>
|
||||
</button>
|
||||
<button className="p-chorus-sm text-left border border-nickel-200 dark:border-mulberry-800 hover:bg-nickel-50 dark:hover:bg-mulberry-900 transition-colors">
|
||||
<strong>Deuteranopia (Green-blind)</strong><br />
|
||||
<small className="text-carbon-600 dark:text-mulberry-300">Blue/Yellow enhanced contrast</small>
|
||||
</button>
|
||||
<button className="p-chorus-sm text-left border border-nickel-200 dark:border-mulberry-800 hover:bg-nickel-50 dark:hover:bg-mulberry-900 transition-colors">
|
||||
<strong>Tritanopia (Blue-blind)</strong><br />
|
||||
<small className="text-carbon-600 dark:text-mulberry-300">Coral/Eucalyptus substitutions</small>
|
||||
</button>
|
||||
<button className="p-chorus-sm text-left border border-nickel-200 dark:border-mulberry-800 hover:bg-nickel-50 dark:hover:bg-mulberry-900 transition-colors">
|
||||
<strong>Achromatopsia (Color blind)</strong><br />
|
||||
<small className="text-carbon-600 dark:text-mulberry-300">High contrast grayscale only</small>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,12 +1,47 @@
|
||||
|
||||
import React from 'react';
|
||||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import ThreeLogo from './ThreeLogo'; // Replace with the correct path to the ThreeLogo component
|
||||
|
||||
interface NavItem {
|
||||
href: string;
|
||||
section: string;
|
||||
icon: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
interface NavCategory {
|
||||
id: string;
|
||||
label: string;
|
||||
icon: string;
|
||||
items: NavItem[];
|
||||
}
|
||||
|
||||
const Sidebar = () => {
|
||||
const navLinks = [
|
||||
const pathname = usePathname();
|
||||
const [expandedSections, setExpandedSections] = useState<string[]>(['overview']);
|
||||
|
||||
// Organize navigation items into categories matching primary nav
|
||||
const navCategories: NavCategory[] = [
|
||||
{
|
||||
id: 'overview',
|
||||
label: 'Overview',
|
||||
icon: 'Navigation/House_01',
|
||||
items: [
|
||||
{ href: '/', section: 'overview', icon: 'Navigation/House_01', label: 'Brand Overview' },
|
||||
{ href: '/identity', section: 'identity', icon: 'User/User_01', label: 'Brand Identity' },
|
||||
{ href: '/usage', section: 'usage', icon: 'Interface/Book', label: 'Usage Guidelines' },
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'visual-identity',
|
||||
label: 'Visual Identity',
|
||||
icon: 'Interface/Main_Component',
|
||||
items: [
|
||||
{ href: '/visual-identity', section: 'visual-identity', icon: 'Interface/Main_Component', label: 'Visual Identity' },
|
||||
{ href: '/logo', section: 'logo', icon: 'Interface/Star', label: 'Logo System' },
|
||||
{ href: '/typography', section: 'typography', icon: 'Edit/Text', label: 'Typography' },
|
||||
{ href: '/colors', section: 'colors', icon: 'Edit/Swatches_Palette', label: 'Color Palette' },
|
||||
@@ -15,33 +50,140 @@ const Sidebar = () => {
|
||||
{ href: '/components', section: 'components', icon: 'Interface/Settings', label: 'Components' },
|
||||
{ href: '/motion', section: 'motion', icon: 'Interface/Link', label: 'Motion System' },
|
||||
{ href: '/implementation', section: 'implementation', icon: 'File/File_Code', label: 'Implementation' },
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'communications',
|
||||
label: 'Communications',
|
||||
icon: 'Communication/Chat',
|
||||
items: [
|
||||
{ href: '/culture', section: 'culture', icon: 'Environment/Bulb', label: 'Culture' },
|
||||
{ href: '/communications', section: 'communications', icon: 'Communication/Chat', label: 'Language Support' },
|
||||
{ href: '/public-relations', section: 'public-relations', icon: 'Communication/Paper_Plane', label: 'Public Relations' },
|
||||
{ href: '/investor-relations', section: 'investor-relations', icon: 'Interface/Chart_Line', label: 'Investor Relations' },
|
||||
{ href: '/collaborators', section: 'collaborators', icon: 'User/Users_Group', label: 'Collaborators' },
|
||||
{ href: '/social-media', section: 'social-media', icon: 'Communication/Share_iOS_Export', label: 'Social Media' },
|
||||
{ href: '/visual-identity', section: 'visual-identity', icon: 'Interface/Main_Component', label: 'Visual Identity' },
|
||||
{ href: '/culture', section: 'culture', icon: 'Environment/Bulb', label: 'Culture' },
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const toggleSection = (sectionId: string) => {
|
||||
setExpandedSections(prev =>
|
||||
prev.includes(sectionId)
|
||||
? prev.filter(id => id !== sectionId)
|
||||
: [sectionId] // Only keep the newly opened section
|
||||
);
|
||||
};
|
||||
|
||||
// Check if current path belongs to a category to auto-expand it
|
||||
React.useEffect(() => {
|
||||
const currentCategory = navCategories.find(category =>
|
||||
category.items.some(item => item.href === pathname)
|
||||
);
|
||||
|
||||
if (currentCategory) {
|
||||
// Always set only the current category as expanded, closing others
|
||||
setExpandedSections([currentCategory.id]);
|
||||
}
|
||||
}, [pathname]);
|
||||
|
||||
const isCurrentPage = (href: string) => pathname === href;
|
||||
const isCategoryActive = (category: NavCategory) =>
|
||||
category.items.some(item => item.href === pathname);
|
||||
|
||||
return (
|
||||
<aside className="fixed inset-y-0 left-0 hidden w-64 border-r border-nickel-200 bg-white/95 p-0 backdrop-blur md:block dark:border-mulberry-800 dark:bg-mulberry-950/95">
|
||||
<div className="mb-chorus-sm flex items-center gap-chorus-sm p-chorus-lg">
|
||||
<span className="text-2xl font-black text-carbon-600 dark:text-white mb-chorus-lg">Brand Guide</span>
|
||||
<aside className="fixed inset-y-0 left-0 hidden w-64 border-r border-nickel-200 bg-white/80 p-0 backdrop-blur lg:block dark:border-mulberry-800 dark:bg-mulberry-950/80">
|
||||
<div className="mb-chorus-xs p-chorus-xs">
|
||||
<div className="px-chorus-md py-chorus-sm">
|
||||
<ThreeLogo width={128} height={128} />
|
||||
<div>
|
||||
<div className="font-logo">CHORUS</div>
|
||||
</div>
|
||||
<nav className="space-y-micro text-sm" id="brand-nav">
|
||||
{navLinks.map((link) => (
|
||||
<Link
|
||||
key={link.section}
|
||||
href={link.href}
|
||||
className="nav-link group flex items-center gap-2 px-chorus-md py-chorus-sm text-carbon-800 transition-all duration-300 ease-out hover:translate-x-1 hover:bg-sand-50 hover:bg-opacity-30 hover:text-mulberry-950 dark:text-mulberry-200 dark:hover:bg-mulberry-900 dark:hover:bg-opacity-40 dark:hover:text-white"
|
||||
data-section={link.section}
|
||||
</div>
|
||||
<h3 className="text-h3 text-carbon-600 dark:text-white mb-chorus-lg">Brand Guide</h3>
|
||||
</div>
|
||||
|
||||
<nav className="space-y-xs text-sm" id="brand-nav">
|
||||
{navCategories.map((category) => {
|
||||
const isExpanded = expandedSections.includes(category.id);
|
||||
const isActive = isCategoryActive(category);
|
||||
|
||||
return (
|
||||
<div key={category.id} className="space-y-xs">
|
||||
{/* Category Header - Accordion Toggle */}
|
||||
<button
|
||||
onClick={() => toggleSection(category.id)}
|
||||
className={`w-full group flex items-center justify-between gap-2 px-chorus-md py-chorus-sm text-left transition-all duration-300 ease-out hover:translate-x-1 hover:bg-sand-50 hover:bg-opacity-30 hover:text-mulberry-950 dark:hover:bg-mulberry-900 dark:hover:bg-opacity-40 dark:hover:text-white ${
|
||||
isActive
|
||||
? 'bg-sand-100 text-mulberry-950 dark:bg-mulberry-800 dark:text-white font-medium'
|
||||
: 'text-carbon-700 dark:text-mulberry-300'
|
||||
}`}
|
||||
aria-expanded={isExpanded}
|
||||
aria-controls={`${category.id}-submenu`}
|
||||
>
|
||||
<img src={`/icons/coolicons.v4.1/coolicons PNG/Black/${link.icon}.png`} alt="" className="h-4 w-4 transition-transform duration-300 group-hover:scale-110 dark:hidden" />
|
||||
<img src={`/icons/coolicons.v4.1/coolicons PNG/White/${link.icon}.png`} alt="" className="hidden h-4 w-4 transition-transform duration-300 group-hover:scale-110 dark:block" />
|
||||
<span className="transition-all duration-300 group-hover:font-medium">{link.label}</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<img
|
||||
src={`/icons/coolicons.v4.1/coolicons PNG/Black/${category.icon}.png`}
|
||||
alt=""
|
||||
className="h-4 w-4 transition-transform duration-300 group-hover:scale-110 dark:hidden"
|
||||
/>
|
||||
<img
|
||||
src={`/icons/coolicons.v4.1/coolicons PNG/White/${category.icon}.png`}
|
||||
alt=""
|
||||
className="hidden h-4 w-4 transition-transform duration-300 group-hover:scale-110 dark:block"
|
||||
/>
|
||||
<span className="transition-all duration-300 group-hover:font-semibold font-semibold">
|
||||
{category.label}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Chevron Icon */}
|
||||
<svg
|
||||
className={`w-4 h-4 transition-transform duration-300 ${isExpanded ? 'rotate-90' : ''}`}
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path fillRule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clipRule="evenodd" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{/* Category Items - Collapsible */}
|
||||
<div
|
||||
id={`${category.id}-submenu`}
|
||||
className={`space-y-1 ml-6 transition-all duration-300 ease-out ${
|
||||
isExpanded ? 'max-h-screen opacity-100' : 'max-h-0 opacity-0 overflow-hidden'
|
||||
}`}
|
||||
>
|
||||
{category.items.map((item) => (
|
||||
<Link
|
||||
key={item.section}
|
||||
href={item.href}
|
||||
className={`nav-link group flex items-center gap-2 px-chorus-sm py-chorus-xs transition-all duration-300 ease-out hover:translate-x-1 hover:bg-sand-50 hover:bg-opacity-30 hover:text-mulberry-950 dark:hover:bg-mulberry-900 dark:hover:bg-opacity-40 dark:hover:text-white ${
|
||||
isCurrentPage(item.href)
|
||||
? 'bg-sand-50 text-mulberry-950 dark:bg-mulberry-900 dark:text-white font-medium border-l-2 border-mulberry-600 dark:border-mulberry-400'
|
||||
: 'text-carbon-600 dark:text-mulberry-400'
|
||||
}`}
|
||||
data-section={item.section}
|
||||
>
|
||||
<img
|
||||
src={`/icons/coolicons.v4.1/coolicons PNG/Black/${item.icon}.png`}
|
||||
alt=""
|
||||
className="h-3 w-3 transition-transform duration-300 group-hover:scale-110 dark:hidden"
|
||||
/>
|
||||
<img
|
||||
src={`/icons/coolicons.v4.1/coolicons PNG/White/${item.icon}.png`}
|
||||
alt=""
|
||||
className="hidden h-3 w-3 transition-transform duration-300 group-hover:scale-110 dark:block"
|
||||
/>
|
||||
<span className="transition-all duration-300 group-hover:font-medium text-sm">
|
||||
{item.label}
|
||||
</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
</aside>
|
||||
);
|
||||
|
||||
@@ -23,6 +23,7 @@ export default function ThreeLogo({ width = 64, height = 64, className = "" }: T
|
||||
const scene = new THREE.Scene();
|
||||
const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 100);
|
||||
camera.position.set(0, 0, 2.2); // Move camera back to prevent clipping
|
||||
camera.lookAt(0, 0, 0); // Ensure camera looks at exact center
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
@@ -121,8 +122,13 @@ export default function ThreeLogo({ width = 64, height = 64, className = "" }: T
|
||||
}
|
||||
});
|
||||
|
||||
// Center the model exactly at origin
|
||||
const box = new THREE.Box3().setFromObject(model);
|
||||
const center = box.getCenter(new THREE.Vector3());
|
||||
model.position.sub(center); // Move model so its center is at (0,0,0)
|
||||
|
||||
scene.add(model);
|
||||
console.log('🎯 Your Möbius GLB model added to scene');
|
||||
console.log('🎯 Your Möbius GLB model added to scene and centered at origin');
|
||||
},
|
||||
(progress) => {
|
||||
if (progress.total > 0) {
|
||||
@@ -137,6 +143,7 @@ export default function ThreeLogo({ width = 64, height = 64, className = "" }: T
|
||||
console.log('Creating fallback torus geometry...');
|
||||
const fallbackGeometry = new THREE.TorusGeometry(0.6, 0.2, 16, 100);
|
||||
const fallbackMesh = new THREE.Mesh(fallbackGeometry, material);
|
||||
fallbackMesh.position.set(0, 0, 0); // Ensure fallback is also centered
|
||||
scene.add(fallbackMesh);
|
||||
model = fallbackMesh;
|
||||
|
||||
@@ -185,7 +192,10 @@ export default function ThreeLogo({ width = 64, height = 64, className = "" }: T
|
||||
style={{
|
||||
width: `${width}px`,
|
||||
height: `${height}px`,
|
||||
aspectRatio: '1 / 1'
|
||||
aspectRatio: '1 / 1',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user