feat: Add comprehensive iconography system and enhance brand guidelines

- Add complete Iconography section with Coolicons v4.1 integration
- Implement theme-adaptive icons (black for light mode, white for dark mode)
- Add Visual Aid modal dialog for accessibility settings
- Replace theme toggle with semantic moon/sun icons
- Add personality trait icons with appropriate semantic choices
- Fix code block theming to respect light/dark mode toggle
- Include comprehensive icon categories: Interface, File/Data, Communication, Navigation
- Add detailed implementation guides for HTML, SVG, and Tailwind
- Create accessibility-aware color system with vision deficiency support
- Add Inconsolata and Inter Tight fonts for complete typography system

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
tony
2025-08-20 16:49:53 +10:00
parent 4511f4c801
commit ba0e8c84ae
3749 changed files with 24003 additions and 1760 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -113,7 +113,7 @@ Each component logo follows the pattern: **Component Icon + CHORUS Brand Mark**
- Position: Baseline aligned with bottom of CHORUS, or centered vertically
### Color Values
```css
css
/* Primary Brand Colors */
--logo-primary-text: #F5F5DC; /* Natural Paper */
--logo-secondary-text: #C0C0C0; /* Brushed Aluminum */
@@ -124,7 +124,7 @@ Each component logo follows the pattern: **Component Icon + CHORUS Brand Mark**
--logo-primary-text-rev: #000000; /* Carbon Black */
--logo-secondary-text-rev: #8B4513; /* Walnut Brown */
--logo-background-light: #F5F5DC; /* Natural Paper */
```
## Usage Guidelines
@@ -202,4 +202,4 @@ Each component logo follows the pattern: **Component Icon + CHORUS Brand Mark**
- **Social Media**: PNG at platform-specific dimensions
- **App Icons**: PNG at required iOS/Android specifications
This logo concept provides CHORUS Services with a sophisticated, scalable visual identity that reflects the platform's technical capabilities while maintaining the premium, approachable aesthetic required for enterprise clients.
This logo concept provides CHORUS Services with a sophisticated, scalable visual identity that reflects the platform's technical capabilities while maintaining the premium, approachable aesthetic required for enterprise clients.

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

View File

@@ -135,30 +135,30 @@ The CHORUS component logo system creates visual harmony between the main brand a
### Combined Logo Layouts
#### Horizontal Integration
```
[Component Icon] COMPONENT NAME → [CHORUS Icon] CHORUS
powered by
```
- **Use Case**: Marketing materials, business cards, letterhead
- **Spacing**: Component and CHORUS sections separated by 2x the x-height
- **Hierarchy**: Component name 100%, CHORUS name 70%, "powered by" 40%
#### Vertical Integration
```
[Component Icon]
COMPONENT NAME
[CHORUS Icon]
CHORUS Services
```
- **Use Case**: Vertical layouts, mobile applications, square formats
- **Spacing**: Consistent vertical rhythm based on typography line-height
- **Connection**: Subtle arrow or connection line between icons
#### Compact Integration
```
[Component Icon][CHORUS Icon] COMPONENT × CHORUS
```
- **Use Case**: Favicons, app icons, tight space applications
- **Treatment**: Icons side-by-side with minimal separation
- **Typography**: Single line with multiplication symbol (×) or plus (+)
@@ -199,7 +199,7 @@ CHORUS Services
## Technical Implementation
### SVG Structure Template
```svg
svg
<svg viewBox="0 0 240 60" xmlns="http://www.w3.org/2000/svg">
<!-- Component Icon -->
<g id="component-icon" transform="translate(0,0)">
@@ -220,10 +220,10 @@ CHORUS Services
<text id="component-name" x="0" y="45" class="component-text">COMPONENT</text>
<text id="chorus-name" x="160" y="45" class="chorus-text">CHORUS</text>
</svg>
```
### CSS Integration Classes
```css
css
.component-logo {
display: inline-flex;
align-items: center;
@@ -248,7 +248,7 @@ CHORUS Services
font-size: var(--text-size, 18px);
color: var(--text-color);
}
```
## Brand Protection Guidelines

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,238 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>CHORUS</title>
<style>
body { margin: 0; overflow: hidden; background-color: #5E6367; }
canvas { display: block; }
</style>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Exo:ital,wght@0,100..900;1,100..900&family=Luckiest+Guy&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/",
"lil-gui": "https://cdn.jsdelivr.net/npm/lil-gui@0.19/+esm"
}
}
</script>
</head>
<body>
<script type="module">
import GUI from 'lil-gui';
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
// Initialize CSS2DRenderer
const labelRenderer = new CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0px';
labelRenderer.domElement.style.pointerEvents = 'none'; // allows clicks to pass through
document.body.appendChild(labelRenderer.domElement);
// === Animation parameters ===
const spinSpeed = 0.003; // radians per frame
// Animation parameters (now in an object for GUI control)
const params = {
spinSpeedX: 0.01, // continuous X spin
spinSpeedY: 0.01, // continuous X spin
spinSpeedZ: 0.1, // continuous Z spin
lightCount: 25,
};
let scene, camera, renderer, mobius, clock;
let baseRotationY = 0;
init();
animate();
function init() {
scene = new THREE.Scene();
const material = new THREE.MeshPhysicalMaterial({
color: 0xFFFFFF,
roughness: 0.24,
metalness: 1.0,
clearcoat: 0.48,
clearcoatRoughness: 0.15,
reflectivity: 1.2,
sheen: 0.35,
sheenColor: new THREE.Color(0x212121),
sheenRoughness: 0.168,
envMapIntensity: 1,
});
// Add scattered lights
addRandomLights();
// Generate a synthetic cube environment
const size = 512;
const canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
const ctx = canvas.getContext('2d');
// Gradient: sunset horizon (bottom warm, top cool)
const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0, '#001133'); // top dark blue
gradient.addColorStop(0.4, '#223366'); // mid blue
gradient.addColorStop(0.5, '#ff8844'); // orange near horizon
gradient.addColorStop(0.51, '#000000'); // black horizon
gradient.addColorStop(0.8, '#105010'); // green base
gradient.addColorStop(1, '#000000'); // black base
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
const texture = new THREE.CanvasTexture(canvas);
texture.mapping = THREE.EquirectangularReflectionMapping;
// Apply as environment
scene.environment = texture;
scene.background = null; // keep transparent
function expandGradient(img) {
const canvas = document.createElement('canvas');
const w = 512, h = 256; // safe HDRI-like size
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext('2d');
// Stretch the 1px-wide strip to fill the canvas
ctx.drawImage(img, 0, 0, w, h);
return new THREE.CanvasTexture(canvas);
}
const envloader = new THREE.ImageLoader();
envloader.load('horizon-gradient.png', (image) => {
const tex = expandGradient(image);
tex.mapping = THREE.EquirectangularReflectionMapping;
// ✅ safe to feed into PMREM
const pmrem = new THREE.PMREMGenerator(renderer);
const envMap = pmrem.fromEquirectangular(tex).texture;
scene.environment = envMap;
});
const textDiv = document.createElement('div');
textDiv.textContent = "CHORUS";
textDiv.style.color = "#FFFFFF";
textDiv.style.fontSize = "96px";
textDiv.style.fontFamily = "Exo, sans-serif";
textDiv.style.textAlign = "left";
// Create CSS2DObject and position it at the origin
const textLabel = new CSS2DObject(textDiv);
textLabel.position.set(0, 0, 0); // exact origin
scene.add(textLabel);
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 100);
camera.position.set(0, 0, 1.8);
camera.lookAt(0, 0, 0);
const light = new THREE.PointLight(0xffffff, 1.4);
light.position.set(0, 4, 1);
scene.add(light);
const bottomLight = new THREE.PointLight(0x800080, 1.2, 12); // (color, intensity, distance)
bottomLight.position.set(0, -4, 1); // directly under the model
scene.add(bottomLight);
const leftLight = new THREE.PointLight(0x808000, 1.45, 5); // (color, intensity, distance)
leftLight.position.set(-5, 0, 4); // top left of the model
scene.add(leftLight);
scene.add(new THREE.AmbientLight(0xffffff, 0.45));
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( 'https://www.gstatic.com/draco/v1/decoders/' );
loader.setDRACOLoader( dracoLoader );
loader.load(
"./mobius-ring.glb", // ensure mobius.glb is in the same folder as this HTML
(gltf) => {
mobius = gltf.scene;
mobius.traverse((child) => {
if (child.isMesh) {
child.material = material;
}
});
scene.add(mobius);
},
undefined,
(err) => console.error("Error loading model:", err)
);
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x000000, 0); // transparent background
document.body.appendChild(renderer.domElement);
clock = new THREE.Clock();
window.addEventListener("resize", onWindowResize);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
if (mobius) {
const elapsed = clock.getElapsedTime();
// Continuous spin
mobius.rotation.x += params.spinSpeedX;
mobius.rotation.y += params.spinSpeedY;
mobius.rotation.z += params.spinSpeedZ;
}
renderer.render(scene, camera);
labelRenderer.render(scene, camera);
}
function addRandomLights() {
for (let i = 0; i < params.lightCount; i++) {
const color = new THREE.Color().setHSL(Math.random(), 0.84, 0.9);
const light = new THREE.PointLight(color, params.lightIntensity, params.lightDistance);
const angle = Math.random() * Math.PI * 2;
const height = (Math.random() - 0.5) * 4;
const radius = 6 + Math.random() * 4;
light.position.set(Math.cos(angle) * radius, height, Math.sin(angle) * radius);
scene.add(light);
}
}
</script>
</body>
</html>

View File

@@ -148,7 +148,7 @@ This document provides comprehensive specifications for all CHORUS Services logo
## Technical Implementation Specifications
### SVG Code Structure
```svg
svg
<svg viewBox="0 0 240 60" xmlns="http://www.w3.org/2000/svg" aria-labelledby="chorus-logo-title">
<title id="chorus-logo-title">CHORUS Services Logo</title>
@@ -163,10 +163,10 @@ This document provides comprehensive specifications for all CHORUS Services logo
<text x="80" y="50" font-family="-apple-system, SF Pro Text" font-weight="400" font-size="10" fill="#C0C0C0">Services</text>
</g>
</svg>
```
### CSS Implementation
```css
css
.chorus-logo {
display: inline-block;
max-width: 100%;
@@ -194,16 +194,16 @@ This document provides comprehensive specifications for all CHORUS Services logo
min-width: 100px;
}
}
```
### File Naming Convention
```
chorus-logo-horizontal-color.svg
chorus-logo-horizontal-reversed.svg
chorus-logo-stacked-color.png
chorus-logo-icon-only-white.svg
chorus-logo-monochrome-black.pdf
```
## Quality Assurance Checklist

View File

@@ -0,0 +1,245 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>CHORUS Möbius Strip</title>
<style>
body { margin: 0; overflow: hidden; background-color: #0b0213; }
canvas { display: block; }
</style>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Exo:ital,wght@0,100..900;1,100..900&family=Luckiest+Guy&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/",
"lil-gui": "https://cdn.jsdelivr.net/npm/lil-gui@0.19/+esm"
}
}
</script>
</head>
<body>
<script type="module">
import GUI from 'lil-gui';
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
// Initialize CSS2DRenderer
const labelRenderer = new CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0px';
labelRenderer.domElement.style.pointerEvents = 'none'; // allows clicks to pass through
document.body.appendChild(labelRenderer.domElement);
// === Animation parameters ===
const spinSpeed = 0.003; // radians per frame
// Animation parameters (now in an object for GUI control)
const params = {
spinSpeedX: 0.010, // continuous X spin
spinSpeedY: -0.010, // continuous X spin
spinSpeedZ: -0.1, // continuous Z spin
lightCount: 25,
};
let scene, camera, renderer, mobius, clock;
let baseRotationY = 0;
// Setup lil-gui
// const gui = new GUI();
// gui.add(params, 'spinSpeedX', -0.2, 0.2).step(0.001).name('X Spin Speed');
// gui.add(params, 'spinSpeedY', -0.2, 0.2).step(0.001).name('Y Spin Speed');
// gui.add(params, 'spinSpeedZ', -0.2, 0.2).step(0.001).name('Z Spin Speed');
init();
animate();
function init() {
scene = new THREE.Scene();
const material = new THREE.MeshPhysicalMaterial({
color: 0x333333,
roughness: 0.24,
metalness: 1.0,
clearcoat: 0.48,
clearcoatRoughness: 0.15,
reflectivity: 1.2,
sheen: 0.35,
sheenColor: new THREE.Color(0x212121),
sheenRoughness: 0.168,
envMapIntensity: 1,
});
// Add scattered lights
addRandomLights();
// Generate a synthetic cube environment
const size = 512;
const canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
const ctx = canvas.getContext('2d');
// Gradient: sunset horizon (bottom warm, top cool)
const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0, '#001133'); // top dark blue
gradient.addColorStop(0.4, '#223366'); // mid blue
gradient.addColorStop(0.5, '#ff8844'); // orange near horizon
gradient.addColorStop(0.51, '#000000'); // black horizon
gradient.addColorStop(0.8, '#105010'); // green base
gradient.addColorStop(1, '#000000'); // black base
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
const texture = new THREE.CanvasTexture(canvas);
texture.mapping = THREE.EquirectangularReflectionMapping;
// Apply as environment
scene.environment = texture;
scene.background = null; // keep transparent
function expandGradient(img) {
const canvas = document.createElement('canvas');
const w = 512, h = 256; // safe HDRI-like size
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext('2d');
// Stretch the 1px-wide strip to fill the canvas
ctx.drawImage(img, 0, 0, w, h);
return new THREE.CanvasTexture(canvas);
}
const envloader = new THREE.ImageLoader();
envloader.load('horizon-gradient.png', (image) => {
const tex = expandGradient(image);
tex.mapping = THREE.EquirectangularReflectionMapping;
// ✅ safe to feed into PMREM
const pmrem = new THREE.PMREMGenerator(renderer);
const envMap = pmrem.fromEquirectangular(tex).texture;
scene.environment = envMap;
});
const textDiv = document.createElement('div');
textDiv.textContent = "CHORUS";
textDiv.style.color = "#ffffff";
textDiv.style.fontSize = "96px";
textDiv.style.fontFamily = "Exo, sans-serif";
textDiv.style.textAlign = "center";
// Create CSS2DObject and position it at the origin
const textLabel = new CSS2DObject(textDiv);
textLabel.position.set(0, 0, 0); // exact origin
scene.add(textLabel);
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 100);
camera.position.set(0, 0, 1.8);
camera.lookAt(0, 0, 0);
const light = new THREE.PointLight(0xffffff, 1.4);
light.position.set(0, 4, 1);
scene.add(light);
const bottomLight = new THREE.PointLight(0x800080, 1.2, 12); // (color, intensity, distance)
bottomLight.position.set(0, -4, 1); // directly under the model
scene.add(bottomLight);
const leftLight = new THREE.PointLight(0x808000, 1.45, 5); // (color, intensity, distance)
leftLight.position.set(-5, 0, 4); // top left of the model
scene.add(leftLight);
scene.add(new THREE.AmbientLight(0xffffff, 0.45));
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( 'https://www.gstatic.com/draco/v1/decoders/' );
loader.setDRACOLoader( dracoLoader );
loader.load(
"./mobius-ring.glb", // ensure mobius.glb is in the same folder as this HTML
(gltf) => {
mobius = gltf.scene;
mobius.traverse((child) => {
if (child.isMesh) {
child.material = material;
}
});
scene.add(mobius);
},
undefined,
(err) => console.error("Error loading model:", err)
);
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x000000, 0); // transparent background
document.body.appendChild(renderer.domElement);
clock = new THREE.Clock();
window.addEventListener("resize", onWindowResize);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
if (mobius) {
const elapsed = clock.getElapsedTime();
// Continuous spin
mobius.rotation.x += params.spinSpeedX;
mobius.rotation.y += params.spinSpeedY;
mobius.rotation.z += params.spinSpeedZ;
}
renderer.render(scene, camera);
labelRenderer.render(scene, camera);
}
function addRandomLights() {
for (let i = 0; i < params.lightCount; i++) {
const color = new THREE.Color().setHSL(Math.random(), 0.84, 0.9);
const light = new THREE.PointLight(color, params.lightIntensity, params.lightDistance);
const angle = Math.random() * Math.PI * 2;
const height = (Math.random() - 0.5) * 4;
const radius = 6 + Math.random() * 4;
light.position.set(Math.cos(angle) * radius, height, Math.sin(angle) * radius);
scene.add(light);
}
}
</script>
</body>
</html>

BIN
brand-assets/logos/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.