fix: Resolve color-blindness ring theme toggle conflicts

- Fix conflicting data-theme attributes between accessibility system and dark/light toggle
- Remove obsolete updateRingMaterial function that referenced non-existent mobius variable
- Update setAccessibilityTheme to use both data-theme and data-accessibility attributes
- Add dark mode variants for all accessibility materials (protanopia, deuteranopia, tritanopia, achromatopsia)
- Update logo.js material selection logic to check both attribute systems
- Ensure theme toggle preserves accessibility settings while changing light/dark mode
- Update CHORUS 8-color accessibility system with proper light/dark mode material mappings

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
tony
2025-08-21 08:28:13 +10:00
parent ba0e8c84ae
commit b25886a88c
2 changed files with 329 additions and 74 deletions

View File

@@ -163,6 +163,16 @@
--color-natural-paper: #F5F5DC; --color-natural-paper: #F5F5DC;
--color-brushed-nickel: #c1bfb1; --color-brushed-nickel: #c1bfb1;
/* CHORUS Semantic Color Tokens - 8 Color System */
--chorus-primary: #000000; /* carbon-950 */
--chorus-secondary: #0b0213; /* mulberry-950 */
--chorus-accent: #403730; /* walnut-900 */
--chorus-neutral: #c1bfb1; /* nickel-500 */
--chorus-info: #3a4654; /* ocean-900 */
--chorus-success: #3a4540; /* eucalyptus-900 */
--chorus-warning: #6a5c46; /* sand-900 */
--chorus-danger: #3e2d2c; /* coral-900 */
/* Light Theme Variables */ /* Light Theme Variables */
--bg-primary: #FFFFFF; --bg-primary: #FFFFFF;
--bg-secondary: #FEFEFE; --bg-secondary: #FEFEFE;
@@ -232,6 +242,97 @@
--color-ring-primary: #374151; /* Gray-700 for logo materials only */ --color-ring-primary: #374151; /* Gray-700 for logo materials only */
} }
/* CHORUS 8-Color Accessibility System */
/* Protanopia (Red-blind) - Preserve carbon/mulberry/walnut, adjust coral/eucalyptus */
[data-accessibility="protanopia"] {
--chorus-danger: var(--chorus-info); /* Use ocean instead of coral */
--chorus-success: var(--chorus-warning); /* Use sand instead of eucalyptus */
--chorus-warning: var(--chorus-neutral); /* Neutral tone for sand */
}
/* Light mode protanopia adjustments */
:root:not(.dark)[data-accessibility="protanopia"],
.light[data-accessibility="protanopia"] {
--chorus-danger: #2a3441; /* ocean-950 */
--chorus-success: #473e2f; /* sand-950 */
--chorus-warning: #2a2a2a; /* nickel-900 */
}
/* Dark mode protanopia adjustments */
.dark[data-accessibility="protanopia"] {
--chorus-danger: #cbefff; /* ocean-50 */
--chorus-success: #cee1be; /* sand-50 */
--chorus-warning: #f5f5f5; /* nickel-50 */
}
/* Deuteranopia (Green-blind) - Enhance blue/yellow contrast */
[data-accessibility="deuteranopia"] {
--chorus-success: var(--chorus-info); /* Use ocean instead of eucalyptus */
--chorus-info: var(--chorus-warning); /* Use sand for info */
--chorus-accent: var(--chorus-danger); /* Use coral for accent */
}
/* Light mode deuteranopia adjustments */
:root:not(.dark)[data-accessibility="deuteranopia"],
.light[data-accessibility="deuteranopia"] {
--chorus-success: #2a3441; /* ocean-950 */
--chorus-info: #473e2f; /* sand-950 */
--chorus-accent: #2e1d1c; /* coral-950 */
}
/* Dark mode deuteranopia adjustments */
.dark[data-accessibility="deuteranopia"] {
--chorus-success: #cbefff; /* ocean-50 */
--chorus-info: #cee1be; /* sand-50 */
--chorus-accent: #ffd6d6; /* coral-50 */
}
/* Tritanopia (Blue-blind) - Replace blue/yellow distinctions */
[data-accessibility="tritanopia"] {
--chorus-info: var(--chorus-danger); /* Use coral instead of ocean */
--chorus-warning: var(--chorus-success); /* Use eucalyptus instead of sand */
--chorus-primary: var(--chorus-secondary); /* Use mulberry for primary */
}
/* Light mode tritanopia adjustments */
:root:not(.dark)[data-accessibility="tritanopia"],
.light[data-accessibility="tritanopia"] {
--chorus-info: #2e1d1c; /* coral-950 */
--chorus-warning: #2a3330; /* eucalyptus-950 */
--chorus-primary: #0b0213; /* mulberry-950 */
}
/* Dark mode tritanopia adjustments */
.dark[data-accessibility="tritanopia"] {
--chorus-info: #ffd6d6; /* coral-50 */
--chorus-warning: #bacfbf; /* eucalyptus-50 */
--chorus-primary: #f0f4ff; /* mulberry-50 */
}
/* Achromatopsia (Complete color blindness) - Use brightness/contrast only */
[data-accessibility="achromatopsia"] {
--chorus-primary: #000000; /* Pure black */
--chorus-secondary: #333333; /* Dark gray */
--chorus-accent: #666666; /* Medium gray */
--chorus-neutral: #999999; /* Light gray */
--chorus-info: #444444; /* Dark medium */
--chorus-success: #222222; /* Very dark */
--chorus-warning: #777777; /* Medium light */
--chorus-danger: #111111; /* Almost black */
}
/* Dark mode achromatopsia adjustments */
.dark[data-accessibility="achromatopsia"] {
--chorus-primary: #ffffff; /* Pure white */
--chorus-secondary: #cccccc; /* Light gray */
--chorus-accent: #999999; /* Medium gray */
--chorus-neutral: #666666; /* Darker gray */
--chorus-info: #bbbbbb; /* Light medium */
--chorus-success: #dddddd; /* Very light */
--chorus-warning: #888888; /* Medium dark */
--chorus-danger: #eeeeee; /* Almost white */
}
/* Typography optimizations for brand guide */ /* Typography optimizations for brand guide */
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
font-weight: 600; font-weight: 600;
@@ -402,11 +503,12 @@
<section class="mb-chorus-xxl hero full-width py-chorus-xxl text-center bg-gradient-to-b dark:from-mulberry-800 dark:to-mulberry-950 from-sand-300 to-white p-chorus-lg"> <section class="mb-chorus-xxl hero full-width py-chorus-xxl text-center bg-gradient-to-b dark:from-mulberry-800 dark:to-mulberry-950 from-sand-300 to-white p-chorus-lg">
<div class="text-center"> <div class="text-center">
<h1 class="font-logo text-6xl font-regular tracking-wide text-mulberry-950 dark:text-white mb-chorus-md">CHORUS</h1> <h1 class="font-logo text-6xl font-regular tracking-wide text-mulberry-950 dark:text-white mb-chorus-md">CHORUS</h1>
<h3 class="text-2xl font-medium mb-chorus-xl">A distributed, semantic and temporal knowledge fabric<br/>for humans and AI agents alike<br/>to share reasoning, context, and intent,<br/>not just files.</h3> <h3 class="text-2xl font-medium mb-chorus-xl text-mulberry-400">A distributed, semantic and temporal knowledge fabric<br/>for humans and AI agents alike<br/>to share reasoning, context, and intent,<br/>not just files.</h3>
<h2 class="text-2xl font-black text-carbon-600 dark:text-white mb-chorus-lg">Brand Guide v1.0</h2> <h2 class="text-8xl font-bold text-carbon-600 dark:text-white mb-chorus-lg">Brand Guide</h2>
<p class="text-lg text-carbon-500 dark:text-gray-400 max-w-2xl mx-auto">This living document is your comprehensive visual identity system<br/>for our brand of distributed AI orchestration.</p> <h4 class="text-2xl font-semibold mb-chorus-lg">version 1.0</h4>
<p class="text-lg text-carbon-500 dark:text-mulberry-500 max-w-2xl mx-auto">This living document is your comprehensive visual identity system<br/>for our brand of distributed AI orchestration.</p>
</div> </div>
</section> </section>
@@ -416,9 +518,10 @@
<!-- Brand Overview --> <!-- Brand Overview -->
<section id="overview" class="mb-chorus-xxl"> <section id="overview" class="mb-chorus-xxl">
<h2 class="text-3xl font-bold mb-chorus-lg">Brand Overview</h2> <h2 class="text-5xl font-semibold mb-chorus-lg">Brand Overview</h2>
<div class="space-y-chorus-lg"> <div class="py-chorus-lg space-y-chorus-lg">
<div class="grid gap-chorus-md md:grid-cols-3">
<div> <div>
<h3 class="text-xl font-semibold mb-chorus-md">Mission Statement</h3> <h3 class="text-xl font-semibold mb-chorus-md">Mission Statement</h3>
<p>CHORUS Services eliminates context loss, reduces hallucinations, and enables scalable multi-agent collaboration through intelligent context management and distributed reasoning.</p> <p>CHORUS Services eliminates context loss, reduces hallucinations, and enables scalable multi-agent collaboration through intelligent context management and distributed reasoning.</p>
@@ -433,6 +536,7 @@
<h3 class="text-xl font-semibold mb-chorus-md">Brand Positioning</h3> <h3 class="text-xl font-semibold mb-chorus-md">Brand Positioning</h3>
<p>CHORUS Services positions itself as the premium, enterprise-grade solution for distributed AI orchestration, combining technical sophistication with approachable design to serve global enterprise customers seeking reliable, scalable AI coordination.</p> <p>CHORUS Services positions itself as the premium, enterprise-grade solution for distributed AI orchestration, combining technical sophistication with approachable design to serve global enterprise customers seeking reliable, scalable AI coordination.</p>
</div> </div>
</div>
<div> <div>
<h3 class="text-xl font-semibold mb-chorus-md">Target Audiences</h3> <h3 class="text-xl font-semibold mb-chorus-md">Target Audiences</h3>
@@ -474,7 +578,7 @@
<!-- Brand Identity --> <!-- Brand Identity -->
<section id="identity" class="mb-chorus-xxl"> <section id="identity" class="mb-chorus-xxl">
<h2 class="text-3xl font-bold mb-chorus-lg">Brand Identity Concept</h2> <h2 class="text-5xl font-semibold mb-chorus-lg ">Brand Identity Concept</h2>
<div class="space-y-chorus-lg"> <div class="space-y-chorus-lg">
<div> <div>
@@ -491,7 +595,7 @@
</div> </div>
<div> <div>
<h3 class="text-xl font-semibold mb-chorus-md">Brand Personality</h3> <h3 class="text-xl font-semibold mb-chorus-lg ">Brand Personality</h3>
<div class="grid gap-chorus-md md:grid-cols-2"> <div class="grid gap-chorus-md md:grid-cols-2">
<div class="flex items-start gap-chorus-sm"> <div class="flex items-start gap-chorus-sm">
<img src="icons/coolicons.v4.1/coolicons PNG/Black/Edit/Remove_Minus.png" alt="Minimalist" class="w-5 h-5 mt-0.5 dark:hidden"> <img src="icons/coolicons.v4.1/coolicons PNG/Black/Edit/Remove_Minus.png" alt="Minimalist" class="w-5 h-5 mt-0.5 dark:hidden">
@@ -561,10 +665,10 @@
</div> </div>
</section> </section>
<div class="px-chorus-lg"> <div class="px-chorus-lg">
<div class="max-w-4xl mx-auto py-chorus-xl"> <div class="max-w-4xl mx-auto">
<!-- Logo System --> <!-- Logo System -->
<section id="logo" class="mb-chorus-xxl"> <section id="logo" class="mb-chorus-xxl">
<h2 class="text-3xl font-bold mb-chorus-lg">Logo System</h2> <h2 class="text-5xl font-semibold mb-chorus-lg">Logo System</h2>
<div class="space-y-chorus-lg"> <div class="space-y-chorus-lg">
<div> <div>
@@ -579,7 +683,7 @@
</div> </div>
<div> <div>
<h3 class="text-xl font-semibold mb-chorus-md">Core Elements</h3> <h3 class="text-3xl font-semibold mb-chorus-md py-chorus-lg">Core Elements</h3>
<ol class="space-y-chorus-sm"> <ol class="space-y-chorus-sm">
<li><strong>3D Mobius Ring:</strong> The primary visual element featuring elegant metallic rendering with sophisticated lighting and materials, representing infinite collaboration and seamless process flow.</li> <li><strong>3D Mobius Ring:</strong> The primary visual element featuring elegant metallic rendering with sophisticated lighting and materials, representing infinite collaboration and seamless process flow.</li>
<li><strong>2D Minimalist Icon:</strong> An ultra-clean, geometric abstraction of the Mobius ring for UI applications and small-scale use.</li> <li><strong>2D Minimalist Icon:</strong> An ultra-clean, geometric abstraction of the Mobius ring for UI applications and small-scale use.</li>
@@ -711,7 +815,7 @@
<!-- Motion System --> <!-- Motion System -->
<section id="motion" class="mb-chorus-xxl"> <section id="motion" class="mb-chorus-xxl">
<h2 class="text-3xl font-bold mb-chorus-lg">Motion Design System</h2> <h2 class="text-5xl font-semibold mb-chorus-lg">Motion Design System</h2>
@@ -990,7 +1094,7 @@ document.addEventListener('DOMContentLoaded', () => {
<!-- Color Palette --> <!-- Color Palette -->
<section id="colors" class="mb-chorus-xxl"> <section id="colors" class="mb-chorus-xxl">
<h2 class="text-3xl font-bold mb-chorus-lg">Color Palette</h2> <h2 class="text-5xl font-semibold mb-chorus-lg">Color Palette</h2>
<div class="space-y-chorus-lg"> <div class="space-y-chorus-lg">
<div> <div>
@@ -1182,11 +1286,12 @@ document.addEventListener('DOMContentLoaded', () => {
</div> </div>
<div> <div>
<h3 class="text-xl font-semibold mb-chorus-md">Theme Implementation</h3> <h3 class="text-3xl font-semibold mb-chorus-md">Theme Implementation</h3>
<div class="grid gap-chorus-lg md:grid-cols-2"> <div class="grid gap-chorus-lg md:grid-cols-2">
<div class="border p-chorus-lg border-nickel-900 bg-mulberry-800"> <div class="border p-chorus-lg border-nickel-900 bg-mulberry-900 shadow-lg">
<h4 class="font-black mb-chorus-sm text-white">Dark Mode (Default/Preferred)</h4> <h2 class="text-3xl font-black mb-chorus-sm text-white">Dark Mode</h2>
<h4 class="mb-chorus-sm text-white">(Default/Preferred)</h4>
<p class="text-sm text-white dark:text-purple-300 mb-chorus-md">Dark mode is the preferred default for all CHORUS Services applications</p> <p class="text-sm text-white dark:text-purple-300 mb-chorus-md">Dark mode is the preferred default for all CHORUS Services applications</p>
<ul class="text-sm space-y-1 text-mulberry-100"> <ul class="text-sm space-y-1 text-mulberry-100">
<li><strong>Background Hierarchy:</strong> Carbon Black → Mulberry Variants → Cool Gray → Border Gray</li> <li><strong>Background Hierarchy:</strong> Carbon Black → Mulberry Variants → Cool Gray → Border Gray</li>
@@ -1196,8 +1301,9 @@ document.addEventListener('DOMContentLoaded', () => {
</ul> </ul>
</div> </div>
<div class="border border-nickel-100 p-chorus-lg border-nickel-900 bg-white"> <div class="border border-nickel-100 p-chorus-lg dark:border-nickel-900 bg-white shadow-lg">
<h4 class="font-black mb-chorus-sm text-carbon-900">Light Mode (Alternative)</h4> <h2 class="text-3xl font-black mb-chorus-sm text-carbon-900">Light Mode</h2>
<h4 class="mb-chorus-sm text-sand-700">(Alternative)</h4>
<p class="text-sm text-carbon-600 mb-chorus-md">Available as alternative but dark mode is strongly preferred</p> <p class="text-sm text-carbon-600 mb-chorus-md">Available as alternative but dark mode is strongly preferred</p>
<ul class="text-sm space-y-1 text-carbon-800"> <ul class="text-sm space-y-1 text-carbon-800">
<li><strong>Background Hierarchy:</strong> Pure White → Natural Paper → Light Gray → Border Light</li> <li><strong>Background Hierarchy:</strong> Pure White → Natural Paper → Light Gray → Border Light</li>
@@ -1215,7 +1321,7 @@ document.addEventListener('DOMContentLoaded', () => {
<!-- Iconography System --> <!-- Iconography System -->
<section id="iconography" class="mb-chorus-xxl"> <section id="iconography" class="mb-chorus-xxl">
<h2 class="text-3xl font-bold mb-chorus-lg">Iconography System</h2> <h2 class="text-5xl font-semibold mb-chorus-lg">Iconography System</h2>
<div class="space-y-chorus-lg"> <div class="space-y-chorus-lg">
<div> <div>
@@ -1556,7 +1662,7 @@ document.addEventListener('DOMContentLoaded', () => {
<!-- Accessibility & Vision Inclusivity --> <!-- Accessibility & Vision Inclusivity -->
<section id="accessibility" class="mb-chorus-xxl"> <section id="accessibility" class="mb-chorus-xxl">
<h2 class="text-3xl font-bold mb-chorus-lg">Accessibility & Vision Inclusivity</h2> <h2 class="text-5xl font-semibold mb-chorus-lg">Accessibility & Vision Inclusivity</h2>
<div class="space-y-chorus-lg"> <div class="space-y-chorus-lg">
<div> <div>
@@ -1579,6 +1685,63 @@ document.addEventListener('DOMContentLoaded', () => {
</div> </div>
</div> </div>
<!-- CHORUS 8-Color Accessibility System -->
<div>
<h3 class="text-xl font-semibold mb-chorus-md">CHORUS 8-Color Accessibility System</h3>
<p class="mb-chorus-md">Our advanced accessibility system remaps the core CHORUS 8-color palette (carbon, mulberry, walnut, nickel, ocean, eucalyptus, sand, coral) to vision-deficiency appropriate alternatives while preserving the light/dark theme toggle functionality.</p>
<div class="grid gap-chorus-md md:grid-cols-2 lg:grid-cols-4 mt-chorus-lg">
<div class="border border-nickel-100 p-chorus-md dark:border-nickel-900">
<h4 class="font-medium mb-chorus-sm text-blue-800 dark:text-blue-300">Protanopia (Red-blind)</h4>
<div class="text-xs space-y-1 text-carbon-600 dark:text-purple-300">
<div>• Danger: Ocean → Coral</div>
<div>• Success: Sand → Eucalyptus</div>
<div>• Warning: Nickel → Sand</div>
<div>• Preserves: Carbon, Mulberry, Walnut</div>
</div>
</div>
<div class="border border-nickel-100 p-chorus-md dark:border-nickel-900">
<h4 class="font-medium mb-chorus-sm text-purple-800 dark:text-purple-300">Deuteranopia (Green-blind)</h4>
<div class="text-xs space-y-1 text-carbon-600 dark:text-purple-300">
<div>• Success: Ocean → Eucalyptus</div>
<div>• Info: Sand → Ocean</div>
<div>• Accent: Coral → Walnut</div>
<div>• Enhances: Blue/yellow contrast</div>
</div>
</div>
<div class="border border-nickel-100 p-chorus-md dark:border-nickel-900">
<h4 class="font-medium mb-chorus-sm text-red-800 dark:text-red-300">Tritanopia (Blue-blind)</h4>
<div class="text-xs space-y-1 text-carbon-600 dark:text-purple-300">
<div>• Info: Coral → Ocean</div>
<div>• Warning: Eucalyptus → Sand</div>
<div>• Primary: Mulberry → Carbon</div>
<div>• Maintains: Red/green clarity</div>
</div>
</div>
<div class="border border-nickel-100 p-chorus-md dark:border-nickel-900">
<h4 class="font-medium mb-chorus-sm text-gray-800 dark:text-gray-300">Achromatopsia (Monochrome)</h4>
<div class="text-xs space-y-1 text-carbon-600 dark:text-purple-300">
<div>• Pure grayscale system</div>
<div>• Brightness hierarchy preserved</div>
<div>• Contrast ratios maintained</div>
<div>• Texture-based differentiation</div>
</div>
</div>
</div>
<div class="mt-chorus-lg p-chorus-md bg-sand-50 dark:bg-mulberry-900 border border-sand-200 dark:border-mulberry-800">
<h4 class="font-medium mb-2">Technical Implementation</h4>
<div class="text-sm text-carbon-600 dark:text-purple-300">
<p class="mb-2">The system uses CSS semantic tokens with compound selectors that combine light/dark themes with accessibility modes:</p>
<code class="text-xs bg-gray-100 dark:bg-gray-800 px-2 py-1">.dark[data-accessibility="protanopia"] { --chorus-danger: var(--chorus-info); }</code>
<p class="mt-2">This preserves your existing theme toggle while providing vision-inclusive alternatives.</p>
</div>
</div>
</div>
<div> <div>
<h3 class="text-xl font-semibold mb-chorus-md">Supported Vision Conditions</h3> <h3 class="text-xl font-semibold mb-chorus-md">Supported Vision Conditions</h3>
@@ -1794,22 +1957,10 @@ setAccessibilityTheme('protanopia');</code>
</div> </div>
</section> </section>
<!-- Include the web design section from the playground -->
<section id="web-design" class="mb-chorus-xxl">
<h2 class="text-3xl font-bold mb-chorus-lg">Web Design System</h2>
<p class="text-carbon-600 dark:text-purple-300 mb-chorus-xl">Interactive demonstration of the CHORUS web design system, including typography, components, forms, and styling patterns.</p>
<div class="border border-nickel-100 p-chorus-lg dark:border-nickel-900">
<p class="text-sm text-carbon-500 dark:text-gray-400">The web design components and interactive examples have been preserved in the original playground file for full testing and evaluation.</p>
<div class="mt-chorus-md">
<a href="tailwind_theme_evaluation_playground.html" class="bg-mulberry-950 px-chorus-lg py-chorus-sm text-white hover:opacity-90 dark:bg-white dark:text-carbon-950">View Interactive Design System</a>
</div>
</div>
</section>
<!-- Typography Section --> <!-- Typography Section -->
<section id="typography" class="mb-chorus-xl"> <section id="typography" class="mb-chorus-xl">
<h2 class="text-3xl font-bold mb-chorus-lg">Typography</h2> <h2 class="text-5xl font-semibold mb-chorus-lg">Typography</h2>
<p class="text-carbon-600 dark:text-purple-300 mb-chorus-xl">The CHORUS typography system is designed for clarity, hierarchy, and accessibility across all devices.</p> <p class="text-carbon-600 dark:text-purple-300 mb-chorus-xl">The CHORUS typography system is designed for clarity, hierarchy, and accessibility across all devices.</p>
<div class="grid gap-chorus-lg md:grid-cols-2"> <div class="grid gap-chorus-lg md:grid-cols-2">
@@ -1845,6 +1996,49 @@ setAccessibilityTheme('protanopia');</code>
<li><a href="#" class="text-gray-500 hover:text-gray-700 dark:text-purple-400 dark:hover:text-purple-300">Muted Link</a></li> <li><a href="#" class="text-gray-500 hover:text-gray-700 dark:text-purple-400 dark:hover:text-purple-300">Muted Link</a></li>
</ul> </ul>
</div> </div>
<!-- Font Sizes -->
<div>
<h3 class="text-xl font-semibold mb-chorus-md">Font Sizes</h3>
<div class="space-y-chorus-sm">
<p class="text-xs">Extra Small (12px)</p>
<p class="text-sm">Small (14px)</p>
<p class="text-base">Base (16px)</p>
<p class="text-lg">Large (18px)</p>
<p class="text-xl">Extra Large (20px)</p>
<p class="text-2xl">
2X Large (24px)
</p>
<p class="text-3xl">
3X Large (30px)
</p>
<p class="text-4xl">
4X Large (36px)
</p>
<p class="text-5xl">
5X Large (48px)
</p>
</div>
</div>
<!-- Font Weights -->
<div>
<h3 class="text-xl font-semibold mb-chorus-md">Font Weights</h3>
<div class="space-y-chorus-sm">
<p class="font-thin">Thin (100)</p>
<p class="font-extralight">Extra Light (200)</p>
<p class="font-light">Light (300)</p>
<p class="font-normal">Normal (400)</p>
<p class="font-medium">Medium (500)</p>
<p class="font-semibold">Semi Bold (600)</p>
<p class="font-bold">Bold (700)</p>
<p class="font-extrabold">Extra Bold (800)</p>
<p class="font-black">Black (900)</p>
</div>
</div>
</div> </div>
</section> </section>
</div> </div>
@@ -1972,30 +2166,33 @@ setAccessibilityTheme('protanopia');</code>
<!-- Vision Condition Buttons --> <!-- Vision Condition Buttons -->
<div class="space-y-chorus-sm"> <div class="space-y-chorus-sm">
<h4 class="font-medium text-carbon-950 dark:text-white">Color Vision Support</h4> <h4 class="font-medium text-carbon-950 dark:text-white">Color Vision Support</h4>
<p class="text-xs text-carbon-600 dark:text-purple-300 mb-2">
8-color CHORUS system adaptations that preserve brand integrity while ensuring accessibility
</p>
<div class="grid grid-cols-1 gap-2"> <div class="grid grid-cols-1 gap-2">
<button data-accessibility-theme="standard" class="modal-vision-btn bg-white text-carbon-950 border border-gray-300 px-4 py-2 text-sm hover:bg-gray-50 transition-all cursor-pointer text-left"> <button data-accessibility-theme="standard" class="modal-vision-btn bg-white text-carbon-950 border border-gray-300 px-4 py-2 text-sm hover:bg-gray-50 transition-all cursor-pointer text-left">
<div class="font-medium">Standard Vision</div> <div class="font-medium">Standard Vision</div>
<div class="text-xs text-gray-600">Default metallic appearance</div> <div class="text-xs text-gray-600">Default CHORUS 8-color palette</div>
</button> </button>
<button data-accessibility-theme="protanopia" class="modal-vision-btn bg-blue-800 text-white px-4 py-2 text-sm hover:bg-blue-700 transition-all cursor-pointer text-left"> <button data-accessibility-theme="protanopia" class="modal-vision-btn bg-blue-800 text-white px-4 py-2 text-sm hover:bg-blue-700 transition-all cursor-pointer text-left">
<div class="font-medium">Protanopia (Red-blind)</div> <div class="font-medium">Protanopia (Red-blind)</div>
<div class="text-xs text-blue-200">Enhanced blue/yellow contrast</div> <div class="text-xs text-blue-200">Ocean replaces coral, sand replaces eucalyptus</div>
</button> </button>
<button data-accessibility-theme="deuteranopia" class="modal-vision-btn bg-purple-800 text-white px-4 py-2 text-sm hover:bg-purple-700 transition-all cursor-pointer text-left"> <button data-accessibility-theme="deuteranopia" class="modal-vision-btn bg-purple-800 text-white px-4 py-2 text-sm hover:bg-purple-700 transition-all cursor-pointer text-left">
<div class="font-medium">Deuteranopia (Green-blind)</div> <div class="font-medium">Deuteranopia (Green-blind)</div>
<div class="text-xs text-purple-200">Blue/purple dominance patterns</div> <div class="text-xs text-purple-200">Ocean replaces eucalyptus, coral becomes accent</div>
</button> </button>
<button data-accessibility-theme="tritanopia" class="modal-vision-btn bg-red-800 text-white px-4 py-2 text-sm hover:bg-red-700 transition-all cursor-pointer text-left"> <button data-accessibility-theme="tritanopia" class="modal-vision-btn bg-red-800 text-white px-4 py-2 text-sm hover:bg-red-700 transition-all cursor-pointer text-left">
<div class="font-medium">Tritanopia (Blue-blind)</div> <div class="font-medium">Tritanopia (Blue-blind)</div>
<div class="text-xs text-red-200">Red/green clarity focus</div> <div class="text-xs text-red-200">Coral replaces ocean, eucalyptus replaces sand</div>
</button> </button>
<button data-accessibility-theme="achromatopsia" class="modal-vision-btn bg-gray-700 text-white px-4 py-2 text-sm hover:bg-gray-600 transition-all cursor-pointer text-left"> <button data-accessibility-theme="achromatopsia" class="modal-vision-btn bg-gray-700 text-white px-4 py-2 text-sm hover:bg-gray-600 transition-all cursor-pointer text-left">
<div class="font-medium">Achromatopsia (Complete color blindness)</div> <div class="font-medium">Achromatopsia (Complete color blindness)</div>
<div class="text-xs text-gray-300">High-contrast monochrome</div> <div class="text-xs text-gray-300">Grayscale system preserving contrast hierarchy</div>
</button> </button>
</div> </div>
</div> </div>
@@ -2023,24 +2220,14 @@ setAccessibilityTheme('protanopia');</code>
// Function to update ring material based on theme // Function to update ring material based on theme
function updateRingMaterial(isDark) { // Removed obsolete updateRingMaterial function - now handled by logo.js module
if (mobius) {
const targetMaterial = isDark ? darkMaterial : lightMaterial;
mobius.traverse((child) => {
if (child.isMesh) {
child.material = targetMaterial;
}
});
}
}
// Theme toggle (defaults to dark mode) // Theme toggle (defaults to dark mode)
const toggle = document.getElementById('toggleTheme'); const toggle = document.getElementById('toggleTheme');
toggle?.addEventListener('click', () => { toggle?.addEventListener('click', () => {
const root = document.documentElement; const root = document.documentElement;
const isDark = root.classList.toggle('dark'); const isDark = root.classList.toggle('dark');
root.setAttribute('data-theme', isDark ? 'dark' : 'light'); // Note: Don't set data-theme here as it conflicts with accessibility themes
updateRingMaterial(isDark);
console.log('Theme toggled to:', isDark ? 'dark' : 'light'); console.log('Theme toggled to:', isDark ? 'dark' : 'light');
console.log('updateAllLogoMaterials function available:', typeof window.updateAllLogoMaterials); console.log('updateAllLogoMaterials function available:', typeof window.updateAllLogoMaterials);
@@ -2066,24 +2253,27 @@ setAccessibilityTheme('protanopia');</code>
function setAccessibilityTheme(themeName) { function setAccessibilityTheme(themeName) {
console.log(`Setting accessibility theme: ${themeName}`); console.log(`Setting accessibility theme: ${themeName}`);
// Remove any existing data-theme attribute // Remove any existing accessibility attributes
document.documentElement.removeAttribute('data-theme'); document.documentElement.removeAttribute('data-theme'); // For logo materials
document.documentElement.removeAttribute('data-accessibility'); // For CSS system
// Set new theme if not standard vision // Set new theme if not standard vision
if (themeName !== 'standard') { if (themeName !== 'standard') {
document.documentElement.setAttribute('data-theme', themeName); document.documentElement.setAttribute('data-theme', themeName); // Logo materials
document.documentElement.setAttribute('data-accessibility', themeName); // CSS system
} }
// Store preference // Store preference
localStorage.setItem('chorus-accessibility-theme', themeName); localStorage.setItem('chorus-accessibility-theme', themeName);
// Update logo materials if available // Force update logo materials immediately - call the update function directly
if (window.updateLogoAccessibilityTheme) { const isDark = document.documentElement.classList.contains('dark');
if (window.updateAllLogoMaterials) {
try { try {
window.updateLogoAccessibilityTheme(themeName); window.updateAllLogoMaterials(isDark);
console.log('updateLogoAccessibilityTheme completed successfully'); console.log('updateAllLogoMaterials called after accessibility theme change');
} catch (error) { } catch (error) {
console.error('Error calling updateLogoAccessibilityTheme:', error); console.error('Error calling updateAllLogoMaterials after accessibility change:', error);
} }
} else { } else {
console.warn('updateLogoAccessibilityTheme not available - logo.js may not be loaded yet'); console.warn('updateLogoAccessibilityTheme not available - logo.js may not be loaded yet');

View File

@@ -8,6 +8,7 @@ const logoInstances = new Map();
// Define materials for both themes and accessibility modes // Define materials for both themes and accessibility modes
let darkMaterial, lightMaterial; let darkMaterial, lightMaterial;
let accessibilityMaterials = {}; let accessibilityMaterials = {};
let accessibilityMaterialsDark = {};
// Animation parameters (now in an object for GUI control) // Animation parameters (now in an object for GUI control)
const params = { const params = {
@@ -62,60 +63,113 @@ function createMaterials() {
envMapIntensity: 0.8, envMapIntensity: 0.8,
}); });
// Accessibility materials for different color blindness types // CHORUS 8-Color Accessibility Materials - Matching CSS system
accessibilityMaterials.protanopia = new THREE.MeshPhysicalMaterial({ accessibilityMaterials.protanopia = new THREE.MeshPhysicalMaterial({
color: 0x1e40af, // Blue-800 for protanopia (red-blind) color: 0x2a3441, // ocean-950 (matching --chorus-danger for protanopia)
roughness: 0.26, roughness: 0.26,
metalness: 0.95, metalness: 0.95,
clearcoat: 0.5, clearcoat: 0.5,
clearcoatRoughness: 0.14, clearcoatRoughness: 0.14,
reflectivity: 1.1, reflectivity: 1.1,
sheen: 0.3, sheen: 0.3,
sheenColor: new THREE.Color(0xca8a04), // Yellow-600 sheenColor: new THREE.Color(0x473e2f), // sand-950 (matching --chorus-success for protanopia)
sheenRoughness: 0.18, sheenRoughness: 0.18,
envMapIntensity: 0.9, envMapIntensity: 0.9,
}); });
accessibilityMaterials.deuteranopia = new THREE.MeshPhysicalMaterial({ accessibilityMaterials.deuteranopia = new THREE.MeshPhysicalMaterial({
color: 0x6b21a8, // Purple-800 for deuteranopia (green-blind) color: 0x2a3441, // ocean-950 (matching --chorus-success for deuteranopia)
roughness: 0.25, roughness: 0.25,
metalness: 0.96, metalness: 0.96,
clearcoat: 0.49, clearcoat: 0.49,
clearcoatRoughness: 0.13, clearcoatRoughness: 0.13,
reflectivity: 1.15, reflectivity: 1.15,
sheen: 0.32, sheen: 0.32,
sheenColor: new THREE.Color(0x3b82f6), // Blue-500 sheenColor: new THREE.Color(0x2e1d1c), // coral-950 (matching --chorus-accent for deuteranopia)
sheenRoughness: 0.17, sheenRoughness: 0.17,
envMapIntensity: 0.92, envMapIntensity: 0.92,
}); });
accessibilityMaterials.tritanopia = new THREE.MeshPhysicalMaterial({ accessibilityMaterials.tritanopia = new THREE.MeshPhysicalMaterial({
color: 0x991b1b, // Red-800 for tritanopia (blue-blind) color: 0x2e1d1c, // coral-950 (matching --chorus-info for tritanopia)
roughness: 0.27, roughness: 0.27,
metalness: 0.94, metalness: 0.94,
clearcoat: 0.51, clearcoat: 0.51,
clearcoatRoughness: 0.15, clearcoatRoughness: 0.15,
reflectivity: 1.05, reflectivity: 1.05,
sheen: 0.28, sheen: 0.28,
sheenColor: new THREE.Color(0x16a34a), // Green-600 sheenColor: new THREE.Color(0x2a3330), // eucalyptus-950 (matching --chorus-warning for tritanopia)
sheenRoughness: 0.19, sheenRoughness: 0.19,
envMapIntensity: 0.88, envMapIntensity: 0.88,
}); });
accessibilityMaterials.achromatopsia = new THREE.MeshPhysicalMaterial({ accessibilityMaterials.achromatopsia = new THREE.MeshPhysicalMaterial({
color: 0x374151, // Gray-700 for achromatopsia (complete color blindness) color: 0x111111, // Almost black (matching --chorus-danger for achromatopsia)
roughness: 0.3, roughness: 0.3,
metalness: 0.9, metalness: 0.9,
clearcoat: 0.45, clearcoat: 0.45,
clearcoatRoughness: 0.16, clearcoatRoughness: 0.16,
reflectivity: 1.0, reflectivity: 1.0,
sheen: 0.25, sheen: 0.25,
sheenColor: new THREE.Color(0x6b7280), // Gray-500 sheenColor: new THREE.Color(0x444444), // Dark medium (matching --chorus-info for achromatopsia)
sheenRoughness: 0.2, sheenRoughness: 0.2,
envMapIntensity: 0.85, envMapIntensity: 0.85,
}); });
console.log("Materials created including accessibility variants"); // Create dark mode variants for accessibility materials
accessibilityMaterialsDark.protanopia = new THREE.MeshPhysicalMaterial({
color: 0xcbefff, // ocean-50 (matching dark mode --chorus-danger for protanopia)
roughness: 0.24,
metalness: 1.0,
clearcoat: 0.48,
clearcoatRoughness: 0.15,
reflectivity: 1.2,
sheen: 0.35,
sheenColor: new THREE.Color(0xcee1be), // sand-50 (matching dark mode --chorus-success for protanopia)
sheenRoughness: 0.168,
envMapIntensity: 1,
});
accessibilityMaterialsDark.deuteranopia = new THREE.MeshPhysicalMaterial({
color: 0xcbefff, // ocean-50 (matching dark mode --chorus-success for deuteranopia)
roughness: 0.24,
metalness: 1.0,
clearcoat: 0.48,
clearcoatRoughness: 0.15,
reflectivity: 1.2,
sheen: 0.35,
sheenColor: new THREE.Color(0xffd6d6), // coral-50 (matching dark mode --chorus-accent for deuteranopia)
sheenRoughness: 0.168,
envMapIntensity: 1,
});
accessibilityMaterialsDark.tritanopia = new THREE.MeshPhysicalMaterial({
color: 0xffd6d6, // coral-50 (matching dark mode --chorus-info for tritanopia)
roughness: 0.24,
metalness: 1.0,
clearcoat: 0.48,
clearcoatRoughness: 0.15,
reflectivity: 1.2,
sheen: 0.35,
sheenColor: new THREE.Color(0xbacfbf), // eucalyptus-50 (matching dark mode --chorus-warning for tritanopia)
sheenRoughness: 0.168,
envMapIntensity: 1,
});
accessibilityMaterialsDark.achromatopsia = new THREE.MeshPhysicalMaterial({
color: 0xeeeeee, // Almost white (matching dark mode --chorus-danger for achromatopsia)
roughness: 0.24,
metalness: 1.0,
clearcoat: 0.48,
clearcoatRoughness: 0.15,
reflectivity: 1.2,
sheen: 0.35,
sheenColor: new THREE.Color(0xbbbbbb), // Light medium (matching dark mode --chorus-info for achromatopsia)
sheenRoughness: 0.168,
envMapIntensity: 1,
});
console.log("Materials created including accessibility variants and dark mode variants");
} }
function initLogo(canvas) { function initLogo(canvas) {
@@ -257,16 +311,27 @@ function initLogo(canvas) {
function updateCanvasMaterial(mobius, isDark) { function updateCanvasMaterial(mobius, isDark) {
if (mobius) { if (mobius) {
// Check for accessibility theme first // Check for accessibility theme first (both data-theme for legacy and data-accessibility for new system)
const accessibilityTheme = document.documentElement.getAttribute('data-theme'); const accessibilityTheme = document.documentElement.getAttribute('data-accessibility') ||
document.documentElement.getAttribute('data-theme');
let targetMaterial; let targetMaterial;
if (accessibilityTheme && accessibilityMaterials[accessibilityTheme]) { if (accessibilityTheme && accessibilityTheme !== 'standard') {
targetMaterial = accessibilityMaterials[accessibilityTheme]; // Choose accessibility material based on light/dark mode
console.log(`Updating material to accessibility theme: ${accessibilityTheme}`); const accessibilityMaterialSet = isDark ? accessibilityMaterialsDark : accessibilityMaterials;
if (accessibilityMaterialSet[accessibilityTheme]) {
targetMaterial = accessibilityMaterialSet[accessibilityTheme];
console.log(`Updating material to ${isDark ? 'dark' : 'light'} accessibility theme: ${accessibilityTheme}`);
} else { } else {
// Fallback to standard materials
targetMaterial = isDark ? darkMaterial : lightMaterial; targetMaterial = isDark ? darkMaterial : lightMaterial;
console.log(`Updating material to:`, isDark ? 'dark' : 'light', 'material color:', targetMaterial.color.getHex().toString(16)); console.log(`Accessibility material not found for ${accessibilityTheme}, using standard ${isDark ? 'dark' : 'light'} material`);
}
} else {
// Standard materials
targetMaterial = isDark ? darkMaterial : lightMaterial;
console.log(`Updating material to standard:`, isDark ? 'dark' : 'light', 'material color:', targetMaterial.color.getHex().toString(16));
} }
let meshCount = 0; let meshCount = 0;