Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 55 additions & 78 deletions .claude/skills/design-system/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,84 @@
---
name: ckm:design-system
description: Token architecture, component specifications, and slide generation. Three-layer tokens (primitive→semantic→component), CSS variables, spacing/typography scales, component specs, strategic slide creation. Use for design tokens, systematic design, brand-compliant presentations.
name: andritz-design-system
description: Andritz Precision industrial design system with dark/light theme variants. Three-layer token architecture (primitive→semantic→component), Material Design surface hierarchy, sharp 0px corners, tonal layering, industrial component specifications, and slide generation.
argument-hint: "[component or token]"
license: MIT
metadata:
author: claudekit
version: "1.0.0"
version: "2.0.0"
---

# Design System
# Andritz Design System

Token architecture, component specifications, systematic design, slide generation.
Industrial precision design system based on the **"Monolithic Engine"** creative north star — solid, authoritative, deeply layered. Supports dark/light theme variants via Material Design surface hierarchy.

## When to Use

- Design token creation
- Component state definitions
- CSS variable systems
- Spacing/typography scales
- Design-to-code handoff
- Tailwind theme configuration
- Andritz-branded UI development
- Industrial dashboard and command center design
- Dark/light theme implementation via surface hierarchy
- Material Design token systems with tonal layering
- Sharp-corner (0px radius) component systems
- Data-heavy layouts with zone-based organization
- **Slide/presentation generation**

## Andritz Key Colors

### Light Theme
- Surface: `#f8fafb` | Primary: `#0075be` / `#005c97` | On-surface: `#191c1d`

### Dark Theme
- Surface: `#10141a` | Primary: `#9bcaff` / `#0075be` | On-surface: `#dfe2eb`

## Token Architecture

Load: `references/token-architecture.md`

### Three-Layer Structure

```
Primitive (raw values)
Primitive (Andritz raw values)
Semantic (purpose aliases)
Semantic (surface hierarchy + purpose aliases)
Component (component-specific)
Component (industrial component tokens)
```

**Example:**
```css
/* Primitive */
--color-blue-600: #2563EB;
--andritz-blue-500: #0075be;

/* Semantic */
--color-primary: var(--color-blue-600);
--color-primary: var(--andritz-blue-500);

/* Component */
--button-bg: var(--color-primary);
--button-bg: linear-gradient(135deg, var(--color-primary-text), var(--color-primary));
```

## Quick Start

**Generate tokens:**
```bash
node scripts/generate-tokens.cjs --config tokens.json -o tokens.css
node scripts/generate-tokens.cjs --config templates/design-tokens-starter.json -o assets/design-tokens.css
```

**Validate usage:**
```bash
node scripts/validate-tokens.cjs --dir src/
```

**Use in slides/HTML:**
```html
<link rel="stylesheet" href="assets/design-tokens.css">
<link rel="stylesheet" href="assets/css/slide-animations.css">
```

## References

| Topic | File |
|-------|------|
| Design Philosophy | `references/design-philosophy.md` |
| Token Architecture | `references/token-architecture.md` |
| Primitive Tokens | `references/primitive-tokens.md` |
| Semantic Tokens | `references/semantic-tokens.md` |
Expand All @@ -76,10 +91,11 @@ node scripts/validate-tokens.cjs --dir src/

| Property | Default | Hover | Active | Disabled |
|----------|---------|-------|--------|----------|
| Background | primary | primary-dark | primary-darker | muted |
| Text | white | white | white | muted-fg |
| Border | none | none | none | muted-border |
| Shadow | sm | md | none | none |
| Background | gradient(primary) | tonal-shift | scale-98% | surface-muted |
| Text | on-primary | on-primary | on-primary | on-surface-variant |
| Border | none | none | none | ghost-border |
| Shadow | none | none | none | none |
| Radius | 0px | 0px | 0px | 0px |

## Scripts

Expand All @@ -95,12 +111,12 @@ node scripts/validate-tokens.cjs --dir src/

| Template | Purpose |
|----------|---------|
| `design-tokens-starter.json` | Starter JSON with three-layer structure |
| `design-tokens-starter.json` | Andritz three-layer token starter |

## Integration

**With brand:** Extract primitives from brand colors/typography
**With ui-styling:** Component tokens → Tailwind config
**With brand:** Extract primitives from Andritz brand colors/typography
**With ui-styling:** Component tokens → Tailwind config with 0px radius

**Skill Dependencies:** brand, ui-styling
**Primary Agents:** ui-ux-designer, frontend-developer
Expand Down Expand Up @@ -146,34 +162,6 @@ python scripts/search-slides.py "cta" --context --position 9 --prev-emotion frus
| `data/slide-copy.csv` | 25 copywriting formulas (PAS, AIDA, FAB) |
| `data/slide-charts.csv` | 25 chart types with Chart.js config |

### Contextual Decision Flow

```
1. Parse goal/context
2. Search slide-strategies.csv → Get strategy + emotion beats
3. For each slide:
a. Query slide-layout-logic.csv → layout + break_pattern
b. Query slide-typography.csv → type scale
c. Query slide-color-logic.csv → color treatment
d. Query slide-backgrounds.csv → image if needed
e. Apply animation class from slide-animations.css
4. Generate HTML with design tokens
5. Validate with slide-token-validator.py
```

### Pattern Breaking (Duarte Sparkline)

Premium decks alternate between emotions for engagement:
```
"What Is" (frustration) ↔ "What Could Be" (hope)
```

System calculates pattern breaks at 1/3 and 2/3 positions.

### Slide Requirements

**ALL slides MUST:**
Expand All @@ -197,8 +185,8 @@ new Chart(document.getElementById('revenueChart'), {
labels: ['Sep', 'Oct', 'Nov', 'Dec'],
datasets: [{
data: [5, 12, 28, 45],
borderColor: '#FF6B6B', // Use brand coral
backgroundColor: 'rgba(255, 107, 107, 0.1)',
borderColor: 'var(--color-primary)',
backgroundColor: 'rgba(0, 117, 190, 0.1)',
fill: true,
tension: 0.4
}]
Expand All @@ -210,35 +198,24 @@ new Chart(document.getElementById('revenueChart'), {
### Token Compliance

```css
/* CORRECT - uses token */
background: var(--slide-bg);
/* CORRECT - uses Andritz token */
background: var(--color-surface);
color: var(--color-primary);
font-family: var(--typography-font-heading);
font-family: var(--font-family-primary);
border-radius: 0px;

/* WRONG - hardcoded */
background: #0D0D0D;
color: #FF6B6B;
font-family: 'Space Grotesk';
```

### Reference Implementation

Working example with all features:
```
assets/designs/slides/claudekit-pitch-251223.html
```

### Command

```bash
/slides:create "10-slide investor pitch for ClaudeKit Marketing"
background: #f8fafb;
color: #0075be;
font-family: 'Inter';
border-radius: 0.5rem;
```

## Best Practices

1. Never use raw hex in components - always reference tokens
2. Semantic layer enables theme switching (light/dark)
3. Component tokens enable per-component customization
4. Use HSL format for opacity control
1. Never use border-radius — 0px is the Andritz rule, no exceptions
2. Use tonal layering (surface hierarchy) instead of borders — No-Line Rule
3. Semantic layer enables light/dark theme switching via surface hierarchy
4. Component tokens enable per-component customization
5. Document every token's purpose
6. **Slides must import design-tokens.css and use var() exclusively**
159 changes: 159 additions & 0 deletions .claude/skills/design-system/assets/css/slide-animations.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/* Andritz Precision — Slide Animation Library */
/* Industrial motion: deliberate, mechanical, precise */

/* === ENTRANCE ANIMATIONS === */

@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}

@keyframes fadeInUp {
from { opacity: 0; transform: translateY(24px); }
to { opacity: 1; transform: translateY(0); }
}

@keyframes fadeInDown {
from { opacity: 0; transform: translateY(-24px); }
to { opacity: 1; transform: translateY(0); }
}

@keyframes fadeInLeft {
from { opacity: 0; transform: translateX(-32px); }
to { opacity: 1; transform: translateX(0); }
}

@keyframes fadeInRight {
from { opacity: 0; transform: translateX(32px); }
to { opacity: 1; transform: translateX(0); }
}

@keyframes scaleIn {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}

/* === SLIDE TRANSITIONS === */

@keyframes slideInRight {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}

@keyframes slideInLeft {
from { transform: translateX(-100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}

@keyframes slideOutLeft {
from { transform: translateX(0); opacity: 1; }
to { transform: translateX(-100%); opacity: 0; }
}

@keyframes slideOutRight {
from { transform: translateX(0); opacity: 1; }
to { transform: translateX(100%); opacity: 0; }
}

/* === INDUSTRIAL EFFECTS === */

/* Precision reveal — content appears with a mechanical wipe */
@keyframes wipeReveal {
from { clip-path: inset(0 100% 0 0); }
to { clip-path: inset(0 0 0 0); }
}

/* Bottom-up reveal — like a gauge filling */
@keyframes fillReveal {
from { clip-path: inset(100% 0 0 0); }
to { clip-path: inset(0 0 0 0); }
}

/* Pulse line glow — dark theme data highlight */
@keyframes pulseGlow {
0%, 100% { box-shadow: 0px 0px 8px rgba(155, 202, 255, 0.4); }
50% { box-shadow: 0px 0px 16px rgba(155, 202, 255, 0.7); }
}

/* Number counter effect — for KPI reveals */
@keyframes countUp {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}

/* Stagger delay utility for child elements */
@keyframes staggerFadeIn {
from { opacity: 0; transform: translateY(16px); }
to { opacity: 1; transform: translateY(0); }
}

/* === CHART ANIMATIONS === */

@keyframes drawLine {
from { stroke-dashoffset: 1000; }
to { stroke-dashoffset: 0; }
}

@keyframes barGrow {
from { transform: scaleY(0); transform-origin: bottom; }
to { transform: scaleY(1); transform-origin: bottom; }
}

@keyframes pieReveal {
from { stroke-dashoffset: 314; }
to { stroke-dashoffset: 0; }
}

/* === UTILITY CLASSES === */

.animate-fade-in { animation: fadeIn 300ms ease-out both; }
.animate-fade-in-up { animation: fadeInUp 300ms ease-out both; }
.animate-fade-in-down { animation: fadeInDown 300ms ease-out both; }
.animate-fade-in-left { animation: fadeInLeft 300ms ease-out both; }
.animate-fade-in-right { animation: fadeInRight 300ms ease-out both; }
.animate-scale-in { animation: scaleIn 300ms ease-out both; }
.animate-wipe-reveal { animation: wipeReveal 500ms ease-in-out both; }
.animate-fill-reveal { animation: fillReveal 500ms ease-in-out both; }
.animate-pulse-glow { animation: pulseGlow 2s ease-in-out infinite; }

/* Slide transition classes */
.slide-enter { animation: slideInRight 300ms ease-out both; }
.slide-enter-reverse { animation: slideInLeft 300ms ease-out both; }
.slide-exit { animation: slideOutLeft 300ms ease-out both; }
.slide-exit-reverse { animation: slideOutRight 300ms ease-out both; }

/* Stagger children — apply to parent, children auto-stagger */
.stagger-children > * {
animation: staggerFadeIn 300ms ease-out both;
}
.stagger-children > *:nth-child(1) { animation-delay: 0ms; }
.stagger-children > *:nth-child(2) { animation-delay: 80ms; }
.stagger-children > *:nth-child(3) { animation-delay: 160ms; }
.stagger-children > *:nth-child(4) { animation-delay: 240ms; }
.stagger-children > *:nth-child(5) { animation-delay: 320ms; }
.stagger-children > *:nth-child(6) { animation-delay: 400ms; }
.stagger-children > *:nth-child(7) { animation-delay: 480ms; }
.stagger-children > *:nth-child(8) { animation-delay: 560ms; }

/* Delay modifiers */
.delay-100 { animation-delay: 100ms; }
.delay-200 { animation-delay: 200ms; }
.delay-300 { animation-delay: 300ms; }
.delay-400 { animation-delay: 400ms; }
.delay-500 { animation-delay: 500ms; }
.delay-600 { animation-delay: 600ms; }

/* Duration modifiers */
.duration-fast { animation-duration: 150ms; }
.duration-normal { animation-duration: 300ms; }
.duration-slow { animation-duration: 500ms; }

/* === REDUCED MOTION === */

@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Loading