AXIS_CODER / index.tsx
sudo-saidso's picture
Update index.tsx
9b487d5 verified
import React, { useState, useEffect, useRef } from 'react';
import { createRoot } from 'react-dom/client';
import { GoogleGenAI } from "@google/genai";
import {
ChevronDown, Github, FileText, ArrowLeft, Cpu, Globe, Zap,
Code2, Copy, Check, Trash2, Download, Upload, Play, Eye,
Code as CodeIcon, Sun, Moon, Sparkles
} from 'lucide-react';
// --- Types & Config ---
declare global {
interface Window { Prism: any; }
}
type ViewState = 'app' | 'docs' | 'editor';
type Theme = 'dark' | 'light';
const LANGUAGES = [
'JavaScript', 'TypeScript', 'Python', 'Java', 'C++', 'C#',
'Go', 'Rust', 'Swift', 'Kotlin', 'PHP', 'Ruby', 'SQL', 'HTML', 'CSS',
'Bash', 'JSON', 'YAML', 'Markdown', 'Natural Language'
];
const LANGUAGE_MAP: Record<string, string> = {
'JavaScript': 'javascript', 'TypeScript': 'typescript', 'Python': 'python',
'Java': 'java', 'C++': 'cpp', 'C#': 'csharp', 'Go': 'go', 'Rust': 'rust',
'Swift': 'swift', 'Kotlin': 'kotlin', 'PHP': 'php', 'Ruby': 'ruby',
'SQL': 'sql', 'HTML': 'markup', 'CSS': 'css', 'Bash': 'bash',
'JSON': 'json', 'YAML': 'yaml', 'Markdown': 'markdown', 'Natural Language': 'text'
};
const SHARED_CODE_STYLES: React.CSSProperties = {
fontFamily: '"JetBrains Mono", monospace',
fontSize: '0.875rem',
lineHeight: '1.625rem',
padding: '1rem',
whiteSpace: 'pre',
wordSpacing: 'normal',
wordBreak: 'normal',
tabSize: 2,
MozTabSize: 2,
boxSizing: 'border-box',
};
// --- Logic: Language Detection ---
const detectLanguage = (code: string): string => {
if (!code.trim()) return 'Natural Language';
const snippets = {
HTML: /<[a-z][\s\S]*>/i,
JSON: /^[\s]*[\{\[]/,
SQL: /\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|CREATE|DROP)\b/i,
Python: /\b(def|import|if __name__ == "__main__":|print\(f?['"])\b/,
JavaScript: /\b(const|let|var|function|async|await|console\.log)\b/,
Rust: /\b(fn|pub|use|let mut|match|impl)\b/,
Go: /\b(package|import|func|go\s|chan|select)\b/,
Swift: /\b(import|let|var|func|enum|struct|extension)\b/,
Bash: /#!\/bin\/(bash|sh)|sudo\s/,
Markdown: /^#\s|!\[.*\]\(.*\)|\[.*\]\(.*\)/m,
YAML: /^[\w-]+:\s/m,
CSS: /[\.#][\w-]+\s*\{/
};
for (const [lang, regex] of Object.entries(snippets)) {
if (regex.test(code)) return lang;
}
return 'Natural Language';
};
const parseMarkdownToHTML = (text: string) => {
return text
.replace(/^### (.*$)/gim, '<h3>$1</h3>')
.replace(/^## (.*$)/gim, '<h2>$1</h2>')
.replace(/^# (.*$)/gim, '<h1>$1</h1>')
.replace(/\*\*(.*)\*\*/gim, '<b>$1</b>')
.replace(/\*(.*)\*/gim, '<i>$1</i>')
.replace(/!\[(.*?)\]\((.*?)\)/gim, "<img alt='$1' src='$2' />")
.replace(/\[(.*?)\]\((.*?)\)/gim, "<a href='$2'>$1</a>")
.replace(/`([^`]+)`/g, '<code>$1</code>')
.replace(/^\s*-\s+(.*)/gim, '<li>$1</li>')
.replace(/(<li>.*<\/li>)/gim, '<ul>$1</ul>')
.replace(/<\/ul>\s*<ul>/gim, '')
.replace(/\n$/gim, '<br />');
};
// --- Shared Components ---
const LogoSVG = ({ className, theme }: { className?: string, theme: Theme }) => (
<svg className={className} width="32" height="32" viewBox="0 0 65 65" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M32.447 0c.68 0 1.272.465 1.438 1.125a39 39 0 0 0 2 5.905q3.23 7.5 8.854 13.125q5.626 5.626 13.125 8.855a39 39 0 0 0 5.905 1.999c.66.166 1.125.758 1.125 1.438s-.464 1.273-1.125 1.439a39 39 0 0 0-5.905 1.999q-7.5 3.23-13.125 8.854q-5.625 5.627-8.854 13.125a39 39 0 0 0-2 5.906a1.485 1.485 0 0 1-1.438 1.124c-.68 0-1.272-.464-1.438-1.125a39 39 0 0 0-2-5.905q-3.228-7.5-8.854-13.125T7.03 35.885a39 39 0 0 0-5.905-2A1.485 1.485 0 0 1 0 32.448c0-.68.465-1.272 1.125-1.438a39 39 0 0 0 5.905-2q7.5-3.229 13.125-8.854C25.78 14.53 26.857 12.03 29.01 7.03a39 39 0 0 0 1.999-5.905A1.485 1.485 0 0 1 32.447 0" fill="url(#logo-grad)"/>
<defs>
<linearGradient id="logo-grad" x1="18.447" x2="52.153" y1="43.42" y2="15.004" gradientUnits="userSpaceOnUse">
<stop offset="0" stopColor={theme === 'dark' ? "#4893fc" : "#2563eb"}/><stop offset="1" stopColor={theme === 'dark' ? "#bd99fe" : "#9333ea"}/>
</linearGradient>
</defs>
</svg>
);
const Toast = ({ message, onClose }: { message: string; onClose: () => void }) => {
useEffect(() => { const timer = setTimeout(onClose, 3000); return () => clearTimeout(timer); }, [onClose]);
return (
<div className="fixed bottom-8 left-1/2 -translate-x-1/2 z-[100] animate-[slideUp_0.3s_ease-out]">
<div className="bg-neutral-900/90 border border-gray-700 text-white px-4 py-2 rounded-lg shadow-2xl backdrop-blur-md flex items-center gap-2 text-sm font-mono">
<span className="text-cyan-400"></span> {message}
</div>
</div>
);
};
const LanguageSelect = ({ language, onChange, theme }: { language: string; onChange: (val: string) => void; theme: Theme }) => {
const [isOpen, setIsOpen] = useState(false);
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const click = (e: MouseEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setIsOpen(false); };
document.addEventListener('mousedown', click); return () => document.removeEventListener('mousedown', click);
}, []);
return (
<div className="relative w-full" ref={ref}>
<button onClick={() => setIsOpen(!isOpen)} className={`w-full flex items-center justify-between border px-4 py-3 rounded-lg backdrop-blur-sm transition-all text-sm font-mono ${theme === 'dark' ? 'bg-black/40 border-cyan-500/30 text-cyan-400 hover:border-cyan-500/60' : 'bg-white border-gray-200 text-gray-900 hover:border-cyan-500 shadow-sm'}`}>
<span>{language}</span>
<ChevronDown size={16} className={`transition-transform ${isOpen ? 'rotate-180' : ''}`} />
</button>
{isOpen && (
<div className={`absolute top-full left-0 right-0 mt-2 max-h-60 overflow-y-auto border rounded-lg shadow-xl z-50 custom-scrollbar ${theme === 'dark' ? 'bg-neutral-900 border-gray-800' : 'bg-white border-gray-200'}`}>
{LANGUAGES.map((lang) => (
<button key={lang} onClick={() => { onChange(lang); setIsOpen(false); }} className={`w-full text-left px-4 py-2 text-sm font-mono transition-colors ${language === lang ? 'bg-cyan-500/10 text-cyan-500' : theme === 'dark' ? 'text-gray-400 hover:bg-gray-800' : 'text-gray-600 hover:bg-gray-100'}`}>
{lang}
</button>
))}
</div>
)}
</div>
);
};
const CodeEditor = ({ code, language, onChange, readOnly = false, placeholder, theme }: { code: string; language: string; onChange?: (val: string) => void; readOnly?: boolean; placeholder?: string; theme: Theme }) => {
const textareaRef = useRef<HTMLTextAreaElement>(null);
const preRef = useRef<HTMLPreElement>(null);
const [highlightedCode, setHighlightedCode] = useState('');
useEffect(() => {
const prismLang = LANGUAGE_MAP[language] || 'text';
if (window.Prism && window.Prism.languages[prismLang]) {
setHighlightedCode(window.Prism.highlight(code || '', window.Prism.languages[prismLang], prismLang));
} else {
setHighlightedCode((code || '').replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"));
}
}, [code, language]);
const syncScroll = () => { if (textareaRef.current && preRef.current) { preRef.current.scrollTop = textareaRef.current.scrollTop; preRef.current.scrollLeft = textareaRef.current.scrollLeft; } };
return (
<div className="relative w-full h-full overflow-hidden">
<pre ref={preRef} aria-hidden="true" style={SHARED_CODE_STYLES} className="absolute inset-0 m-0 pointer-events-none !bg-transparent overflow-hidden z-0">
<code className={`language-${LANGUAGE_MAP[language] || 'text'} !bg-transparent !p-0 block min-w-full`} dangerouslySetInnerHTML={{ __html: highlightedCode + '\n' }} />
</pre>
<textarea ref={textareaRef} value={code} onChange={(e) => onChange && onChange(e.target.value)} onScroll={syncScroll} readOnly={readOnly} placeholder={placeholder} style={SHARED_CODE_STYLES} className="absolute inset-0 w-full h-full bg-transparent text-transparent caret-cyan-500 resize-none focus:outline-none placeholder-gray-500 overflow-auto custom-scrollbar border-none ring-0 z-10" spellCheck={false} />
</div>
);
};
const EditorFooter = ({ onClear, textToCopy, colorClass, theme }: { onClear?: () => void; textToCopy: string; colorClass: string; theme: Theme }) => {
const [copied, setCopied] = useState(false);
const handleCopy = async () => { if (!textToCopy) return; await navigator.clipboard.writeText(textToCopy); setCopied(true); setTimeout(() => setCopied(false), 2000); };
return (
<div className={`flex items-center justify-end gap-4 px-4 py-2 border-t backdrop-blur-sm ${theme === 'dark' ? 'border-white/5 bg-black/20' : 'border-gray-100 bg-gray-50'}`}>
{onClear && (
<button onClick={onClear} className={`flex items-center gap-2 text-[10px] font-mono opacity-50 hover:opacity-100 hover:text-red-500 transition-all ${colorClass}`}>
<Trash2 size={12} /> CLEAR
</button>
)}
<button onClick={handleCopy} className={`flex items-center gap-2 text-[10px] font-mono opacity-50 hover:opacity-100 transition-all ${colorClass}`}>
{copied ? <Check size={12} className="text-green-500" /> : <Copy size={12} />} {copied ? 'COPIED' : 'COPY'}
</button>
</div>
);
};
const Snippet = ({ code, filename, theme }: { code: string; filename: string; theme: Theme }) => {
const [copied, setCopied] = useState(false);
const handleCopy = async () => { await navigator.clipboard.writeText(code); setCopied(true); setTimeout(() => setCopied(false), 2000); };
return (
<div className={`rounded-xl overflow-hidden border mb-4 ${theme === 'dark' ? 'bg-neutral-950 border-white/5' : 'bg-gray-50 border-gray-200 shadow-sm'}`}>
<div className={`flex items-center justify-between px-4 py-3 border-b ${theme === 'dark' ? 'border-white/5 bg-white/5' : 'border-gray-200 bg-gray-100'}`}>
<div className="flex items-center gap-2">
<div className="w-2 h-2 rounded-full bg-red-500/40" /><div className="w-2 h-2 rounded-full bg-yellow-500/40" /><div className="w-2 h-2 rounded-full bg-green-500/40" />
<span className="ml-2 text-[10px] font-mono text-gray-500 uppercase tracking-widest">{filename}</span>
</div>
<button onClick={handleCopy} className={`text-xs font-mono transition-colors ${theme === 'dark' ? 'text-gray-400 hover:text-white' : 'text-gray-500 hover:text-black'}`}>
{copied ? 'COPIED' : 'COPY'}
</button>
</div>
<div className={`p-6 font-mono text-sm leading-relaxed overflow-x-auto custom-scrollbar ${theme === 'dark' ? 'text-gray-400 bg-black/40' : 'text-gray-700 bg-white'}`}>
<pre className="whitespace-pre">{code}</pre>
</div>
</div>
);
};
// --- View Components ---
const DocsView = ({ onBack, theme }: { onBack: () => void; theme: Theme }) => {
const jsCode = `// Prime Discovery Logic
function findPrimes(limit) {
const results = [];
for (let i = 2; i <= limit; i++) {
let isPrime = true;
for (let j = 2; j <= Math.sqrt(i); j++) {
if (i % j === 0) { isPrime = false; break; }
}
if (isPrime) results.push(i);
}
return results;
}
const primes = findPrimes(50);
console.log("Calculated Primes:", primes);`;
const htmlCode = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Prime Discovery</title>
</head>
<body>
<script>
${jsCode}
</script>
</body>
</html>`;
return (
<div className="relative z-30 flex-1 w-full max-w-[900px] mx-auto px-4 pb-20 animate-[fadeIn_0.5s_ease-out]">
<div className="mb-12">
<button onClick={onBack} className={`flex items-center gap-2 text-xs font-mono transition-colors group ${theme === 'dark' ? 'text-cyan-400' : 'text-cyan-600'}`}>
<ArrowLeft size={16} className="group-hover:-translate-x-1 transition-transform" /> RETURN_TO_SYSTEM
</button>
</div>
<header className={`mb-16 border-b pb-12 ${theme === 'dark' ? 'border-white/5' : 'border-gray-200'}`}>
<div className={`inline-block px-3 py-1 rounded-full border text-[10px] font-mono mb-4 tracking-widest uppercase ${theme === 'dark' ? 'bg-cyan-500/10 border-cyan-500/20 text-cyan-400' : 'bg-cyan-50 border-cyan-200 text-cyan-700'}`}>Documentation V3.0</div>
<h2 className={`text-4xl sm:text-5xl font-black tracking-tighter mb-6 ${theme === 'dark' ? 'text-white' : 'text-gray-900'}`}>Master the <span className="text-transparent bg-gradient-to-r from-cyan-400 to-purple-500 bg-clip-text">AXIS</span> Engine</h2>
<p className={`font-mono text-sm leading-relaxed max-w-2xl ${theme === 'dark' ? 'text-gray-400' : 'text-gray-600'}`}>AXIS is a precision tool for code translation and multi-language logic synthesis.</p>
</header>
<div className="space-y-12">
<section>
<div className="flex items-center gap-3 mb-8">
<div className={`w-8 h-8 rounded-lg flex items-center justify-center border ${theme === 'dark' ? 'bg-purple-500/20 border-purple-500/30 text-purple-400' : 'bg-purple-50 border-purple-200 text-purple-600'}`}><CodeIcon size={18} /></div>
<h3 className={`text-xl font-bold ${theme === 'dark' ? 'text-white' : 'text-gray-900'}`}>Standard Workflow</h3>
</div>
<Snippet code={jsCode} filename="prime_discovery.js" theme={theme} />
<div className="py-6 text-center"><span className={`font-mono text-[10px] uppercase tracking-widest ${theme === 'dark' ? 'text-gray-500' : 'text-gray-400'}`}>Targeting <span className="text-pink-500">HTML</span> Output:</span></div>
<Snippet code={htmlCode} filename="index.html" theme={theme} />
</section>
</div>
</div>
);
};
const RichTextEditor = ({ onBack, theme }: { onBack: () => void; theme: Theme }) => {
const [code, setCode] = useState('# AXIS Workspace\n\nEdit Markdown or HTML here.\n\n## Subheading\n\n- Bullet point 1\n- Bullet point 2\n\nThis is **bold** text.');
const [mode, setMode] = useState<'edit' | 'preview' | 'split'>('split');
const [copied, setCopied] = useState(false);
const getPreviewContent = () => {
// Check if it's already a full HTML doc
if (code.trim().toLowerCase().startsWith('<!doctype html') || code.trim().toLowerCase().startsWith('<html')) {
return code;
}
const parsed = parseMarkdownToHTML(code);
return `
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
color: #24292f;
padding: 2.5rem;
line-height: 1.6;
background: #ffffff;
min-height: 100vh;
}
h1, h2, h3 {
color: #1f2328;
margin-top: 24px;
margin-bottom: 16px;
font-weight: 600;
line-height: 1.25;
}
h1 { border-bottom: 1px solid #d0d7de; padding-bottom: 0.3em; font-size: 2em; }
h2 { border-bottom: 1px solid #d0d7de; padding-bottom: 0.3em; font-size: 1.5em; }
p { margin-top: 0; margin-bottom: 16px; }
code {
background-color: rgba(175, 184, 193, 0.2);
padding: 0.2em 0.4em;
border-radius: 6px;
font-family: "JetBrains Mono", monospace;
font-size: 85%;
}
ul { padding-left: 2em; margin-bottom: 16px; }
li { margin-bottom: 0.25rem; }
a { color: #0969da; text-decoration: none; }
a:hover { text-decoration: underline; }
</style>
</head>
<body>${parsed}</body>
</html>
`;
};
const handleCopy = async () => { if (!code) return; await navigator.clipboard.writeText(code); setCopied(true); setTimeout(() => setCopied(false), 2000); };
const handleExport = () => {
const blob = new Blob([code], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a'); a.href = url; a.download = 'axis_note.txt'; a.click();
};
return (
<div className="relative z-30 flex-1 w-full max-w-[1200px] mx-auto px-4 pb-10 animate-[fadeIn_0.5s_ease-out]">
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between mb-4 gap-4">
<button onClick={onBack} className={`flex items-center gap-2 text-[10px] font-mono font-bold tracking-[0.2em] transition-all uppercase ${theme === 'dark' ? 'text-cyan-400/60 hover:text-cyan-400' : 'text-cyan-600/60 hover:text-cyan-600'}`}>
<ArrowLeft size={14} /> EXIT_WORKSPACE
</button>
<div className={`flex p-1 rounded-lg border w-full sm:w-auto ${theme === 'dark' ? 'bg-black/40 border-white/10' : 'bg-gray-100 border-gray-200'}`}>
{['edit', 'preview', 'split'].map((m) => (
<button key={m} onClick={() => setMode(m as any)} className={`flex-1 sm:flex-none px-3 py-1 rounded text-[10px] font-mono transition-all uppercase ${mode === m ? (theme === 'dark' ? 'bg-cyan-500 text-black' : 'bg-white text-black shadow-sm') : 'text-gray-500 hover:text-gray-400'}`}>
{m}
</button>
))}
</div>
</div>
<div className={`border rounded-2xl overflow-hidden shadow-2xl flex flex-col h-[65vh] sm:h-[75vh] ${theme === 'dark' ? 'bg-neutral-900 border-white/10' : 'bg-white border-gray-200'}`}>
<div className={`flex-1 flex ${mode === 'split' ? 'flex-col lg:flex-row' : 'flex-col'} overflow-hidden`}>
{(mode === 'edit' || mode === 'split') && (
<div className={`flex-1 ${mode === 'split' ? 'border-b lg:border-b-0 lg:border-r border-white/5' : ''} ${theme === 'dark' ? 'bg-black/20' : 'bg-gray-50/50'}`}>
<CodeEditor code={code} language="Markdown" onChange={setCode} placeholder="Source logic..." theme={theme} />
</div>
)}
{(mode === 'preview' || mode === 'split') && (
<div className="flex-1 bg-white relative">
<iframe srcDoc={getPreviewContent()} title="prev" className="w-full h-full border-none" />
</div>
)}
</div>
<div className={`px-4 py-3 border-t flex flex-wrap items-center justify-between text-[10px] font-mono uppercase gap-2 ${theme === 'dark' ? 'border-white/5 bg-black/40 text-gray-500' : 'border-gray-100 bg-gray-50 text-gray-400'}`}>
<div className="flex gap-4"><button onClick={() => setCode('')} className="hover:text-red-500 transition-colors">Clear</button><span>Chars: {code.length}</span></div>
<div className="flex gap-4">
<button onClick={handleCopy} className="hover:text-cyan-500 transition-colors">{copied ? 'COPIED' : 'COPY'}</button>
<button onClick={handleExport} className="hover:text-cyan-500 transition-colors">Export</button>
</div>
</div>
</div>
</div>
);
};
// --- Main Application ---
const App = () => {
const [view, setView] = useState<ViewState>('app');
const [theme, setTheme] = useState<Theme>('dark');
const [inputCode, setInputCode] = useState('');
const [outputCode, setOutputCode] = useState('');
const [outputLanguage, setOutputLanguage] = useState('Python');
const [loading, setLoading] = useState(false);
const [toast, setToast] = useState('');
const inputLanguage = detectLanguage(inputCode);
useEffect(() => {
document.body.className = theme === 'light' ? 'light-mode' : '';
}, [theme]);
const toggleTheme = () => setTheme(prev => prev === 'dark' ? 'light' : 'dark');
const handleTranslate = async () => {
if (!inputCode.trim()) { setToast('Enter code to sync.'); return; }
setLoading(true); setOutputCode('');
try {
const response = await fetch('/api/translate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ inputCode, outputLanguage })
});
const data = await response.json();
setOutputCode(data.code || '');
} catch {
setToast('Synthesis failed.');
} finally {
setLoading(false);
}
};
const handleDispatch = () => {
const extMap: Record<string, string> = {
'JavaScript': 'js', 'TypeScript': 'ts', 'Python': 'py', 'Java': 'java', 'C++': 'cpp',
'C#': 'cs', 'Go': 'go', 'Rust': 'rs', 'Swift': 'swift', 'Kotlin': 'kt', 'PHP': 'php',
'Ruby': 'rb', 'SQL': 'sql', 'HTML': 'html', 'CSS': 'css', 'Bash': 'sh', 'JSON': 'json',
'YAML': 'yaml', 'Markdown': 'md'
};
const ext = extMap[outputLanguage] || 'txt';
const blob = new Blob([outputCode], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a'); a.href = url; a.download = `axis_build.${ext}`; a.click();
setToast(`File dispatched: axis_build.${ext}`);
};
return (
<div className={`relative min-h-screen flex flex-col transition-colors duration-500 overflow-x-hidden ${theme === 'dark' ? 'bg-black text-white' : 'bg-gray-50 text-gray-900'}`}>
{/* Background Layer */}
<div className="grid-bg" />
<div className="glow-orb glow-orb-1" />
<div className="glow-orb glow-orb-2" />
<header className="px-4 py-6 sm:py-10 flex flex-col items-center justify-center relative z-20 w-full">
{/* Navigation Wrapper */}
<div className="flex w-full max-w-[1400px] justify-between items-start mb-6 sm:mb-0">
{/* Left Buttons */}
<div className="flex flex-col sm:flex-row gap-2">
<button onClick={() => setView(view === 'editor' ? 'app' : 'editor')} className={`p-2 rounded-lg border flex items-center justify-center gap-2 transition-all w-28 sm:w-32 ${theme === 'dark' ? 'bg-black/20 border-white/10 text-gray-400 hover:text-white' : 'bg-white border-gray-200 text-gray-600 hover:text-black shadow-sm'}`}>
<Github size={18} /><span className="text-[10px] font-mono uppercase tracking-widest">Editor</span>
</button>
<button onClick={() => setView(view === 'docs' ? 'app' : 'docs')} className={`p-2 rounded-lg border flex items-center justify-center gap-2 transition-all w-28 sm:w-32 ${theme === 'dark' ? 'bg-black/20 border-white/10 text-gray-400 hover:text-white' : 'bg-white border-gray-200 text-gray-600 hover:text-black shadow-sm'}`}>
<FileText size={18} /><span className="text-[10px] font-mono uppercase tracking-widest">Docs</span>
</button>
</div>
{/* Right Toggle */}
<button onClick={toggleTheme} className={`p-2 rounded-lg border transition-all ${theme === 'dark' ? 'bg-black/20 border-white/10 text-yellow-500' : 'bg-white border-gray-200 text-gray-600 hover:text-blue-600 shadow-sm'}`}>
{theme === 'dark' ? <Sun size={20} /> : <Moon size={20} />}
</button>
</div>
<h1 className="bg-gradient-to-r from-cyan-400 via-pink-500 to-purple-600 bg-clip-text text-5xl sm:text-7xl font-black text-transparent tracking-tighter uppercase mb-2 select-none">AXIS</h1>
<div className="font-mono text-[9px] sm:text-[10px] uppercase tracking-[0.4em] opacity-40 text-center">aligned. integrated. syntax.</div>
</header>
{view === 'app' ? (
<main className="flex-1 w-full max-w-[1400px] mx-auto px-4 pb-20 flex flex-col lg:flex-row gap-10 z-20">
{/* Ingestion Section */}
<div className="flex-1 flex flex-col space-y-4">
<div className="flex items-center justify-between">
<span className={`text-[11px] font-bold tracking-[0.2em] uppercase ${theme === 'dark' ? 'text-cyan-400' : 'text-cyan-600'}`}>Source Ingestion</span>
<div className={`flex items-center gap-2 px-3 py-1 rounded-full border text-[9px] font-mono ${theme === 'dark' ? 'bg-cyan-500/10 border-cyan-500/20 text-cyan-400' : 'bg-cyan-50 border-cyan-200 text-cyan-700'}`}>
<Sparkles size={10} /> {inputLanguage.toUpperCase()}
</div>
</div>
<div className={`h-[400px] sm:h-[600px] flex flex-col rounded-2xl border-2 overflow-hidden shadow-2xl transition-all duration-300 ${theme === 'dark' ? 'border-cyan-500/20 bg-black/60 focus-within:border-cyan-500/40' : 'border-gray-200 bg-white focus-within:border-cyan-500/40'}`}>
<CodeEditor code={inputCode} language={inputLanguage} onChange={setInputCode} theme={theme} placeholder="// Paste Source Logic..." />
<EditorFooter onClear={() => setInputCode('')} textToCopy={inputCode} colorClass="text-cyan-500" theme={theme} />
</div>
<button onClick={handleTranslate} disabled={loading} className={`w-full py-4 sm:py-5 rounded-xl font-black uppercase tracking-[0.2em] transition-all shadow-xl text-sm sm:text-base ${loading ? 'opacity-50 cursor-wait' : 'bg-cyan-500 text-black hover:scale-[1.01] active:scale-95'}`}>{loading ? 'Synthesizing...' : 'Apply Engine'}</button>
</div>
{/* Output Section */}
<div className="flex-1 flex flex-col space-y-4">
<span className={`text-[11px] font-bold tracking-[0.2em] uppercase ${theme === 'dark' ? 'text-pink-500' : 'text-pink-600'}`}>Neural Output</span>
<LanguageSelect language={outputLanguage} onChange={setOutputLanguage} theme={theme} />
<div className={`h-[400px] sm:h-[600px] flex flex-col rounded-2xl border-2 overflow-hidden shadow-2xl transition-all duration-300 ${theme === 'dark' ? 'border-pink-500/20 bg-black/60 focus-within:border-pink-500/40' : 'border-gray-200 bg-white focus-within:border-pink-500/40'}`}>
<CodeEditor code={outputCode} language={outputLanguage} readOnly theme={theme} placeholder="// Logic Stream Output..." />
<EditorFooter textToCopy={outputCode} colorClass="text-pink-500" theme={theme} />
</div>
<button onClick={handleDispatch} disabled={!outputCode} className={`w-full py-4 sm:py-5 rounded-xl font-black uppercase tracking-[0.2em] border transition-all text-sm sm:text-base ${theme === 'dark' ? 'bg-neutral-900 border-white/5 text-white hover:bg-neutral-800' : 'bg-white border-gray-200 text-gray-900 hover:bg-gray-50 shadow-sm active:scale-95'}`}>Dispatch Build</button>
</div>
</main>
) : view === 'docs' ? <DocsView onBack={() => setView('app')} theme={theme} /> : <RichTextEditor onBack={() => setView('app')} theme={theme} />}
<footer className="relative z-20 pb-12 pt-8 w-full flex flex-col items-center justify-center gap-6 px-4">
<a href="https://axis.jessejesse.com" target="_blank" rel="noreferrer" className={`font-mono text-[10px] sm:text-sm font-bold transition-opacity uppercase tracking-widest text-center ${theme === 'dark' ? 'text-white/60 hover:text-white' : 'text-black/60 hover:text-black'}`}>axis.jessejesse.com</a>
<LogoSVG theme={theme} className={`mx-auto transition-all hover:scale-110 ${theme === 'dark' ? 'grayscale opacity-50 hover:grayscale-0 hover:opacity-100' : ''}`} />
</footer>
{toast && <Toast message={toast} onClose={() => setToast('')} />}
</div>
);
};
const root = createRoot(document.getElementById('root')!);
root.render(<App />);