import React, { useState, useEffect } from 'react'; // Fire/Frost/Arcane CSS definitions (injected into preview) const FIRE_FROST_CSS = ` :root { /* Fire Colors (Meg/The Emissary) */ --fire-primary: #FF6B35; --fire-secondary: #F7931E; --fire-accent: #FFA500; /* Frost Colors (Michael/The Wizard) */ --frost-primary: #4ECDC4; --frost-secondary: #45B7D1; --frost-accent: #00CED1; /* Arcane Colors (Holly/The Catalyst) */ --arcane-primary: #A855F7; --arcane-secondary: #9D4EDD; --arcane-accent: #C77DFF; --arcane-dark: #7F00FF; /* Neutral Colors */ --neutral-dark: #1a1a1a; --neutral-gray: #6b7280; --neutral-light: #f3f4f6; } /* Fire/Frost/Arcane Gradient Utilities */ .fire-frost-gradient { background: linear-gradient(135deg, #FF6B35 0%, #4ECDC4 100%); } .fire-gradient { background: linear-gradient(135deg, #FF6B35 0%, #FFA500 100%); } .frost-gradient { background: linear-gradient(135deg, #4ECDC4 0%, #00CED1 100%); } .arcane-gradient { background: linear-gradient(135deg, #A855F7 0%, #C77DFF 100%); } .trinity-gradient { background: linear-gradient(135deg, #FF6B35 0%, #A855F7 50%, #4ECDC4 100%); } .arcane-storm-gradient { background: linear-gradient(135deg, #7F00FF 0%, #A855F7 50%, #C77DFF 100%); } /* Typography Colors */ .fire-text { color: var(--fire-primary); } .frost-text { color: var(--frost-primary); } .arcane-text { color: var(--arcane-primary); } /* Border Utilities */ .fire-border { border-color: var(--fire-primary); } .frost-border { border-color: var(--frost-primary); } .arcane-border { border-color: var(--arcane-primary); } /* Common Ghost page styles */ .gh-content { max-width: 1200px; margin: 0 auto; padding: 40px 20px; } .gh-content h1 { font-size: 3rem; font-weight: 700; margin-bottom: 1.5rem; line-height: 1.2; } .gh-content h2 { font-size: 2rem; font-weight: 600; margin: 2rem 0 1rem; line-height: 1.3; } .gh-content p { font-size: 1.125rem; line-height: 1.75; margin-bottom: 1.5rem; } .gh-content a { color: var(--fire-primary); text-decoration: underline; } .gh-content a:hover { color: var(--frost-primary); } `; // Sample templates with Ghost wrapper classes const SAMPLE_TEMPLATES = { blank: { name: 'Blank Page', html: '

Page Title

\n

Start writing your content here...

' }, simple: { name: 'Simple Page', html: `

Welcome to Firefrost Gaming

This is a simple page template with basic structure.

Section Heading

Add your content here. This template includes proper Ghost content classes for consistent styling.

You can add more paragraphs, headings, and content as needed.

` }, twoColumn: { name: 'Trinity Layout (3 Columns)', html: `

The Trinity

๐Ÿ”ฅ Fire Path

GingerFury - The Emissary

Community-focused content goes here. Passionate, warm, welcoming.

โšก Arcane Path

unicorn20089 - The Catalyst

Creative, building-focused content. Innovation, transformation, foundation.

โ„๏ธ Frost Path

Frostystyle - The Wizard

Technical, precise content goes here. Cool, calculated, systematic.

` }, cardGrid: { name: 'Trinity Card Grid', html: `

The Trinity - Fire + Arcane + Frost

Showcase the three elemental forces.

๐Ÿ”ฅ Fire - The Emissary

Passion, community, warmth. GingerFury brings the heart and the people.

โšก Arcane - The Catalyst

Creative transformation, building, innovation. unicorn20089 brings the foundation.

โ„๏ธ Frost - The Wizard

Precision, technical excellence, strategy. Frostystyle brings the architecture.

` } }; // Helper function to generate preview HTML for iframe srcdoc const generatePreviewHtml = (htmlContent) => { return ` Ghost Preview
${htmlContent}
`; }; export default function GhostPageBuilder() { // Two-state pattern: instant input + debounced preview const [htmlInput, setHtmlInput] = useState(''); const [debouncedHtml, setDebouncedHtml] = useState(''); const [viewport, setViewport] = useState('desktop'); const [copied, setCopied] = useState(false); // Load saved draft from localStorage on mount useEffect(() => { const saved = localStorage.getItem('firefrost_ghost_draft'); if (saved) { setHtmlInput(saved); setDebouncedHtml(saved); } else { // Start with simple template if no saved draft setHtmlInput(SAMPLE_TEMPLATES.simple.html); setDebouncedHtml(SAMPLE_TEMPLATES.simple.html); } }, []); // Debounce preview updates and auto-save to localStorage useEffect(() => { const timer = setTimeout(() => { setDebouncedHtml(htmlInput); localStorage.setItem('firefrost_ghost_draft', htmlInput); }, 500); return () => clearTimeout(timer); }, [htmlInput]); // Tab key handler for textarea const handleKeyDown = (e) => { if (e.key === 'Tab') { e.preventDefault(); const start = e.target.selectionStart; const end = e.target.selectionEnd; // Insert two spaces at cursor position const newValue = htmlInput.substring(0, start) + " " + htmlInput.substring(end); setHtmlInput(newValue); // Move cursor after inserted spaces (wait for React state update) setTimeout(() => { e.target.selectionStart = e.target.selectionEnd = start + 2; }, 0); } }; // Copy HTML to clipboard const handleCopy = async () => { try { await navigator.clipboard.writeText(htmlInput); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch (err) { console.error('Failed to copy:', err); } }; // Load sample template const loadTemplate = (templateKey) => { setHtmlInput(SAMPLE_TEMPLATES[templateKey].html); }; // Clear editor const handleReset = () => { if (confirm('Clear the editor? Your current work will be lost.')) { setHtmlInput(''); localStorage.removeItem('firefrost_ghost_draft'); } }; // Viewport dimensions const viewportWidths = { desktop: '100%', tablet: '768px', mobile: '375px' }; return (
{/* Header */}

๐Ÿ”ฅโšกโ„๏ธ Ghost Page Builder

Live preview with Fire + Arcane + Frost CSS

{/* Toolbar */}
{/* Sample Templates Dropdown */}
{/* Viewport Toggle */}
{/* Spacer */}
{/* Action Buttons */}
{/* Main Content: Split Pane */}
{/* Left: Editor */}
HTML Editor