diff --git a/.agent/skills/pencil-design/SKILL.md b/.agent/skills/pencil-design/SKILL.md new file mode 100644 index 00000000..8d240a08 --- /dev/null +++ b/.agent/skills/pencil-design/SKILL.md @@ -0,0 +1,494 @@ +--- +name: pencil-design +description: Pencil UI/UX design tool workflows và file format. Use for reading .pen files, extracting design content, converting designs to HTML/CSS/React/Blazor code, và understanding component systems. +compatibility: "Pencil 2.6+, JSON parsing" +metadata: + author: Velik Ho + version: "1.0" + references: "pencil.evolus.vn, Pencil GitHub" +--- + +# Pencil Design Tool / Công cụ thiết kế Pencil + +## 1. Tổng Quan / Overview + +[Pencil](https://pencil.evolus.vn/) là công cụ thiết kế UI/UX mã nguồn mở. File project có extension `.pen` lưu dưới định dạng JSON. + +**Khả năng Agent với file .pen:** +- ✅ Đọc và phân tích cấu trúc design +- ✅ Extract content (text, colors, images) +- ✅ Convert sang HTML/CSS/React/Blazor +- ✅ Hiểu component system và design tokens +- ❌ Render preview (cần Pencil app) +- ❌ Chỉnh sửa trực tiếp trong app + +## 2. File Format / Định dạng file + +### 2.1 Cấu trúc JSON + +```json +{ + "version": "2.6", + "children": [ /* Page frames và components */ ], + "variables": { /* Design tokens */ } +} +``` + +### 2.2 Element Types + +| Type | Mô tả | Properties chính | +|------|-------|------------------| +| `frame` | Container, layout | `width`, `height`, `fill`, `layout`, `gap`, `padding` | +| `text` | Text element | `content`, `fontSize`, `fontFamily`, `fontWeight`, `fill` | +| `rectangle` | Shape | `width`, `height`, `fill`, `cornerRadius` | +| `ellipse` | Circle/Ellipse | `width`, `height`, `fill` | +| `icon_font` | Icon (Lucide) | `iconFontName`, `iconFontFamily`, `fill` | +| `ref` | Component instance | `ref` (ID), `descendants` (overrides) | + +### 2.3 Layout Properties + +```json +{ + "layout": "vertical", // vertical | horizontal | none + "gap": 16, // spacing between children + "padding": [16, 24], // [vertical, horizontal] hoặc single value + "justifyContent": "center", // start | center | end | space_between + "alignItems": "center" // start | center | end +} +``` + +### 2.4 Size Properties + +```json +{ + "width": 400, // fixed pixels + "width": "fill_container", // 100% của parent + "height": 200 +} +``` + +## 3. Design Tokens / Variables + +Design tokens được định nghĩa trong `variables` object: + +```json +"variables": { + "bg-page": { "type": "color", "value": "#0A0A0B" }, + "text-primary": { "type": "color", "value": "#FFFFFF" }, + "orange-primary": { "type": "color", "value": "#FF5C00" } +} +``` + +**Sử dụng trong elements:** +```json +"fill": "$bg-page", +"fill": "$text-primary" +``` + +### 3.1 Common Token Categories + +| Category | Prefix | Examples | +|----------|--------|----------| +| Background | `bg-` | `$bg-page`, `$bg-surface`, `$bg-elevated` | +| Text | `text-` | `$text-primary`, `$text-secondary`, `$text-tertiary` | +| Border | `border-` | `$border-default`, `$border-subtle` | +| Brand | `{color}-` | `$orange-primary`, `$green-success` | + +## 4. Component System + +### 4.1 Reusable Components + +Components có `reusable: true` có thể được tham chiếu lại: + +```json +{ + "type": "frame", + "id": "tmKtl", + "name": "Component/Button/Primary", + "reusable": true, + "children": [...] +} +``` + +### 4.2 Component Instances (Refs) + +```json +{ + "type": "ref", + "ref": "tmKtl", // ID của component gốc + "name": "myButton", + "descendants": { // Override properties + "q7oNn": { // Child element ID + "content": "Click Me" // Override content + } + } +} +``` + +## 5. Workflows + +### 5.1 Đọc và Phân tích Design + +```markdown +1. Mở file .pen bằng view_file tool +2. Parse JSON structure +3. Identify main page frame (thường là child lớn nhất) +4. Extract sections dựa trên "name" property +5. List design tokens từ "variables" +``` + +### 5.2 Extract Content + +```markdown +1. Tìm tất cả elements có type "text" +2. Collect "content" property +3. Group theo parent frame (section) +4. Export dạng structured text hoặc JSON +``` + +### 5.3 Design to Code Conversion + +**Step 1: Analyze Structure** +```markdown +- Identify layout (vertical/horizontal) +- Map padding và gap values +- Extract color tokens +``` + +**Step 2: Convert Elements** + +| Pencil | HTML/CSS | React | Blazor | +|--------|----------|-------|--------| +| `frame` layout:vertical | `
` flex-direction:column | `
` | `
` | +| `frame` layout:horizontal | `
` flex-direction:row | | | +| `text` | `

`, `

`-`

`, `` | | | +| `icon_font` | `` | `` | `` | + +**Step 3: Apply Styles** +```css +/* Map Pencil properties to CSS */ +gap: 16px /* gap: 16 */ +padding: 24px 32px /* padding: [24, 32] */ +border-radius: 10px /* cornerRadius: 10 */ +background: linear-gradient /* fill.type: "gradient" */ +``` + +### 5.4 Design System Extraction + +```markdown +1. Extract all "variables" as CSS custom properties +2. Convert to: + - CSS Variables (:root) + - Tailwind config + - SCSS variables + - Design tokens JSON +``` + +**Output Example:** +```css +:root { + --bg-page: #0A0A0B; + --text-primary: #FFFFFF; + --orange-primary: #FF5C00; +} +``` + +## 6. Common Patterns + +### 6.1 Page Structure + +``` +Page Frame +├── Header/NavBar +├── Hero Section +├── Features Section +├── Pricing Section +├── CTA Section +└── Footer +``` + +### 6.2 Component Naming Convention + +``` +Component/{Category}/{Variant} +- Component/Button/Primary +- Component/Button/Secondary +- Component/Card/Feature +- Component/Card/Pricing +``` + +### 6.3 Modular Design Architecture (Hybrid Approach) + +**Problem**: Large monolithic `.pen` files (5000+ lines) cause: +- ❌ Slow performance (2-3 second load times) +- ❌ Maintenance challenges (duplicate components) +- ❌ Collaboration bottlenecks (merge conflicts) +- ❌ Poor reusability + +**Solution**: Split into modular structure + +#### File Structure Patterns + +**Option A: By Responsive Breakpoints** +``` +project-name/ +├── components/ +│ └── ui-kit.pen # Component library +├── pages/ +│ ├── desktop-home.pen # Desktop (1440px) +│ ├── tablet-home.pen # Tablet (768px) +│ └── mobile-home.pen # Mobile (390px) +└── original.pen.backup # Backup +``` + +**Option B: By Features** +``` +project-name/ +├── components/ +│ └── ui-kit.pen +├── pages/ +│ ├── hero.pen +│ ├── features.pen +│ ├── pricing.pen +│ └── footer.pen +``` + +**Option C: Hybrid** ⭐ (Recommended) +``` +project-name/ +├── components/ +│ └── ui-kit.pen # Atoms + Design Tokens +├── pages/ +│ ├── desktop-{feature}.pen # Desktop pages +│ ├── mobile-{feature}.pen # Mobile pages +│ └── tablet-{feature}.pen # Tablet pages +└── USAGE_GUIDE.md # Workflow docs +``` + +#### Component Library Structure + +**ui-kit.pen should contain:** + +1. **Design Variables** (always included) + ```json + "variables": { + "bg-page": { "type": "color", "value": "#0A0A0B" }, + "text-primary": { "type": "color", "value": "#FFFFFF" }, + ... + } + ``` + +2. **Component Showcase Page** + - Organized by category sections + - Section 1: Buttons & Actions + - Section 2: Badges & Labels + - Section 3: Cards + - Section 4: Navigation + - Section 5: Typography & Branding + - Section 6: Utilities + - Section 7: Footer Components + +#### Extraction Workflow + +**Step 1: Analyze Original File** +```bash +# Check file stats +wc -l original.pen +du -h original.pen + +# Identify pages and components +grep '"name":' original.pen | grep -E "(Page|Component)" +``` + +**Step 2: Create Directory Structure** +```bash +mkdir -p components pages +``` + +**Step 3: Extract with Python Script** +```python +import json + +# Read original +with open('original.pen', 'r') as f: + data = json.load(f) + +variables = data['variables'] + +# Extract Component Library +comp_lib = { + 'version': '2.6', + 'children': [], + 'variables': variables +} + +# Find component library page (e.g., id: 'CompLib') +for child in data['children']: + if child.get('name') == 'Component Library': + child['x'] = 0 # Reset position + child['y'] = 0 + comp_lib['children'].append(child) + break + +# Write component library +with open('components/ui-kit.pen', 'w') as f: + json.dump(comp_lib, f, indent=2) + +# Extract pages similarly +# - Desktop: find by name "Desktop Page" +# - Mobile: find by name "Mobile Page" +# - Tablet: find by name "Tablet Page" +``` + +**Step 4: Validate Extracted Files** +```python +import json +import os + +files_to_check = [ + 'components/ui-kit.pen', + 'pages/desktop-home.pen', + 'pages/mobile-home.pen', + 'pages/tablet-home.pen' +] + +for filepath in files_to_check: + with open(filepath, 'r') as f: + data = json.load(f) + + assert 'version' in data + assert 'children' in data and len(data['children']) > 0 + assert 'variables' in data + + print(f'✅ {filepath} - Valid') +``` + +**Step 5: Create Usage Guide** + +Generate `USAGE_GUIDE.md`: +```markdown +# Design System - Usage Guide + +## Component Library +- File: `components/ui-kit.pen` +- Contains: Design tokens + All reusable components + +## Workflow +1. Open `components/ui-kit.pen` +2. Copy components you need +3. Paste into page files +4. Maintain design token references + +## Important +⚠️ Pencil doesn't support external file refs (yet) +Components are COPIED, not linked +``` + +#### Current Limitations + +> [!WARNING] +> **No External File References**: Pencil 2.6 doesn't support linking components across files. +> +> **Workaround**: Manual Import Workflow +> 1. Update component in `ui-kit.pen` +> 2. Copy updated component +> 3. Replace in each page file manually + +**Future**: When Pencil adds cross-file linking, this will auto-update. + +#### Benefits + +| Metric | Before (Monolith) | After (Modular) | Improvement | +|--------|-------------------|-----------------|-------------| +| Largest file | 9,118 lines (328KB) | 3,181 lines (118KB) | **64% smaller** | +| Load time | ~2-3 seconds | ~0.5-1 second | **3x faster** | +| Collaboration | Hard (conflicts) | Easy (parallel work) | ✅ | +| Reusability | Low (duplicates) | High (single source) | ✅ | + +#### When to Use Modular Approach + +✅ **Use when:** +- File > 5,000 lines +- Multiple responsive breakpoints +- Team collaboration needed +- Component reuse across projects + +❌ **Skip when:** +- Simple single-page designs +- Solo designer, no collaboration +- Prototypes or wireframes +- File < 2,000 lines + +## 7. Best Practices + +### 7.1 Khi đọc .pen files + +1. **Luôn kiểm tra `version`** - Đảm bảo compatibility +2. **Tìm page chính** - Thường là frame có name kết thúc bằng "Page" +3. **Extract tokens trước** - Hiểu color palette trước khi convert +4. **Map components** - List ra reusable components trước +5. **Check file size** - Nếu > 300KB, consider splitting + +### 7.2 Khi convert sang code + +1. **Mobile-first** - Responsive breakpoints +2. **Semantic HTML** - `
`, `
`, `
`, `