Files
igny8/docs/30-FRONTEND/DESIGN-GUIDE.md
IGNY8 VPS (Salman) f10916bfab VErsion 1.3.2
2026-01-03 09:35:43 +00:00

7.2 KiB

IGNY8 Design System Guide

Single Source of Truth for UI Components

🔒 STYLE LOCKED - This design system is enforced by ESLint. All frontend code must comply.

Last Updated: January 3, 2026
Version: 1.3.2


Resource Path Description
Component System COMPONENT-SYSTEM.md Full component reference with props, examples, and usage
Design Tokens Doc DESIGN-TOKENS.md Detailed token documentation
ESLint Plugin frontend/eslint/ Custom rules enforcing design system
Live Demo /ui-elements route Interactive component showcase
CSS Tokens frontend/src/styles/design-system.css CSS variables source file
Icons frontend/src/icons/ All SVG icons

🎨 Color System (CRITICAL!)

Only 6 Base Colors in Entire System

All colors derive from 6 primary hex values defined in design-system.css:

Token Hex Purpose
--color-primary #0077B6 Brand Blue - main CTA, links
--color-success #2CA18E Success Green - confirmations
--color-warning #D9A12C Warning Amber - alerts
--color-danger #A12C40 Danger Red - errors, destructive
--color-purple #2C40A1 Purple - premium features
--color-gray-base #667085 Neutral gray - text, borders

Tailwind Color Utilities

⚠️ Tailwind default colors are DISABLED! Only use:

/* ✅ AVAILABLE */
brand-50 through brand-950    /* Primary blue scale */
gray-25 through gray-950      /* Neutral scale */
success-25 through success-950 /* Green scale */
error-25 through error-950     /* Red scale */
warning-25 through warning-950 /* Amber scale */
purple-25 through purple-950   /* Purple scale */

/* ❌ DISABLED - These will NOT work */
blue-*, red-*, green-*, emerald-*, amber-*, indigo-*, 
pink-*, rose-*, sky-*, teal-*, cyan-*, etc.

Usage Examples

// ✅ CORRECT
<div className="bg-brand-500 text-white">Primary Button</div>
<div className="text-gray-700 bg-gray-50">Card content</div>
<Badge tone="success">Active</Badge>
<Alert variant="error" message="Failed" />

// ❌ WRONG
<div className="bg-blue-500">...</div>     // Default blue disabled
<div className="bg-[#0693e3]">...</div>   // Hardcoded hex
<div style={{ color: '#ff0000' }}>...</div> // Inline style

Core Principles

1. Use Components, Never Raw HTML

// ❌ NEVER
<button className="...">Click</button>
<input type="text" className="..." />
<select className="...">...</select>
<textarea className="..."></textarea>

// ✅ ALWAYS
<Button variant="primary">Click</Button>
<InputField type="text" label="Name" />
<Select options={options} />
<TextArea rows={4} />

2. Import Icons from Central Location

// ❌ NEVER
import { XIcon } from '@heroicons/react/24/outline';
import { Trash } from 'lucide-react';

// ✅ ALWAYS
import { CloseIcon, TrashBinIcon } from '../../icons';

3. Consistent Sizing

// Icons in buttons/badges
<Icon className="w-4 h-4" />

// Standalone icons
<Icon className="w-5 h-5" />

// Large/header icons
<Icon className="w-6 h-6" />

Component Quick Reference

Need Component Import
Action button Button components/ui/button/Button
Icon-only button IconButton components/ui/button/IconButton
Text input InputField components/form/input/InputField
Checkbox Checkbox components/form/input/Checkbox
Radio Radio components/form/input/Radio
Dropdown Select components/form/Select
Multi-line text TextArea components/form/input/TextArea
Toggle Switch components/form/switch/Switch
Status label Badge components/ui/badge/Badge
Container Card components/ui/card/Card
Popup Modal components/ui/modal
Loading Spinner components/ui/spinner/Spinner
Notification useToast components/ui/toast/ToastContainer

→ See COMPONENT-SYSTEM.md for full props and examples


ESLint Enforcement

Rules

Rule Level Action
no-raw-button warn Use Button or IconButton
no-raw-input warn Use InputField, Checkbox, Radio
no-raw-select warn Use Select or SelectDropdown
no-raw-textarea warn Use TextArea
no-icon-children warn Use startIcon/endIcon props instead of icon children
no-restricted-imports error Block @heroicons/*, lucide-react, @mui/icons-material

Check Violations

# Inside container
docker exec -it igny8_frontend npm run lint

# Or directly
cd frontend
npm run lint

Plugin Location

The custom ESLint plugin is at: frontend/eslint/eslint-plugin-igny8-design-system.cjs


For AI Agents

When working on this codebase:

  1. Read first: docs/30-FRONTEND/COMPONENT-SYSTEM.md
  2. Never use: <button>, <input>, <select>, <textarea> tags
  3. Import icons from: src/icons only
  4. Verify after changes: npm run lint
  5. Reference pages: Planner and Writer modules use correct patterns

Correct Import Paths

// From a page in src/pages/
import Button from '../components/ui/button/Button';
import IconButton from '../components/ui/button/IconButton';
import InputField from '../components/form/input/InputField';
import { PlusIcon, CloseIcon } from '../icons';

// From a component in src/components/
import Button from '../../components/ui/button/Button';
import { PlusIcon } from '../../icons';

// From a nested component
// Adjust ../ based on depth

File Structure

frontend/
├── eslint/
│   └── eslint-plugin-igny8-design-system.cjs  # Custom rules
├── src/
│   ├── components/
│   │   ├── ui/           # Display components
│   │   │   ├── button/   # Button, IconButton
│   │   │   ├── badge/    # Badge
│   │   │   ├── card/     # Card
│   │   │   ├── modal/    # Modal
│   │   │   └── ...
│   │   └── form/         # Form components
│   │       ├── input/    # InputField, Checkbox, Radio, TextArea
│   │       ├── switch/   # Switch
│   │       ├── Select.tsx
│   │       └── ...
│   ├── icons/            # All SVG icons
│   │   └── index.ts      # Export all icons
│   └── styles/
│       └── design-system.css  # Design tokens
docs/
└── 30-FRONTEND/
    └── COMPONENT-SYSTEM.md    # Full component documentation

Migration Checklist

When fixing violations:

  • Replace <button> with Button or IconButton
  • Replace <input type="text/email/password/number"> with InputField
  • Replace <input type="checkbox"> with Checkbox
  • Replace <input type="radio"> with Radio
  • Replace <select> with Select or SelectDropdown
  • Replace <textarea> with TextArea
  • Replace external icon imports with src/icons
  • Run npm run lint to verify
  • Run npm run build to confirm no errors