Series: Gestalt Color System - Core and Flow
Copy
╔═══════════════════════════════════════════════════════════════════════════════╗
│ │
│ DECISION FLOW: WHEN CORE, WHEN FLOW? │
│ │
│ A Comprehensive Guide to Choosing Between Core and Flow Colors │
│ The Definitive Flowchart for Color System Decisions │
│ │
╚═══════════════════════════════════════════════════════════════════════════════╝
The Fundamental Question
Core and Flow Philosophy
Before making any color decision, understand the foundational principle:Copy
┌─────────────────────────────────────────────────────────────────────────────────┐
│ CORE & FLOW PHILOSOPHY │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ╔═══════════════════════════════════════════════════════════════════════════╗ │
│ ║ ║ │
│ ║ "Core Colors define identity. Flow Colors handle everything in between." ║ │
│ ║ ║ │
│ ╚═══════════════════════════════════════════════════════════════════════════╝ │
│ │
│ CORE = Identity FLOW = Transition │
│ ═══════════════ ════════════════ │
│ │
│ * What IS this element? * How does this element BEHAVE? │
│ * What category does it belong to? * What state is it in? │
│ * What does it represent? * How does it relate to others? │
│ │
│ Examples: Examples: │
│ * "This is a TypeScript file" * "This button is being hovered" │
│ * "This is Agent #3" * "This is 20% opacity of primary" │
│ * "This is a success state" * "This is between green and blue" │
│ │
│ Technical: Technical: │
│ * oklch(L% C H) * color-mix(in oklab, ...) │
│ * Direct definition * Derived from Core │
│ * Hue specifies identity * Transparency, lightness shifts │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
The Master Decision Tree
Central Decision Flowchart
Copy
┌─────────────────────────────────────────────────────────────────────────────────┐
│ MASTER DECISION FLOWCHART │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────┐ │
│ │ "I need a color" │ │
│ └──────────┬───────────┘ │
│ │ │
│ v │
│ ┌───────────────────────────────────┐ │
│ │ Does this color represent │ │
│ │ a unique IDENTITY? │ │
│ │ │ │
│ │ Ask: "What IS this element?" │ │
│ └───────────────┬───────────────────┘ │
│ │ │
│ ┌─────────────────────┴─────────────────────┐ │
│ │ │ │
│ v YES v NO │
│ ┌──────────────────────────┐ ┌─────────────────────────────┐ │
│ │ │ │ │ │
│ │ ╔════════════════════╗ │ │ Is it derived from an │ │
│ │ ║ USE CORE ║ │ │ existing identity color? │ │
│ │ ║ (OKLCH) ║ │ │ │ │
│ │ ╚════════════════════╝ │ │ Ask: "What state/variation │ │
│ │ │ │ of Core is this?" │ │
│ │ oklch(L% C H) │ └─────────────┬───────────────┘ │
│ │ │ │ │
│ └──────────────────────────┘ ┌─────────────┴─────────────┐ │
│ │ │ │ │
│ v YES │ v NO │
│ ┌───────────────────┐ │ ┌───────────────┐│
│ │ │ │ │ ││
│ │ ╔═══════════════╗ │ │ │ Create new ││
│ │ ║ USE FLOW ║ │ │ │ CORE COLOR ││
│ │ ║ (OKLAB) ║ │ │ │ ││
│ │ ╚═══════════════╝ │ │ │ --> Define ││
│ │ │ │ │ oklch() ││
│ │ color-mix(in │ │ │ ││
│ │ oklab, ...) │ │ └───────────────┘│
│ └───────────────────┘ │ │ │
│ │ │ │ │
│ └───────────────┴───────────┘ │
│ │ │
│ v │
│ ┌───────────────────────┐ │
│ │ All colors trace │ │
│ │ back to a Core Color │ │
│ │ (SEED principle) │ │
│ └───────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Identity Detection Criteria
What Makes Something an Identity?
Copy
┌─────────────────────────────────────────────────────────────────────────────────┐
│ IDENTITY DETECTION CHECKLIST │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ Ask these questions to determine if something needs a CORE COLOR: │
│ │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ QUESTION │ CORE if YES │ FLOW if NO │ │
│ ├────────────────────────────────────────┼─────────────┼───────────────┤ │
│ │ Does it have a unique category? │ V │ │ │
│ │ (file type, user role, entity type) │ │ │ │
│ ├────────────────────────────────────────┼─────────────┼───────────────┤ │
│ │ Is it always this color when visible? │ V │ │ │
│ │ (regardless of state) │ │ │ │
│ ├────────────────────────────────────────┼─────────────┼───────────────┤ │
│ │ Does changing its color change its │ V │ │ │
│ │ meaning? (semantic meaning) │ │ │ │
│ ├────────────────────────────────────────┼─────────────┼───────────────┤ │
│ │ Is it a brand color? │ V │ │ │
│ ├────────────────────────────────────────┼─────────────┼───────────────┤ │
│ │ Is this the "resting state" color? │ V │ │ │
│ │ (default appearance) │ │ │ │
│ ├────────────────────────────────────────┼─────────────┼───────────────┤ │
│ │ Would users recognize this element │ V │ │ │
│ │ BY this color? │ │ │ │
│ └────────────────────────────────────────┴─────────────┴───────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Identity Examples
Copy
┌─────────────────────────────────────────────────────────────────────────────────┐
│ IDENTITY EXAMPLES (CORE COLORS) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ├── File Type Identity ───────────────────────────────────────────────────┐ │
│ │ │ │
│ │ .ts (TypeScript) --> Blue (230) --> oklch(55% 0.15 230) │ │
│ │ .py (Python) --> Green (130) --> oklch(55% 0.15 130) │ │
│ │ .rs (Rust) --> Orange (35) --> oklch(55% 0.15 35) │ │
│ │ .go (Go) --> Cyan (195) --> oklch(55% 0.15 195) │ │
│ │ │ │
│ │ "That blue badge means TypeScript" = identity recognition │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ ├── Semantic Identity ────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Success --> Green (130) --> oklch(55% 0.15 130) │ │
│ │ Warning --> Yellow (85) --> oklch(65% 0.15 85) │ │
│ │ Danger --> Red (25) --> oklch(55% 0.18 25) │ │
│ │ Info --> Blue (230) --> oklch(55% 0.12 230) │ │
│ │ │ │
│ │ "Red means error, green means success" = semantic recognition │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ ├── Agent Identity (Golden Angle Distribution) ───────────────────────────┐ │
│ │ │ │
│ │ Agent #1 --> 27.5 --> oklch(55% 0.15 27.5) │ │
│ │ Agent #2 --> 55 --> oklch(55% 0.15 55) │ │
│ │ Agent #3 --> 82.5 --> oklch(55% 0.15 82.5) │ │
│ │ │ │
│ │ "That's the yellow agent" = Agent #3 identified by color │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Derivation Detection Criteria
What Makes Something a Derivation?
Copy
┌─────────────────────────────────────────────────────────────────────────────────┐
│ DERIVATION DETECTION CHECKLIST │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ Ask these questions to determine if something needs a FLOW COLOR: │
│ │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ QUESTION │ FLOW if YES │ CORE if NO │ │
│ ├────────────────────────────────────────┼─────────────┼───────────────┤ │
│ │ Is this a state variation? │ V │ │ │
│ │ (hover, active, focus, disabled) │ │ │ │
│ ├────────────────────────────────────────┼─────────────┼───────────────┤ │
│ │ Is this a transparency level? │ V │ │ │
│ │ (overlay, background tint) │ │ │ │
│ ├────────────────────────────────────────┼─────────────┼───────────────┤ │
│ │ Is this a lightness/darkness shift? │ V │ │ │
│ │ (pressed state, shadow) │ │ │ │
│ ├────────────────────────────────────────┼─────────────┼───────────────┤ │
│ │ Is this between two identities? │ V │ │ │
│ │ (gradient, merge line, transition) │ │ │ │
│ ├────────────────────────────────────────┼─────────────┼───────────────┤ │
│ │ Does this color only appear │ V │ │ │
│ │ temporarily? (feedback, animation) │ │ │ │
│ ├────────────────────────────────────────┼─────────────┼───────────────┤ │
│ │ Is this creating atmosphere? │ V │ │ │
│ │ (ambient glow, focus dimming) │ │ │ │
│ └────────────────────────────────────────┴─────────────┴───────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Derivation Examples
Copy
┌─────────────────────────────────────────────────────────────────────────────────┐
│ DERIVATION EXAMPLES (FLOW COLORS) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ├── State Derivation ─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ CORE: --core-primary: oklch(55% 0.15 230) │ │
│ │ │ │ │
│ │ ├──-> FLOW: --flow-primary-hover: │ │
│ │ │ color-mix(in oklch, var(--core-primary), white 15%)│
│ │ │ │ │
│ │ ├──-> FLOW: --flow-primary-active: │ │
│ │ │ color-mix(in oklab, var(--core-primary), black 20%)│
│ │ │ │ │
│ │ └──-> FLOW: --flow-primary-disabled: │ │
│ │ color-mix(in oklab, var(--core-primary), gray 60%)│
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ ├── Transparency Derivation ──────────────────────────────────────────────┐ │
│ │ │ │
│ │ CORE: --core-success: oklch(55% 0.15 130) │ │
│ │ │ │ │
│ │ ├──-> FLOW: --flow-success-bg: │ │
│ │ │ color-mix(in oklab, var(--core-success), transparent 80%)│
│ │ │ (20% opacity for badge background) │ │
│ │ │ │ │
│ │ └──-> FLOW: --flow-success-glow: │ │
│ │ color-mix(in oklab, var(--core-success), transparent 95%)│
│ │ (5% opacity for subtle glow) │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ ├── Interpolation Derivation ─────────────────────────────────────────────┐ │
│ │ │ │
│ │ CORE A: --core-main-branch: oklch(55% 0.15 230) (blue) │ │
│ │ CORE B: --core-feature-branch: oklch(55% 0.15 50) (orange) │ │
│ │ │ │ │
│ │ └──-> FLOW: --flow-merge-line: │ │
│ │ color-mix(in oklab, │ │
│ │ var(--core-main-branch), │ │
│ │ var(--core-feature-branch) 50%) │ │
│ │ │ │
│ │ "When Flow travels from Core to Core, OKLAB's straight-line │ │
│ │ interpolation prevents muddy transitions" │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Component-Specific Decision Guides
Button Component
Copy
┌─────────────────────────────────────────────────────────────────────────────────┐
│ BUTTON COMPONENT: CORE & FLOW MAPPING │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ State │ Type │ Rationale │
│ ─────────────────┼──────┼─────────────────────────────────────────────────── │
│ Default │ CORE │ Button identity - "This IS a primary button" │
│ :hover │ FLOW │ State variation - brightness increase │
│ :active/:pressed │ FLOW │ State variation - darkness increase │
│ :focus │ FLOW │ State variation - focus ring glow │
│ :disabled │ FLOW │ State variation - desaturated │
│ Text │ CORE │ Contrast identity - ensures readability │
│ │
│ CSS IMPLEMENTATION: │
│ ═══════════════════ │
│ │
│ .btn-primary { │
│ /* CORE: This IS a primary button */ │
│ background: var(--core-primary); │
│ color: var(--core-on-primary); │
│ border: none; │
│ } │
│ │
│ .btn-primary:hover { │
│ /* FLOW: Hover is a state variation */ │
│ background: var(--flow-primary-hover); │
│ } │
│ │
│ .btn-primary:active { │
│ /* FLOW: Active/pressed is a state variation */ │
│ background: var(--flow-primary-active); │
│ } │
│ │
│ .btn-primary:focus-visible { │
│ /* FLOW: Focus ring is a transparency derivation */ │
│ box-shadow: 0 0 0 3px var(--flow-primary-bg); │
│ } │
│ │
│ .btn-primary:disabled { │
│ /* FLOW: Disabled is a state variation */ │
│ background: var(--flow-primary-disabled); │
│ cursor: not-allowed; │
│ } │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Status Badge Component
Copy
┌─────────────────────────────────────────────────────────────────────────────────┐
│ STATUS BADGE: CORE & FLOW MAPPING │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │
│ │ * Running │ │ * Warning │ │ * Error │ │
│ └────────────────────┘ └────────────────────┘ └────────────────────┘ │
│ │
│ Element │ Type │ Rationale │
│ ────────────────┼──────┼─────────────────────────────────────────────────────│
│ Icon dot │ CORE │ Identity - "This indicates success status" │
│ Text │ CORE │ Identity - same meaning as icon │
│ Background │ FLOW │ Transparency derivation - 20% of Core │
│ Border │ FLOW │ Transparency derivation - edge of background │
│ │
│ VISUAL BREAKDOWN: │
│ ═════════════════ │
│ │
│ ┌──────────────────────────────────────┐ │
│ / \ │
│ / FLOW: Background (20% opacity) \ │
│ / \ │
│ │ │ │
│ │ * <-- CORE: Icon dot (identity) │ │
│ │ │ │
│ │ "Running" <-- CORE: Text (identity) │ │
│ │ │ │
│ \ / │
│ \ / │
│ \ / │
│ └──────────────────────────────────────┘ │
│ ^-- FLOW: Border (edge) │
│ │
│ CSS IMPLEMENTATION: │
│ ═══════════════════ │
│ │
│ .badge-success { │
│ /* FLOW: Background is transparency derivation */ │
│ background: var(--flow-success-bg); │
│ │
│ /* CORE: Text IS the success identity */ │
│ color: var(--core-success); │
│ } │
│ │
│ .badge-success .icon { │
│ /* CORE: The dot IS the success indicator */ │
│ fill: var(--core-success); │
│ } │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
File Explorer Item
Copy
┌─────────────────────────────────────────────────────────────────────────────────┐
│ FILE EXPLORER ITEM: CORE & FLOW MAPPING │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ [Folder] src/ │
│ ├── [TS] app.ts <-- TypeScript badge (CORE) │
│ ├── [PY] utils.py <-- Python badge (CORE) │
│ └── [JSON] config.json <-- JSON badge (CORE) │
│ │
│ ELEMENT MAPPING: │
│ ════════════════ │
│ │
│ Element │ Type │ Rationale │
│ ─────────────────────┼─────────┼──────────────────────────────────────────────│
│ Extension badge │ CORE │ Identity - "This IS a TypeScript file" │
│ Filename text │ Neutral │ Not semantic - uses text color │
│ Row background │ Neutral │ Not semantic - uses bg color │
│ Row :hover │ FLOW │ State - light overlay │
│ Row :selected │ FLOW │ State - primary bg transparency │
│ │
│ CSS IMPLEMENTATION: │
│ ═══════════════════ │
│ │
│ .file-item { │
│ /* Neutral text - NOT identity */ │
│ color: var(--color-text-primary); │
│ background: transparent; │
│ } │
│ │
│ .file-item:hover { │
│ /* FLOW: Hover is a state variation */ │
│ background: var(--flow-overlay-light-1); │
│ } │
│ │
│ .file-item.selected { │
│ /* FLOW: Selection derives from theme's primary Core */ │
│ background: var(--flow-primary-bg); │
│ } │
│ │
│ .file-badge[data-ext="ts"] { │
│ /* CORE: This badge IS the TypeScript identity */ │
│ background: var(--core-file-ts); │
│ color: white; │
│ } │
│ │
│ .file-badge[data-ext="py"] { │
│ /* CORE: This badge IS the Python identity */ │
│ background: var(--core-file-py); │
│ color: white; │
│ } │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Anti-Patterns and Common Mistakes
What NOT to Do
Copy
┌─────────────────────────────────────────────────────────────────────────────────┐
│ ANTI-PATTERNS: WHAT NOT TO DO │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ╔═══════════════════════════════════════════════════════════════════════════╗ │
│ ║ ANTI-PATTERN #1: DERIVING A CORE FROM ANOTHER CORE ║ │
│ ╚═══════════════════════════════════════════════════════════════════════════╝ │
│ │
│ X WRONG: │
│ ──────── │
│ --core-secondary: color-mix(in oklch, var(--core-primary), white 20%); │
│ │
│ WHY: Core Colors define independent identities. │
│ They should not depend on each other. │
│ │
│ V CORRECT: │
│ ────────── │
│ --core-primary: oklch(55% 0.15 230); │
│ --core-secondary: oklch(55% 0.10 200); /* Independent definition */ │
│ │
│ ═══════════════════════════════════════════════════════════════════════════ │
│ │
│ ╔═══════════════════════════════════════════════════════════════════════════╗ │
│ ║ ANTI-PATTERN #2: USING FLOW FOR IDENTITY ║ │
│ ╚═══════════════════════════════════════════════════════════════════════════╝ │
│ │
│ X WRONG: │
│ ──────── │
│ .badge-typescript { │
│ background: color-mix(in oklab, blue, transparent 80%); │
│ } │
│ │
│ WHY: TypeScript badge IS an identity, not a state variation. │
│ It should use a Core Color. │
│ │
│ V CORRECT: │
│ ────────── │
│ .badge-typescript { │
│ background: var(--core-file-ts); /* oklch(55% 0.15 230) */ │
│ } │
│ │
│ ═══════════════════════════════════════════════════════════════════════════ │
│ │
│ ╔═══════════════════════════════════════════════════════════════════════════╗ │
│ ║ ANTI-PATTERN #3: HARDCODING FLOW VALUES ║ │
│ ╚═══════════════════════════════════════════════════════════════════════════╝ │
│ │
│ X WRONG: │
│ ──────── │
│ .button:hover { │
│ background: #3399dd; /* Manually calculated lighter blue */ │
│ } │
│ │
│ WHY: Hardcoded values don't update when Core changes. │
│ Flow Colors should always reference Core via var(). │
│ │
│ V CORRECT: │
│ ────────── │
│ .button:hover { │
│ background: var(--flow-primary-hover); │
│ /* Defined as: color-mix(in oklch, var(--core-primary), white 15%) */ │
│ } │
│ │
│ ═══════════════════════════════════════════════════════════════════════════ │
│ │
│ ╔═══════════════════════════════════════════════════════════════════════════╗ │
│ ║ ANTI-PATTERN #4: USING sRGB/HSL FOR INTERPOLATION ║ │
│ ╚═══════════════════════════════════════════════════════════════════════════╝ │
│ │
│ X WRONG: │
│ ──────── │
│ .gradient { │
│ background: linear-gradient(to right, blue, orange); │
│ /* sRGB interpolation --> muddy brown in the middle */ │
│ } │
│ │
│ WHY: sRGB is not perceptually uniform - gradients go through muddy regions. │
│ │
│ V CORRECT: │
│ ────────── │
│ .gradient { │
│ background: linear-gradient(in oklab to right, │
│ var(--core-main-branch), │
│ var(--core-feature-branch)); │
│ /* OKLAB interpolation --> vibrant throughout */ │
│ } │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Quick Reference Decision Matrix
At-a-Glance Matrix
Copy
┌─────────────────────────────────────────────────────────────────────────────────┐
│ CORE vs FLOW: QUICK REFERENCE MATRIX │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ USE CASE │ CORE │ FLOW │ RATIONALE │
│ ════════════════════════════╪══════╪══════╪═══════════════════════════════════│
│ │ │ │ │
│ IDENTITY ELEMENTS │ │ │ │
│ ────────────────────────────┼──────┼──────┼───────────────────────────────────│
│ File type badge │ V │ │ "This IS a TypeScript file" │
│ Agent/terminal label │ V │ │ "This IS Agent #3" │
│ Branch color │ V │ │ "This IS the main branch" │
│ Status indicator │ V │ │ "This IS a success state" │
│ Brand/accent color │ V │ │ "This IS our brand" │
│ ANSI terminal color │ V │ │ "This IS ANSI red" │
│ │ │ │ │
│ STATE VARIATIONS │ │ │ │
│ ────────────────────────────┼──────┼──────┼───────────────────────────────────│
│ Hover state │ │ V │ Brightness increase │
│ Active/pressed state │ │ V │ Darkness increase │
│ Focus ring │ │ V │ Transparency glow │
│ Disabled state │ │ V │ Desaturation │
│ Selected state │ │ V │ Highlight │
│ │ │ │ │
│ TRANSPARENCY │ │ │ │
│ ────────────────────────────┼──────┼──────┼───────────────────────────────────│
│ Badge background │ │ V │ 20% of Core Color │
│ Overlay/backdrop │ │ V │ Partial transparency │
│ Subtle tint │ │ V │ 8% transparency │
│ Glow effect │ │ V │ 5% transparency │
│ │ │ │ │
│ INTERPOLATION │ │ │ │
│ ────────────────────────────┼──────┼──────┼───────────────────────────────────│
│ Gradient (endpoints) │ V │ │ Identity anchors │
│ Gradient (middle) │ │ V │ Interpolation path │
│ Merge line color │ │ V │ Between two branches │
│ Transition animation │ │ V │ Temporal path │
│ │ │ │ │
│ NEUTRAL ELEMENTS │ │ │ │
│ ────────────────────────────┼──────┼──────┼───────────────────────────────────│
│ Background │ N/A │ N/A │ Uses primitive color │
│ Text │ N/A │ N/A │ Uses primitive color │
│ Border │ N/A │ N/A │ Uses primitive color │
│ Divider │ │ V │ Light overlay │
│ │ │ │ │
│ TEXT ON BACKGROUNDS │ │ │ │
│ ────────────────────────────┼──────┼──────┼───────────────────────────────────│
│ Text on primary bg │ V │ │ Contrast identity │
│ Text on success bg │ V │ │ Contrast identity │
│ Text on warning bg │ V │ │ Contrast identity │
│ │ │ │ │
└─────────────────────────────────────────────────────────────────────────────────┘
THE CENTER
How Decision Flow Enables Consistent Information Visualization
The five decision rules ensure that color always communicates meaning:Copy
Connection to Core-Flow:
├── Rule 1 (Identity = Core) ensures semantic colors are stable
│ * TypeScript files are always blue (Hue 230)
│ * Success states are always green (Hue 130)
│ * Users learn color meanings once, apply everywhere
│
├── Rule 2 (State = Flow) ensures interactions feel connected
│ * Hover state clearly relates to default state
│ * Disabled state clearly relates to enabled state
│ * User perceives cause-and-effect through color
│
├── Rule 3 (Flow derives from Core) ensures theme coherence
│ * When brand color changes, all related states update
│ * Single source of truth prevents inconsistency
│ * Human can always trace a Flow back to its Core
│
├── Rule 4 (OKLAB mixing) ensures perceptual accuracy
│ * Gradients between Cores stay vibrant
│ * No muddy middle transitions
│ * Human perceives smooth, natural paths
│
└── Rule 5 (OKLCH for Core, color-mix for Flow) ensures technical correctness
* Predictable implementation pattern
* Clear separation of concerns
* Easy to audit and maintain
The Five Rules Summary
Copy
┌─────────────────────────────────────────────────────────────────────────────────┐
│ THE FIVE RULES OF CORE & FLOW │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ╔═══════════════════════════════════════════════════════════════════════════╗ │
│ ║ RULE 1: IDENTITY = CORE ║ │
│ ║ If the color DEFINES what something IS, use Core. ║ │
│ ╚═══════════════════════════════════════════════════════════════════════════╝ │
│ │
│ ╔═══════════════════════════════════════════════════════════════════════════╗ │
│ ║ RULE 2: STATE = FLOW ║ │
│ ║ If the color MODIFIES how something appears, use Flow. ║ │
│ ╚═══════════════════════════════════════════════════════════════════════════╝ │
│ │
│ ╔═══════════════════════════════════════════════════════════════════════════╗ │
│ ║ RULE 3: FLOW DERIVES FROM CORE ║ │
│ ║ Every Flow Color must trace back to a Core Color via var(). ║ │
│ ╚═══════════════════════════════════════════════════════════════════════════╝ │
│ │
│ ╔═══════════════════════════════════════════════════════════════════════════╗ │
│ ║ RULE 4: USE OKLAB FOR MIXING ║ │
│ ║ "When Flow moves from Core to Core, OKLAB prevents muddy transitions." ║ │
│ ╚═══════════════════════════════════════════════════════════════════════════╝ │
│ │
│ ╔═══════════════════════════════════════════════════════════════════════════╗ │
│ ║ RULE 5: CORE USES OKLCH, FLOW USES color-mix() ║ │
│ ║ Core: oklch(L% C H) ║ │
│ ║ Flow: color-mix(in oklab, var(--core-*), modifier) ║ │
│ ╚═══════════════════════════════════════════════════════════════════════════╝ │
│ │
│ ═══════════════════════════════════════════════════════════════════════════ │
│ │
│ "Core Colors define identity. Flow Colors handle everything in between." │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Implementation Guide
Complete step-by-step guide to implementing Core and Flow in your project