# Code Conversion Reference

Convert Pencil designs to production code (HTML/CSS/React/Blazor).

## Overview

This guide covers converting `.pen` files to production code with proper structure, responsive design, and design system integration.

## Element Mapping

### Pencil to HTML/CSS

| Pencil Element | HTML | CSS Layout | Notes |
|----------------|------|------------|-------|
| `frame` (layout:vertical) | `<div>` | `flex-direction: column` | Flexbox container |
| `frame` (layout:horizontal) | `<div>` | `flex-direction: row` | Flexbox container |
| `frame` (layout:none) | `<div>` | `position: relative` | Free positioning |
| `text` | `<p>`, `<h1>`-`<h6>`, `<span>` | - | Based on fontSize |
| `rectangle` | `<div>` | - | With background |
| `ellipse` | `<div>` | `border-radius: 50%` | Circular shape |
| `icon_font` | `<i class="lucide-{name}">` | - | Lucide icons |

### Pencil to React/Blazor

| Pencil | React | Blazor |
|--------|-------|--------|
| `frame` | `<div className="">` | `<div class="">` |
| `text` | `<p>{content}</p>` | `<p>@content</p>` |
| `icon_font` | `<Icon name={iconName} />` | `<i class="lucide-@iconName"></i>` |
| Component ref | `<Button>` | `<Button />` |

## Property Mapping

### Layout Properties → CSS

```javascript
// Pencil layout properties
{
  "layout": "vertical",
  "gap": 16,
  "padding": [24, 32],
  "justifyContent": "center",
  "alignItems": "center"
}

// CSS output
.container {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 24px 32px;
  justify-content: center;
  align-items: center;
}
```

### Size Properties → CSS

```javascript
// Fixed size
{ "width": 400, "height": 200 }
// CSS
.element { width: 400px; height: 200px; }

// Fill container
{ "width": "fill_container", "height": 200 }
// CSS
.element { width: 100%; height: 200px; }
```

### Color Properties → CSS

```javascript
// Solid color
{ "fill": "#FF5C00" }
// CSS
.element { background: #FF5C00; }

// Design token
{ "fill": "$bg-page" }
// CSS
.element { background: var(--bg-page); }

// Gradient
{
  "fill": {
    "type": "gradient",
    "colors": [
      {"color": "#FF5C00", "position": 0},
      {"color": "#FF8A4C", "position": 1}
    ]
  }
}
// CSS
.element {
  background: linear-gradient(180deg, #FF5C00 0%, #FF8A4C 100%);
}
```

### Border Properties → CSS

```javascript
// Corner radius
{ "cornerRadius": 10 }
// CSS
.element { border-radius: 10px; }

// Stroke
{ "stroke": "$border-default", "strokeWidth": 2 }
// CSS
.element { border: 2px solid var(--border-default); }
```

## Conversion Workflow

### Step 1: Extract Design Tokens

```javascript
import pencilData from './design.pen';

// Extract variables
const tokens = pencilData.variables;

// Generate CSS Variables
const cssTokens = Object.entries(tokens)
  .map(([key, value]) => {
    if (value.type === 'color') {
      return `  --${key}: ${value.value};`;
    }
    if (value.type === 'number') {
      return `  --${key}: ${value.value}px;`;
    }
    return `  --${key}: ${value.value};`;
  })
  .join('\n');

console.log(`:root {\n${cssTokens}\n}`);
```

**Output:**
```css
:root {
  --bg-page: #0A0A0B;
  --text-primary: #FFFFFF;
  --orange-primary: #FF5C00;
  --space-4: 16px;
  --radius-md: 10px;
}
```

### Step 2: Convert Layout Structure

```javascript
function convertElement(element) {
  if (element.type === 'frame') {
    return convertFrame(element);
  }
  if (element.type === 'text') {
    return convertText(element);
  }
  if (element.type === 'icon_font') {
    return convertIcon(element);
  }
  if (element.type === 'ref') {
    return convertRef(element);
  }
}

function convertFrame(frame) {
  const className = frame.name.toLowerCase().replace(/\s+/g, '-');
  const children = frame.children?.map(convertElement).join('\n') || '';
  
  return `<div class="${className}">\n${children}\n</div>`;
}

function convertText(text) {
  const tag = getTextTag(text.fontSize);
  return `<${tag}>${text.content}</${tag}>`;
}

function getTextTag(fontSize) {
  if (fontSize >= 32) return 'h1';
  if (fontSize >= 24) return 'h2';
  if (fontSize >= 18) return 'h3';
  if (fontSize >= 16) return 'h4';
  return 'p';
}

function convertIcon(icon) {
  return `<i class="lucide-${icon.iconFontName}"></i>`;
}
```

### Step 3: Generate CSS Classes

```javascript
function generateCSS(element, className) {
  const styles = [];
  
  // Layout
  if (element.layout) {
    styles.push('display: flex');
    styles.push(`flex-direction: ${element.layout === 'vertical' ? 'column' : 'row'}`);
  }
  
  // Gap
  if (element.gap) {
    styles.push(`gap: ${element.gap}px`);
  }
  
  // Padding
  if (element.padding) {
    const padding = Array.isArray(element.padding)
      ? `${element.padding[0]}px ${element.padding[1]}px`
      : `${element.padding}px`;
    styles.push(`padding: ${padding}`);
  }
  
  // Size
  if (element.width) {
    const width = element.width === 'fill_container' ? '100%' : `${element.width}px`;
    styles.push(`width: ${width}`);
  }
  if (element.height) {
    styles.push(`height: ${element.height}px`);
  }
  
  // Fill (background)
  if (element.fill) {
    if (element.fill.startsWith('$')) {
      // Design token
      const token = element.fill.substring(1);
      styles.push(`background: var(--${token})`);
    } else if (typeof element.fill === 'object' && element.fill.type === 'gradient') {
      // Gradient
      const gradient = convertGradient(element.fill);
      styles.push(`background: ${gradient}`);
    } else {
      // Solid color
      styles.push(`background: ${element.fill}`);
    }
  }
  
  // Border radius
  if (element.cornerRadius) {
    styles.push(`border-radius: ${element.cornerRadius}px`);
  }
  
  // Alignment
  if (element.justifyContent) {
    const value = element.justifyContent.replace('_', '-');
    styles.push(`justify-content: ${value}`);
  }
  if (element.alignItems) {
    styles.push(`align-items: ${element.alignItems}`);
  }
  
  return `.${className} {\n  ${styles.join(';\n  ')};\n}`;
}

function convertGradient(fill) {
  const colors = fill.colors
    .map(c => `${c.color} ${c.position * 100}%`)
    .join(', ');
  return `linear-gradient(180deg, ${colors})`;
}
```

## Best Practices

### 1. Semantic HTML

```html
<!-- ❌ BAD: All divs -->
<div class="page">
  <div class="header">...</div>
  <div class="content">...</div>
  <div class="footer">...</div>
</div>

<!-- ✅ GOOD: Semantic elements -->
<main class="page">
  <header class="header">...</header>
  <section class="content">...</section>
  <footer class="footer">...</footer>
</main>
```

### 2. CSS Variables for Tokens

```css
/* ❌ BAD: Hardcoded colors */
.button {
  background: #FF5C00;
  color: #FFFFFF;
}

/* ✅ GOOD: CSS variables */
.button {
  background: var(--orange-primary);
  color: var(--text-primary);
}
```

### 3. Mobile-First Responsive

```css
/* ✅ GOOD: Mobile-first */
.container {
  padding: 16px;
  flex-direction: column;
}

@media (min-width: 768px) {
  .container {
    padding: 24px;
    flex-direction: row;
  }
}

@media (min-width: 1440px) {
  .container {
    padding: 80px 120px;
  }
}
```

### 4. Component Structure

```jsx
// ✅ GOOD: Match Pencil component hierarchy
// Atom/Button/Primary/Default → Button.jsx

function Button({ children, variant = 'primary', state = 'default' }) {
  return (
    <button className={`button button--${variant} button--${state}`}>
      {children}
    </button>
  );
}

// CSS
.button {
  /* Base styles */
}
.button--primary {
  background: var(--orange-primary);
}
.button--default {
  /* Default state */
}
.button--hover {
  background: var(--orange-light);
}
```

## Framework-Specific Examples

### React Component

```jsx
import React from 'react';
import './HeroSection.css';

export function HeroSection({ title, subtitle, ctaText }) {
  return (
    <section className="hero-section">
      <div className="hero-content">
        <h1 className="hero-title">{title}</h1>
        <p className="hero-subtitle">{subtitle}</p>
        <button className="hero-cta">{ctaText}</button>
      </div>
    </section>
  );
}
```

```css
/* HeroSection.css */
.hero-section {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 80px 120px;
  background: var(--bg-page);
}

.hero-content {
  max-width: 800px;
  text-align: center;
}

.hero-title {
  font-size: 48px;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 16px;
}

.hero-subtitle {
  font-size: 18px;
  color: var(--text-secondary);
  margin-bottom: 32px;
}

.hero-cta {
  padding: 16px 32px;
  background: var(--orange-primary);
  color: var(--text-primary);
  border: none;
  border-radius: 10px;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
}

.hero-cta:hover {
  background: var(--orange-light);
}
```

### Blazor Component

```razor
@* HeroSection.razor *@
<section class="hero-section">
    <div class="hero-content">
        <h1 class="hero-title">@Title</h1>
        <p class="hero-subtitle">@Subtitle</p>
        <button class="hero-cta" @onclick="OnCtaClick">@CtaText</button>
    </div>
</section>

@code {
    [Parameter] public string Title { get; set; } = "";
    [Parameter] public string Subtitle { get; set; } = "";
    [Parameter] public string CtaText { get; set; } = "";
    [Parameter] public EventCallback OnCtaClick { get; set; }
}
```

### Tailwind CSS

From design tokens to Tailwind config:

```javascript
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        'bg-page': '#0A0A0B',
        'bg-surface': '#1A1A1C',
        'text-primary': '#FFFFFF',
        'orange-primary': '#FF5C00',
      },
      spacing: {
        '1': '4px',
        '2': '8px',
        '4': '16px',
        '6': '24px',
      },
      borderRadius: {
        'sm': '6px',
        'md': '10px',
        'lg': '16px',
      }
    }
  }
}
```

```jsx
// Component with Tailwind
<section className="flex flex-col items-center px-30 py-20 bg-bg-page">
  <div className="max-w-3xl text-center">
    <h1 className="text-5xl font-bold text-text-primary mb-4">
      {title}
    </h1>
    <p className="text-lg text-text-secondary mb-8">
      {subtitle}
    </p>
    <button className="px-8 py-4 bg-orange-primary text-text-primary rounded-md hover:bg-orange-light">
      {ctaText}
    </button>
  </div>
</section>
```

## Conversion Tools

### Automated Conversion Script

```javascript
import fs from 'fs';

function convertPencilToHTML(pencilFile) {
  const data = JSON.parse(fs.readFileSync(pencilFile, 'utf-8'));
  
  // Extract main page
  const mainPage = data.children[0];
  
  // Generate HTML
  const html = convertElement(mainPage);
  
  // Generate CSS
  const css = generateCSSForAll(mainPage);
  
  // Generate design tokens
  const tokens = generateTokensCSS(data.variables);
  
  return {
    html,
    css: `${tokens}\n\n${css}`,
    tokens: data.variables
  };
}

// Example usage
const result = convertPencilToHTML('design.pen');
fs.writeFileSync('output.html', result.html);
fs.writeFileSync('output.css', result.css);
console.log('✅ Conversion complete!');
```

## Common Patterns

### Navigation Bar

```html
<nav class="navbar">
  <div class="navbar-logo">
    <img src="logo.svg" alt="Logo" />
  </div>
  <ul class="navbar-menu">
    <li><a href="#home">Home</a></li>
    <li><a href="#features">Features</a></li>
    <li><a href="#pricing">Pricing</a></li>
  </ul>
  <button class="navbar-cta">Sign Up</button>
</nav>
```

```css
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 120px;
  background: var(--bg-surface);
}

.navbar-menu {
  display: flex;
  gap: 32px;
  list-style: none;
}

.navbar-menu a {
  color: var(--text-primary);
  text-decoration: none;
}
```

### Card Component

```html
<div class="card">
  <div class="card-header">
    <i class="lucide-star"></i>
    <h3>Feature Title</h3>
  </div>
  <p class="card-description">
    Feature description text goes here.
  </p>
  <a href="#" class="card-link">Learn More →</a>
</div>
```

```css
.card {
  display: flex;
  flex-direction: column;
  padding: 24px;
  background: var(--bg-surface);
  border-radius: var(--radius-md);
  gap: 16px;
}

.card-header {
  display: flex;
  align-items: center;
  gap: 12px;
}

.card-description {
  color: var(--text-secondary);
  line-height: 1.6;
}

.card-link {
  color: var(--orange-primary);
  text-decoration: none;
  font-weight: 600;
}
```

## Resources

- Back to [Pencil Design Skill](../SKILL.md)
- [File Format Reference](./FILE_FORMAT.md)
- [Build System Reference](./BUILD_SYSTEM.md)
- [Atomic Design Reference](./ATOMIC_DESIGN.md)
- [Tailwind Design System](../tailwind-design-system/SKILL.md)
- [React UI Components](../react-ui-components/SKILL.md)
- [Blazor Theme Patterns](../blazor-theme-patterns/SKILL.md)
- [MAUI Branding Expert](../maui-branding-expert/SKILL.md)
- [Swift UI Components](../swift-ui-components/SKILL.md)
