feat: Implement ScrollReveal animations and sync navigation icons
- Add ScrollReveal component with Intersection Observer API - Create useIntersectionObserver hook for scroll-based animations - Implement progressive scroll animations on motion page (200ms-600ms delays) - Add CSS animation system with prefers-reduced-motion accessibility support - Update navigation icons for consistency between sidebar and primary nav - Use Interface/Trending_Up for Motion System and Environment/Puzzle for Components - Add GPU-accelerated transforms with will-change optimization 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
|
||||
import ScrollReveal from '@/components/ScrollReveal';
|
||||
export default function ColorsPage() {
|
||||
const lightColorSets = [
|
||||
{
|
||||
@@ -170,7 +170,9 @@ export default function ColorsPage() {
|
||||
<div className="py-chorus-xxl bg-gradient-to-b dark:from-carbon-950 dark:to-mulberry-950 from-white to-sand-200">
|
||||
<section id="colors" className="pt-chorus-xxl">
|
||||
<div className="px-chorus-lg max-w-5xl mx-auto">
|
||||
<ScrollReveal delay={300} duration={600} direction="up">
|
||||
<h2 className="text-h2 mb-chorus-lg">Color Palette</h2>
|
||||
</ScrollReveal>
|
||||
|
||||
<div className="space-y-chorus-lg">
|
||||
<div>
|
||||
@@ -183,6 +185,7 @@ export default function ColorsPage() {
|
||||
|
||||
<div className="grid md:grid-cols-2 mb-chorus-lg">
|
||||
<div className="p-chorus-lg bg-mulberry-900 shadow-lg">
|
||||
<ScrollReveal delay={300} duration={600} direction="up">
|
||||
<div className="flex items-center gap-3 mb-chorus-sm">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Environment/Moon.png" alt="Dark Mode" className="w-8 h-8" />
|
||||
<h4 className="text-h4 text-white">Dark Mode (Default)</h4>
|
||||
@@ -194,9 +197,11 @@ export default function ColorsPage() {
|
||||
<li><strong>Aesthetic:</strong> Ultra-minimalist with sophisticated mulberry accents</li>
|
||||
<li><strong>Contrast:</strong> WCAG 2.1 AA compliant</li>
|
||||
</ul>
|
||||
</ScrollReveal>
|
||||
<div className="-mr-chorus-lg">
|
||||
{darkColorSets.map((colorSet) => (
|
||||
<div key={colorSet.name} className={`border border-nickel-200 overflow-hidden bg-${colorSet.baseColor}`}>
|
||||
<ScrollReveal delay={300} duration={600} direction="up">
|
||||
<div className={`p-chorus-lg bg-${colorSet.baseColor}`}>
|
||||
<div className="flex items-start justify-between mb-chorus-md">
|
||||
<div>
|
||||
@@ -226,6 +231,7 @@ export default function ColorsPage() {
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -233,6 +239,8 @@ export default function ColorsPage() {
|
||||
</div>
|
||||
|
||||
<div className="p-chorus-lg bg-white shadow-lg">
|
||||
|
||||
<ScrollReveal delay={300} duration={600} direction="up">
|
||||
<div className="flex items-center gap-3 mb-chorus-sm">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Environment/Sun.png" alt="Light Mode" className="w-8 h-8" />
|
||||
<h4 className="text-h4 text-carbon-900">Light Mode (Alternative)</h4>
|
||||
@@ -244,10 +252,13 @@ export default function ColorsPage() {
|
||||
<li><strong>Usage:</strong> Print materials, accessibility accommodations</li>
|
||||
<li><strong>Contrast:</strong> Optimized for readability on warm backgrounds</li>
|
||||
</ul>
|
||||
</ScrollReveal>
|
||||
|
||||
<div className="-ml-chorus-lg">
|
||||
{lightColorSets.map((colorSet) => (
|
||||
<div key={colorSet.name} className={`border border-nickel-200 overflow-hidden bg-${colorSet.baseColor}`}>
|
||||
<ScrollReveal delay={300} duration={600} direction="up">
|
||||
|
||||
<div className={`p-chorus-lg bg-${colorSet.baseColor}`}>
|
||||
<div className="flex items-start justify-between mb-chorus-md">
|
||||
<div>
|
||||
@@ -277,6 +288,7 @@ export default function ColorsPage() {
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -51,30 +51,30 @@ export default function Communications() {
|
||||
<div className="border border-nickel-200 p-chorus-lg dark:border-nickel-900 ">
|
||||
<h3 className="text-h3 mb-chorus-md">Writing Style</h3>
|
||||
<ul className="space-y-2 text-sm text-carbon-600 dark:text-mulberry-300">
|
||||
<li>• Active voice preferred</li>
|
||||
<li>• Clear, concise sentences</li>
|
||||
<li>• Technical accuracy</li>
|
||||
<li>• Inclusive language</li>
|
||||
<li>Active voice preferred</li>
|
||||
<li>Clear, concise sentences</li>
|
||||
<li>Technical accuracy</li>
|
||||
<li>Inclusive language</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="border border-nickel-200 p-chorus-lg dark:border-nickel-900 ">
|
||||
<h3 className="text-h3 mb-chorus-md">Terminology</h3>
|
||||
<ul className="space-y-2 text-sm text-carbon-600 dark:text-mulberry-300">
|
||||
<li>• "AI agents" not "bots"</li>
|
||||
<li>• "Context management"</li>
|
||||
<li>• "Distributed orchestration"</li>
|
||||
<li>• "Knowledge fabric"</li>
|
||||
<li>"AI agents" not "bots"</li>
|
||||
<li>"Context management"</li>
|
||||
<li>"Distributed orchestration"</li>
|
||||
<li>"Knowledge fabric"</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="border border-nickel-200 p-chorus-lg dark:border-nickel-900 ">
|
||||
<h3 className="text-h3 mb-chorus-md">Localization</h3>
|
||||
<ul className="space-y-2 text-sm text-carbon-600 dark:text-mulberry-300">
|
||||
<li>• Global-first approach</li>
|
||||
<li>• Cultural sensitivity</li>
|
||||
<li>• Technical term consistency</li>
|
||||
<li>• Regional adaptations</li>
|
||||
<li>Global-first approach</li>
|
||||
<li>Cultural sensitivity</li>
|
||||
<li>Technical term consistency</li>
|
||||
<li>Regional adaptations</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -790,6 +790,10 @@ pre[class*="language-"] {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.secondary-nav {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.primary-nav {
|
||||
position: relative;
|
||||
font-weight: 600;
|
||||
@@ -1104,6 +1108,22 @@ nav button {
|
||||
&.dark .bg-white { background-color: #ffffff !important; }
|
||||
}
|
||||
|
||||
/* Scroll Animation System */
|
||||
.scroll-reveal {
|
||||
/* Base styles for scroll animations */
|
||||
will-change: opacity, transform;
|
||||
}
|
||||
|
||||
/* Accessibility: respect prefers-reduced-motion */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.scroll-reveal, .scroll-reveal * {
|
||||
animation-duration: 0.01ms !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
transform: none !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enhanced contrast for accessibility theme selection indicators */
|
||||
[data-theme="protanopia"] .ring-ocean-500 { box-shadow: 0 0 0 2px #1e40af !important; }
|
||||
[data-theme="deuteranopia"] .ring-eucalyptus-500 { box-shadow: 0 0 0 2px #6b21a8 !important; }
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { div } from "three/tsl"
|
||||
import ScrollReveal from '@/components/ScrollReveal';
|
||||
|
||||
export default function IconographyPage() {
|
||||
return (
|
||||
<div className="py-chorus-xxl">
|
||||
<section>
|
||||
<div className="max-w-5xl mx-auto px-chorus-lg pt-chorus-xxl">
|
||||
<ScrollReveal delay={200} duration={600} direction="up">
|
||||
<div className="mb-chorus-xxl">
|
||||
<h1 className="text-h2 mb-chorus-lg">Iconography System</h1>
|
||||
|
||||
@@ -15,23 +17,31 @@ export default function IconographyPage() {
|
||||
</p>
|
||||
|
||||
<div className="grid gap-chorus-md md:grid-cols-3 mt-chorus-lg">
|
||||
<ScrollReveal delay={300} duration={600} direction="up">
|
||||
<div className="border border-nickel-200 p-chorus-md dark:border-nickel-900 bg-white dark:bg-mulberry-950">
|
||||
<h4 className="text-h4 mb-chorus-sm">Clarity & Recognition</h4>
|
||||
<p className="text-sm text-carbon-600 dark:text-mulberry-300">Icons communicate instantly without language barriers</p>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
<ScrollReveal delay={400} duration={600} direction="up">
|
||||
<div className="border border-nickel-200 p-chorus-md dark:border-nickel-900 bg-white dark:bg-mulberry-950">
|
||||
<h4 className="text-h4 mb-chorus-sm">Theme Adaptive</h4>
|
||||
<p className="text-sm text-carbon-600 dark:text-mulberry-300">Black and white variants ensure perfect contrast in all modes</p>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
<ScrollReveal delay={500} duration={600} direction="up">
|
||||
<div className="border border-nickel-200 p-chorus-md dark:border-nickel-900 bg-white dark:bg-mulberry-950">
|
||||
<h4 className="text-h4 mb-chorus-sm">Consistent Scale</h4>
|
||||
<p className="text-sm text-carbon-600 dark:text-mulberry-300">Standardized sizing maintains visual harmony</p>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
{/* Icon Categories */}
|
||||
|
||||
<section className="mb-chorus-xxl">
|
||||
<h2 className="text-h3 mb-chorus-md">Icon Categories</h2>
|
||||
<p className="mb-chorus-md">
|
||||
@@ -39,6 +49,7 @@ export default function IconographyPage() {
|
||||
</p>
|
||||
|
||||
<div className="space-y-chorus-lg">
|
||||
<ScrollReveal delay={500} duration={600} direction="up">
|
||||
{/* Interface Icons */}
|
||||
<div className="shadow-lg bg-white dark:bg-mulberry-900 border border-nickel-200 p-chorus-lg dark:border-nickel-800">
|
||||
<h4 className="text-h4 mb-chorus-md">Interface & Navigation</h4>
|
||||
@@ -86,7 +97,9 @@ export default function IconographyPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={500} duration={600} direction="up">
|
||||
{/* Navigation Icons */}
|
||||
<div className="shadow-lg bg-white dark:bg-mulberry-900 border border-nickel-200 p-chorus-lg dark:border-nickel-800">
|
||||
<h4 className="text-h4 mb-chorus-md">Navigation & Direction</h4>
|
||||
@@ -134,7 +147,8 @@ export default function IconographyPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ScrollReveal>
|
||||
<ScrollReveal delay={500} duration={600} direction="up">
|
||||
{/* File & System Icons */}
|
||||
<div className="shadow-lg bg-white dark:bg-mulberry-900 border border-nickel-200 p-chorus-lg dark:border-nickel-800">
|
||||
<h4 className="text-h4 mb-chorus-md">File & System Operations</h4>
|
||||
@@ -182,7 +196,8 @@ export default function IconographyPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ScrollReveal>
|
||||
<ScrollReveal delay={500} duration={600} direction="up">
|
||||
{/* Communication Icons */}
|
||||
<div className="shadow-lg bg-white dark:bg-mulberry-900 border border-nickel-200 p-chorus-lg dark:border-nickel-800">
|
||||
<h4 className="text-h4 mb-chorus-md">Communication & Social</h4>
|
||||
@@ -230,7 +245,8 @@ export default function IconographyPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ScrollReveal>
|
||||
<ScrollReveal delay={500} duration={600} direction="up">
|
||||
{/* Status & Warning Icons */}
|
||||
<div className="shadow-lg bg-white dark:bg-mulberry-900 border border-nickel-200 p-chorus-lg dark:border-nickel-800">
|
||||
<h4 className="text-h4 mb-chorus-md">Status & Feedback</h4>
|
||||
@@ -278,9 +294,11 @@ export default function IconographyPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ScrollReveal delay={200} duration={600} direction="up">
|
||||
{/* Usage Guidelines */}
|
||||
<section className="mb-chorus-xxl">
|
||||
<h2 className="text-h3 mb-chorus-md">Usage Guidelines</h2>
|
||||
@@ -360,7 +378,9 @@ export default function IconographyPage() {
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={200} duration={600} direction="up">
|
||||
{/* Implementation Guide */}
|
||||
<section>
|
||||
<h2 className="text-h3 mb-chorus-md">Implementation Guide</h2>
|
||||
@@ -383,12 +403,12 @@ export default function IconographyPage() {
|
||||
</h5>
|
||||
<div className="bg-white dark:bg-carbon-950 p-chorus-md border border-gray-200 dark:border-mulberry-700 font-mono text-sm overflow-x-auto">
|
||||
<pre>{`<!-- Light theme icon (visible in light mode) -->
|
||||
<img src="icons/coolicons.v4.1/coolicons PNG/Black/Interface/Settings.png"
|
||||
<img src="icons/coolicons.v4.1/coolicons PNG/Black/Interface/Settings.png"
|
||||
alt="Settings"
|
||||
className="w-6 h-6 dark:hidden" />
|
||||
|
||||
<!-- Dark theme icon (visible in dark mode) -->
|
||||
<img src="icons/coolicons.v4.1/coolicons PNG/White/Interface/Settings.png"
|
||||
<!-- Dark theme icon (visible in dark mode) -->
|
||||
<img src="icons/coolicons.v4.1/coolicons PNG/White/Interface/Settings.png"
|
||||
alt="Settings"
|
||||
className="w-6 h-6 hidden dark:block" />`}</pre>
|
||||
</div>
|
||||
@@ -400,10 +420,10 @@ export default function IconographyPage() {
|
||||
</h5>
|
||||
<div className="bg-white dark:bg-carbon-950 p-chorus-md border border-gray-200 dark:border-mulberry-700 font-mono text-sm overflow-x-auto">
|
||||
<pre>{`/* Standard icon sizes following CHORUS spacing system */
|
||||
.icon-sm { width: 1rem; height: 1rem; } /* 16px */
|
||||
.icon-md { width: 1.25rem; height: 1.25rem; } /* 20px */
|
||||
.icon-lg { width: 1.5rem; height: 1.5rem; } /* 24px */
|
||||
.icon-xl { width: 2rem; height: 2rem; } /* 32px */`}</pre>
|
||||
.icon-sm { width: 1rem; height: 1rem; } /* 16px */
|
||||
.icon-md { width: 1.25rem; height: 1.25rem; } /* 20px */
|
||||
.icon-lg { width: 1.5rem; height: 1.5rem; } /* 24px */
|
||||
.icon-xl { width: 2rem; height: 2rem; } /* 32px */`}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -413,16 +433,17 @@ export default function IconographyPage() {
|
||||
</h5>
|
||||
<div className="bg-white dark:bg-carbon-950 p-chorus-md border border-gray-200 dark:border-mulberry-700 font-mono text-sm overflow-x-auto">
|
||||
<pre>{`public/icons/coolicons.v4.1/
|
||||
├── coolicons PNG/
|
||||
│ ├── Black/ # Light theme icons
|
||||
│ └── White/ # Dark theme icons
|
||||
├── coolicons SVG/ # Vector versions
|
||||
└── Webfont/ # Icon font (optional)`}</pre>
|
||||
├── coolicons PNG/
|
||||
│ ├── Black/ # Light theme icons
|
||||
│ └── White/ # Dark theme icons
|
||||
├── coolicons SVG/ # Vector versions
|
||||
└── Webfont/ # Icon font (optional)`}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -1,26 +1,36 @@
|
||||
|
||||
import ThreeLogo from '@/components/ThreeLogo';
|
||||
import ScrollReveal from '@/components/ScrollReveal';
|
||||
|
||||
export default function LogoPage() {
|
||||
return (
|
||||
<div className="py-chorus-xxl bg-gradient-to-b dark:from-mulberry-700 dark:to-mulberry-950 to-white from-sand-400 ">
|
||||
{/* Full-width Hero Section with 3D Logo */}
|
||||
<section id="logo-hero" className="mb-chorus-lg pt-chorus-xl">
|
||||
|
||||
<div className="relative">
|
||||
{/* Fixed Hero Section with 3D Logo */}
|
||||
<section
|
||||
id="logo-hero"
|
||||
className="fixed top-0 left-0 right-0 bottom-0 md:left-64 flex items-center justify-center bg-gradient-to-b dark:from-mulberry-700 dark:to-mulberry-950 to-white from-sand-400"
|
||||
>
|
||||
<ScrollReveal delay={300} duration={600} direction="up">
|
||||
{/* Logo Section */}
|
||||
<div className="pt-chorus-xs logo-group-circular mx-auto">
|
||||
<div className="pb-chorus-md item mx-auto logo-group-circular">
|
||||
<div className="logo-group-circular">
|
||||
<div className="item logo-group-circular">
|
||||
<ThreeLogo width={512} height={512} />
|
||||
<h4 className="text-h4 font-logo">CHORUS</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ScrollReveal>
|
||||
</section>
|
||||
|
||||
{/* Spacer to create scroll space */}
|
||||
<div className="h-screen"></div>
|
||||
|
||||
{/* Sliding Content Overlay */}
|
||||
<div className="relative z-10 bg-white dark:bg-transparent shadow-2xl">
|
||||
<div className="max-w-5xl mx-auto px-chorus-lg py-chorus-xxl">
|
||||
{/* Logo System Content */}
|
||||
<div className="space-y-chorus-xxl">
|
||||
{/* Primary Logo Description */}
|
||||
<ScrollReveal delay={300} duration={600} direction="up">
|
||||
<section>
|
||||
<h2 className="text-h2 mb-chorus-lg">Logo System</h2>
|
||||
|
||||
@@ -65,7 +75,7 @@ export default function LogoPage() {
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</ScrollReveal>
|
||||
{/* Logo Orientations */}
|
||||
<section>
|
||||
<h3 className="text-h3 mb-chorus-md">Logo Orientations</h3>
|
||||
@@ -263,5 +273,6 @@ export default function LogoPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import ScrollReveal from '@/components/ScrollReveal';
|
||||
|
||||
export default function Motion() {
|
||||
return (
|
||||
<div className="py-chorus-xxl bg-gradient-to-b dark:from-mulberry-950 dark:to-carbon-950 from-white to-sand-200">
|
||||
@@ -6,6 +8,7 @@ export default function Motion() {
|
||||
<h2 className="text-h2 mb-chorus-lg">Motion System</h2>
|
||||
|
||||
<div className="py-chorus-lg space-y-chorus-lg">
|
||||
<ScrollReveal delay={200} duration={600} direction="up">
|
||||
<div className="mb-chorus-lg">
|
||||
<p className="text-lg mb-chorus-md">
|
||||
The CHORUS motion system creates sophisticated, purposeful animations that enhance usability without overwhelming users.
|
||||
@@ -14,7 +17,9 @@ export default function Motion() {
|
||||
Our implementation focuses on performance, accessibility, and consistent timing that reinforces the premium CHORUS brand personality.
|
||||
</p>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={300} duration={600} direction="up">
|
||||
<div className="grid gap-chorus-lg md:grid-cols-3">
|
||||
<div className="border border-nickel-200 p-chorus-lg dark:border-nickel-900">
|
||||
<h3 className="text-h3 mb-chorus-md">Timing Scale</h3>
|
||||
@@ -62,7 +67,9 @@ export default function Motion() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={400} duration={600} direction="up">
|
||||
<div className="grid gap-chorus-lg md:grid-cols-2">
|
||||
<div className="bg-sand-50 dark:bg-mulberry-900 p-chorus-lg border border-sand-200 dark:border-mulberry-800">
|
||||
<h3 className="text-h3 mb-chorus-md">Interactive Elements</h3>
|
||||
@@ -113,7 +120,9 @@ export default function Motion() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={500} duration={600} direction="up">
|
||||
<div className="bg-white dark:bg-carbon-900 p-chorus-lg border border-nickel-200 dark:border-carbon-800">
|
||||
<h3 className="text-h3 mb-chorus-md">CSS Implementation</h3>
|
||||
<div className="grid gap-chorus-md md:grid-cols-2">
|
||||
@@ -145,7 +154,9 @@ export default function Motion() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={600} duration={600} direction="up">
|
||||
<div className="bg-sand-50 dark:bg-mulberry-900 p-chorus-lg border border-sand-200 dark:border-mulberry-800">
|
||||
<h3 className="text-h3 mb-chorus-md">Motion Principles</h3>
|
||||
<div className="grid gap-chorus-md md:grid-cols-2">
|
||||
@@ -171,6 +182,7 @@ export default function Motion() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import ScrollReveal from '@/components/ScrollReveal';
|
||||
|
||||
export default function TypographyPage() {
|
||||
return (
|
||||
<div className="py-chorus-xxl">
|
||||
<section className="mb-chorus-xxl pt-chorus-xxl">
|
||||
<div className="mb-chorus-xxl max-w-5xl mx-auto px-chorus-lg ">
|
||||
<ScrollReveal delay={300} duration={600} direction="up">
|
||||
|
||||
<h1 className="text-h2 mb-chorus-md">Typography</h1>
|
||||
<p className="text-carbon-600 dark:text-mulberry-300 mb-chorus-md">
|
||||
@@ -16,7 +18,9 @@ export default function TypographyPage() {
|
||||
All spacing, sizing, and proportions automatically scale with the 18px base. CHORUS spacing system (chorus-xs, chorus-md, etc.) maintains perfect proportional relationships.
|
||||
</p>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={400} duration={600} direction="up">
|
||||
{/* Font Families */}
|
||||
<div className="py-chorus-xl">
|
||||
<h2 className="text-h3 mb-chorus-md">Font Families</h2>
|
||||
@@ -64,8 +68,9 @@ export default function TypographyPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
|
||||
<ScrollReveal delay={500} duration={600} direction="up">
|
||||
{/* Typography Examples - DO vs DON'T */}
|
||||
<div className="py-chorus-xl">
|
||||
<div className="grid gap-chorus-lg md:grid-cols-2">
|
||||
@@ -189,14 +194,19 @@ export default function TypographyPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal delay={600} duration={600} direction="up">
|
||||
{/* Typography Scale */}
|
||||
|
||||
<h2 className="text-h3 mb-chorus-md">Proportional Font Scale</h2>
|
||||
<p className="text-sm text-carbon-500 dark:text-mulberry-300 mb-chorus-lg">
|
||||
Based on Major Third (1.25×) ratio with 18px foundation for enhanced readability
|
||||
</p>
|
||||
</ScrollReveal>
|
||||
|
||||
|
||||
<ScrollReveal delay={700} duration={600} direction="up">
|
||||
<div className="bg-white dark:bg-mulberry-950 border border-nickel-200 dark:border-mulberry-800 p-chorus-lg">
|
||||
<div className="grid gap-chorus-sm md:grid-cols-2">
|
||||
<div>
|
||||
@@ -219,8 +229,10 @@ export default function TypographyPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
|
||||
<ScrollReveal delay={800} duration={600} direction="up">
|
||||
<div className="pt-chorus-xl">
|
||||
<h2 className="text-h3 mb-chorus-md">Implementation Guide</h2>
|
||||
<p className="text-carbon-600 dark:text-mulberry-300 mb-chorus-lg">
|
||||
@@ -261,7 +273,9 @@ export default function TypographyPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -25,10 +25,8 @@ export default function Footer() {
|
||||
<h4 className="text-h4 text-carbon-950 dark:text-white mb-chorus-md">Brand Guide</h4>
|
||||
<ul className="space-y-chorus-xs text-sm">
|
||||
<li><Link href="/" className="text-carbon-600 dark:text-mulberry-300 hover:text-carbon-950 dark:hover:text-white transition-colors">Overview</Link></li>
|
||||
<li><Link href="/identity" className="text-carbon-600 dark:text-mulberry-300 hover:text-carbon-950 dark:hover:text-white transition-colors">Brand Identity</Link></li>
|
||||
<li><Link href="/colors" className="text-carbon-600 dark:text-mulberry-300 hover:text-carbon-950 dark:hover:text-white transition-colors">Color Palette</Link></li>
|
||||
<li><Link href="/typography" className="text-carbon-600 dark:text-mulberry-300 hover:text-carbon-950 dark:hover:text-white transition-colors">Typography</Link></li>
|
||||
<li><Link href="/logo" className="text-carbon-600 dark:text-mulberry-300 hover:text-carbon-950 dark:hover:text-white transition-colors">Logo System</Link></li>
|
||||
<li><Link href="/visual-identity" className="text-carbon-600 dark:text-mulberry-300 hover:text-carbon-950 dark:hover:text-white transition-colors">Visual Identity</Link></li>
|
||||
<li><Link href="/communications" className="text-carbon-600 dark:text-mulberry-300 hover:text-carbon-950 dark:hover:text-white transition-colors">Communications</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@@ -39,8 +39,8 @@ const MobileAccordionMenu = ({ onClose }: MobileAccordionMenuProps) => {
|
||||
{ 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: '/components', section: 'components', icon: 'Environment/Puzzle', label: 'Components' },
|
||||
{ href: '/motion', section: 'motion', icon: 'Interface/Trending_Up', label: 'Motion System' },
|
||||
{ href: '/implementation', section: 'implementation', icon: 'File/File_Code', label: 'Implementation' },
|
||||
]
|
||||
},
|
||||
@@ -95,7 +95,7 @@ const MobileAccordionMenu = ({ onClose }: MobileAccordionMenuProps) => {
|
||||
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'
|
||||
: 'transparent'
|
||||
}`}
|
||||
aria-expanded={isExpanded}
|
||||
>
|
||||
@@ -131,7 +131,7 @@ const MobileAccordionMenu = ({ onClose }: MobileAccordionMenuProps) => {
|
||||
onClick={onClose}
|
||||
className={`p-chorus-sm flex items-center gap-2 px-chorus-sm 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'
|
||||
? 'transparent text-mulberry-950 dark:text-white font-medium border-l-2 border-mulberry-600 dark:border-mulberry-400'
|
||||
: 'text-carbon-600 dark:text-mulberry-400'
|
||||
}`}
|
||||
>
|
||||
@@ -266,7 +266,7 @@ const Header = () => {
|
||||
{/* 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 backdrop-blur">
|
||||
<li className="item">
|
||||
<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="icon py-chous-sm h-4 w-4 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Navigation/House_01.png" alt="" className="icon py-chous-sm hidden h-4 w-4 dark:inline-flex" />
|
||||
@@ -296,7 +296,7 @@ const Header = () => {
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li className="dark:hover:bg-mulberry-700 hover:bg-sand-300 backdrop-blur">
|
||||
<li className="item">
|
||||
<div className="flex items-center gap-2 ml-chorus-sm">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Shape/Circle.png" alt="" className="icon py-chous-sm h-4 w-4 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Shape/Circle.png" alt="" className="icon py-chous-sm hidden h-4 w-4 dark:inline-flex" />
|
||||
@@ -348,15 +348,15 @@ const Header = () => {
|
||||
</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="icon py-chous-sm h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Interface/Settings.png" alt="" className="icon py-chous-sm hidden h-3 w-3 dark:inline-flex" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Environment/Puzzle.png" alt="" className="icon py-chous-sm h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Environment/Puzzle.png" alt="" className="icon py-chous-sm hidden h-3 w-3 dark:inline-flex" />
|
||||
<span>Components</span>
|
||||
</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="icon py-chous-sm h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Interface/Link.png" alt="" className="icon py-chous-sm hidden h-3 w-3 dark:inline-flex" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Interface/Trending_Up.png" alt="" className="icon py-chous-sm h-3 w-3 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Interface/Trending_Up.png" alt="" className="icon py-chous-sm hidden h-3 w-3 dark:inline-flex" />
|
||||
<span>Motion System</span>
|
||||
</Link>
|
||||
</li>
|
||||
@@ -369,7 +369,7 @@ const Header = () => {
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li className="dark:hover:bg-mulberry-700 hover:bg-sand-300">
|
||||
<li className="item">
|
||||
<div className="flex items-center gap-2 ml-chorus-sm">
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/Black/Communication/Chat.png" alt="" className="icon py-chous-sm h-4 w-4 dark:hidden" />
|
||||
<img src="/icons/coolicons.v4.1/coolicons PNG/White/Communication/Chat.png" alt="" className="icon py-chous-sm hidden h-4 w-4 dark:inline-flex" />
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { useIntersectionObserver } from '@/hooks/useIntersectionObserver';
|
||||
|
||||
interface ScrollRevealProps {
|
||||
children: React.ReactNode;
|
||||
delay?: number;
|
||||
duration?: number;
|
||||
direction?: 'up' | 'down' | 'left' | 'right';
|
||||
distance?: number;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export default function ScrollReveal({
|
||||
children,
|
||||
delay = 0,
|
||||
duration = 600,
|
||||
direction = 'up',
|
||||
distance = 24,
|
||||
className = '',
|
||||
}: ScrollRevealProps) {
|
||||
const { elementRef, isVisible } = useIntersectionObserver({
|
||||
threshold: 0.1,
|
||||
rootMargin: '0px 0px -100px 0px',
|
||||
triggerOnce: true,
|
||||
});
|
||||
|
||||
const getTransform = (visible: boolean) => {
|
||||
if (visible) return 'translate3d(0, 0, 0)';
|
||||
|
||||
switch (direction) {
|
||||
case 'up':
|
||||
return `translate3d(0, ${distance}px, 0)`;
|
||||
case 'down':
|
||||
return `translate3d(0, -${distance}px, 0)`;
|
||||
case 'left':
|
||||
return `translate3d(${distance}px, 0, 0)`;
|
||||
case 'right':
|
||||
return `translate3d(-${distance}px, 0, 0)`;
|
||||
default:
|
||||
return `translate3d(0, ${distance}px, 0)`;
|
||||
}
|
||||
};
|
||||
|
||||
const revealStyle = {
|
||||
opacity: isVisible ? 1 : 0,
|
||||
transform: getTransform(isVisible),
|
||||
transition: `opacity ${duration}ms ease-out ${delay}ms, transform ${duration}ms ease-out ${delay}ms`,
|
||||
willChange: 'opacity, transform',
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={elementRef}
|
||||
style={revealStyle}
|
||||
className={`scroll-reveal ${className}`}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -22,7 +22,7 @@ export default function ThreeLogo({ width = 64, height = 64, className = "" }: T
|
||||
// Scene / Renderer / Camera
|
||||
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.position.set(0, 0, 3.0); // 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 });
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
interface IntersectionObserverOptions {
|
||||
threshold?: number;
|
||||
rootMargin?: string;
|
||||
triggerOnce?: boolean;
|
||||
}
|
||||
|
||||
export function useIntersectionObserver(
|
||||
options: IntersectionObserverOptions = {}
|
||||
) {
|
||||
const { threshold = 0.1, rootMargin = '0px 0px -100px 0px', triggerOnce = true } = options;
|
||||
const [isIntersecting, setIsIntersecting] = useState(false);
|
||||
const [hasIntersected, setHasIntersected] = useState(false);
|
||||
const elementRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const element = elementRef.current;
|
||||
if (!element) return;
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
const isVisible = entry.isIntersecting;
|
||||
setIsIntersecting(isVisible);
|
||||
|
||||
if (isVisible && !hasIntersected) {
|
||||
setHasIntersected(true);
|
||||
}
|
||||
},
|
||||
{
|
||||
threshold,
|
||||
rootMargin,
|
||||
}
|
||||
);
|
||||
|
||||
observer.observe(element);
|
||||
|
||||
return () => {
|
||||
observer.unobserve(element);
|
||||
};
|
||||
}, [threshold, rootMargin, hasIntersected]);
|
||||
|
||||
return {
|
||||
elementRef,
|
||||
isVisible: triggerOnce ? hasIntersected : isIntersecting,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user