<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Ace Editor • AI + Settings + Save Placeholder + Search</title>
<style>
:root { --bar-h: 48px; --bg: #0f1115; --bar: #151823; --fg: #e8e8e8; --muted:#8a8f98; }
* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body { background: var(--bg); color: var(--fg); font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif; overflow: hidden; }
/* Top bar - responsive layout */
.topbar {
position: fixed; inset: 0 0 auto 0; height: var(--bar-h);
display: grid; grid-template-columns: 1fr auto; align-items: center;
padding: 0 10px; background: var(--bar); border-bottom: 1px solid #222837; z-index: 10;
}
/* Mobile: stack search below main toolbar */
@media (max-width: 768px) {
.topbar {
height: calc(var(--bar-h) * 2);
grid-template-columns: 1fr;
grid-template-rows: var(--bar-h) var(--bar-h);
padding: 0;
}
.main-toolbar {
grid-row: 1;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
}
.search-toolbar {
grid-row: 2;
display: flex;
justify-content: center;
align-items: center;
padding: 0 10px;
border-top: 1px solid #1a1f2d;
}
.search {
width: 100%;
max-width: none;
}
.search input {
width: 100%;
min-width: 0;
}
}
/* Desktop: original layout */
@media (min-width: 769px) {
.topbar {
grid-template-columns: 1fr auto 1fr;
grid-template-areas: "left center right";
}
.main-toolbar {
display: contents;
}
.search-toolbar {
grid-area: center;
justify-self: center;
}
}
.bargroup { display: flex; align-items: center; gap: 8px; }
.left { justify-self: start; }
.right { justify-self: end; }
.iconbtn {
min-width: 40px; height: 34px; padding: 0 12px;
border-radius: 10px; border: 1px solid #2a3144;
background: #1a1f2d; color: #e6e6e6; display: grid; place-items: center; cursor: pointer;
transition: transform .06s ease, background .15s ease, border-color .15s ease;
font-size: 14px; line-height: 1;
}
.iconbtn:hover { background:#22283a; border-color:#3a4562; }
.iconbtn:active { transform: scale(.98); }
/* Save dropdown (placeholder) */
.dropdown { position: relative; }
.menu {
position: absolute; top: calc(100% + 6px); left: 0; min-width: 160px;
background: #0f1422; border: 1px solid #2a3144; border-radius: 10px; padding: 6px;
display: none; z-index: 20; box-shadow: 0 10px 30px rgba(0,0,0,.35);
}
.menu.open { display: block; }
.menu button {
width: 100%; text-align: left; padding: 8px 10px; border-radius: 8px; border: 1px solid transparent;
background: transparent; color: #e7ebf7; cursor: pointer; font: 14px system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
}
.menu button:hover { background: #17203a; border-color: #2e3a5a; }
/* Search */
.search {
display: flex; align-items: center; gap: 6px; background: #10162a;
border: 1px solid #2a3144; border-radius: 10px; padding: 4px 6px;
}
.search-type {
min-width: 80px; height: 28px; padding: 0 4px; border-radius: 6px;
border: 1px solid #2a3144; background: #1a1f2d; color: #e6e6e6;
font-size: 11px; cursor: pointer;
}
.search-type:hover { background: #22283a; border-color: #3a4562; }
.search input {
background: transparent; border: 0; outline: none; color: #e6e9ee; width: 180px;
font: 13px system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
}
.select-toggle {
position: relative; display: flex; align-items: center; cursor: pointer;
width: 24px; height: 24px;
}
.select-toggle input[type="checkbox"] {
position: absolute; opacity: 0; width: 0; height: 0;
}
.checkmark {
position: absolute; top: 0; left: 0; width: 24px; height: 24px;
background: #1a1f2d; border: 1px solid #2a3144; border-radius: 6px;
display: flex; align-items: center; justify-content: center;
color: transparent; font-size: 14px; line-height: 1;
transition: all 0.2s ease;
}
.select-toggle:hover .checkmark { background: #22283a; border-color: #3a4562; }
.select-toggle input:checked + .checkmark {
background: #1b2a4a; border-color: #3a5082; color: #8ab4ff;
}
.search .sbtn {
min-width: 30px; height: 28px; padding: 0 6px; border-radius: 8px;
border: 1px solid #2a3144; background: #1a1f2d; color: #e6e6e6; cursor: pointer;
font-size: 12px;
}
.search .sbtn:hover { background:#22283a; border-color:#3a4562; }
/* Mobile adjustments */
@media (max-width: 768px) {
.search {
gap: 4px; padding: 3px 4px;
}
.search-type {
min-width: 65px; font-size: 10px; padding: 0 3px;
}
.search input {
width: 120px; font-size: 12px;
}
.select-toggle { width: 22px; height: 22px; }
.checkmark { width: 22px; height: 22px; font-size: 12px; }
.search .sbtn {
min-width: 26px; font-size: 11px; padding: 0 4px;
}
}
/* Settings panel */
.panel {
position: fixed; top: calc(var(--bar-h) + 8px); right: 10px; width: 320px;
background: #111521; border: 1px solid #2a3144; border-radius: 12px;
box-shadow: 0 10px 30px rgba(0,0,0,.35); padding: 10px; z-index: 15; display: none;
}
@media (max-width: 768px) {
.panel {
top: calc(var(--bar-h) * 2 + 8px);
right: 10px;
left: 10px;
width: auto;
}
}
.panel.open { display: block; }
.tabs { display: flex; gap: 6px; padding: 6px; background: #0e121c; border-radius: 10px; margin-bottom: 8px; }
.tabbtn {
flex: 1; text-align: center; padding: 8px 10px; border-radius: 8px; cursor: pointer;
border: 1px solid #2a3144; background: #12182a; color: var(--fg); font-size: 13px;
transition: background .15s ease, border-color .15s ease;
}
.tabbtn[aria-selected="true"] { background: #1a2238; border-color: #3a4562; }
.tabpanel { display: none; }
.tabpanel.active { display: block; }
.row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 8px; padding: 8px; border-radius: 8px; }
.row + .row { margin-top: 4px; }
.row label { color: var(--muted); font-size: 12px; }
select, input[type="checkbox"], input[type="range"], input[type="text"] {
accent-color: #8ab4ff; background: #0c0f18; color: #e6e9ee; border: 1px solid #2a3144; border-radius: 8px;
padding: 6px 8px; font: inherit; min-height: 32px;
}
input[type="range"] { width: 140px; padding: 0; height: 28px; }
/* Editor - adjust top margin for mobile */
#editor { position: absolute; top: var(--bar-h); left: 0; right: 0; bottom: 0; }
@media (max-width: 768px) {
#editor { top: calc(var(--bar-h) * 2); }
}
/* AI Overlay (prompt only) */
.overlay {
position: fixed; inset: 0; display: none; z-index: 50;
background: rgba(5,7,12,0.72); backdrop-filter: blur(6px);
}
.overlay.open { display: grid; grid-template-rows: auto 1fr auto; }
.overlay-header {
display: flex; align-items: center; justify-content: space-between;
padding: 10px 14px; background: #0f1422; border-bottom: 1px solid #22283a;
}
.overlay-title { font-weight: 600; color: #dfe5f3; }
.overlay-close {
width: 34px; height: 34px; border-radius: 10px; border: 1px solid #2a3144;
background: #1a1f2d; color: #e6e6e6; display: grid; place-items: center; cursor: pointer;
}
.overlay-body { padding: 10px; overflow: auto; }
.messages { max-width: 1000px; margin: 0 auto; display: grid; gap: 10px; }
.msg { background: #0f1524; border: 1px solid #232c45; border-radius: 12px; padding: 10px 12px; color: #e6ebf5; font-size: 14px; }
.msg.user { background: #152038; border-color: #2a3a5a; }
.msg.assistant { background: #101a2f; border-color: #243356; }
.overlay-footer { border-top: 1px solid #22283a; background: #0f1422; padding: 10px; display: grid; }
.promptbar {
max-width: 1000px; margin: 0 auto; display: grid; grid-template-columns: 1fr auto; gap: 8px; align-items: end;
}
.prompt {
min-height: 44px; max-height: 40vh; resize: none; overflow-y: auto;
padding: 10px 12px; border-radius: 12px;
background: #0c0f18; color: #e6e9ee; border: 1px solid #2a3144;
font: 14px/1.4 system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
}
.askbtn {
height: 44px; padding: 0 16px; border-radius: 12px; border: 1px solid #2a3144;
background: #1b2a4a; color: #e6f0ff; cursor: pointer; font-weight: 600;
}
.askbtn:hover { background: #21335a; }
/* Blocks overlay styles */
.blocks-header {
display: flex; justify-content: space-between; align-items: center;
margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid #2a3144;
}
.blocks-header h3 { color: #dfe5f3; margin: 0; }
.blocks-controls { display: flex; gap: 8px; }
.block-control-btn {
padding: 6px 12px; border-radius: 6px; border: 1px solid #2a3144;
background: #1a1f2d; color: #e6e6e6; font-size: 12px; cursor: pointer;
}
.block-control-btn:hover { background: #22283a; }
.blocks-tree { max-height: 60vh; overflow-y: auto; }
.block-item {
background: #0f1524; border: 1px solid #232c45; border-radius: 8px;
margin-bottom: 8px; transition: all 0.2s ease;
}
.block-item:hover { border-color: #3a4562; }
.block-header {
display: flex; align-items: center; gap: 8px; padding: 10px 12px;
cursor: pointer; user-select: none;
}
.block-toggle {
color: #8a8f98; font-size: 12px; width: 16px; text-align: center;
}
.block-title {
flex: 1; color: #dfe5f3; font-weight: 500; font-size: 14px;
}
.block-info {
color: #8a8f98; font-size: 11px;
}
.block-content {
border-top: 1px solid #1a1f2d; padding: 8px 12px;
background: #0a0d16;
}
.block-preview {
font-family: 'Courier New', monospace; font-size: 12px;
color: #8a8f98; line-height: 1.4; white-space: pre-wrap;
max-height: 60px; overflow: hidden;
}
/* Console styles */
.console-controls {
display: flex; gap: 8px; align-items: center;
}
.console-btn {
width: 32px; height: 32px; border-radius: 8px; border: 1px solid #2a3144;
background: #1a1f2d; color: #e6e6e6; display: grid; place-items: center;
cursor: pointer; font-size: 14px;
}
.console-btn:hover { background: #22283a; }
.console-output {
font-family: 'Courier New', monospace; font-size: 13px; line-height: 1.5;
color: #e6ebf5; background: #0a0d16; border-radius: 8px; padding: 15px;
height: 400px; overflow-y: auto; margin-bottom: 10px;
}
.console-form {
max-width: 1200px; margin: 0 auto; display: grid;
grid-template-columns: 1fr auto; gap: 8px; align-items: center;
}
.console-input {
font-family: 'Courier New', monospace; padding: 10px 12px; border-radius: 8px;
background: #0c0f18; color: #e6e9ee; border: 1px solid #2a3144;
font-size: 13px;
}
.console-submit {
height: 40px; padding: 0 16px; border-radius: 8px; border: 1px solid #2a3144;
background: #1b2a4a; color: #e6f0ff; cursor: pointer; font-weight: 600;
}
.console-submit:hover { background: #21335a; }
.console-line { margin-bottom: 4px; }
.console-input-line { color: #8ab4ff; }
.console-output-line { color: #90ee90; }
.console-error-line { color: #ff9999; }
.console-log-line { color: #e6ebf5; }
</style>
</head>
<body>
<div class="topbar" role="toolbar" aria-label="Toolbar">
<div class="main-toolbar">
<!-- Left: Save dropdown (placeholders) -->
<div class="bargroup left">
<div class="dropdown">
<button id="saveBtn" class="iconbtn" aria-haspopup="true" aria-expanded="false" aria-controls="saveMenu">💾 Save</button>
<div id="saveMenu" class="menu" role="menu">
<button id="doSave" role="menuitem">Save</button>
<button id="doArtifact" role="menuitem">Save Artifact</button>
</div>
</div>
</div>
<!-- Right: Blocks + Console + AI + Settings -->
<div class="bargroup right">
<button id="blocksBtn" class="iconbtn" aria-label="Open blocks overlay">🧩</button>
<button id="consoleBtn" class="iconbtn" aria-label="Open console overlay">📟</button>
<button id="aiBtn" class="iconbtn" aria-label="Open AI overlay">AI</button>
<button id="settingsBtn" class="iconbtn" aria-label="Settings">⚙️</button>
</div>
</div>
<!-- Search -->
<div class="search-toolbar">
<div class="search" role="search">
<select id="searchType" class="search-type" aria-label="Search type">
<option value="normal">Normal</option>
<option value="functions">Functions</option>
<option value="variables">Variables</option>
<option value="divs">Divs/Tags</option>
</select>
<input id="searchInput" type="text" placeholder="Search or navigate with arrows…" aria-label="Search in file" />
<label class="select-toggle" title="Select whole block">
<input id="selectMode" type="checkbox" aria-label="Select whole block">
<span class="checkmark">✓</span>
</label>
<button id="searchPrev" class="sbtn" title="Previous (Shift+Enter)">↑</button>
<button id="searchNext" class="sbtn" title="Next (Enter)">↓</button>
</div>
</div>
</div>
<!-- Settings panel with Editor/AI tabs -->
<div id="panel" class="panel" role="dialog" aria-label="Settings">
<div class="tabs" role="tablist" aria-label="Settings tabs">
<button class="tabbtn" id="tab-editor" role="tab" aria-selected="true" aria-controls="panel-editor">Editor</button>
<button class="tabbtn" id="tab-ai" role="tab" aria-selected="false" aria-controls="panel-ai">AI</button>
</div>
<section id="panel-editor" class="tabpanel active" role="tabpanel" aria-labelledby="tab-editor">
<div class="row">
<label for="theme">Theme</label>
<select id="theme">
<option value="ace/theme/monokai">Monokai (dark)</option>
</select>
</div>
<div class="row">
<label for="fontsize">Font size</label>
<input id="fontsize" type="range" min="10" max="28" value="14" />
</div>
<div class="row">
<label for="wrap">Soft wrap</label>
<input id="wrap" type="checkbox" />
</div>
<div class="row">
<label for="mode">Mode</label>
<select id="mode">
<option value="ace/mode/html">HTML</option>
<option value="ace/mode/javascript">JavaScript</option>
<option value="ace/mode/php">PHP</option>
</select>
</div>
</section>
<section id="panel-ai" class="tabpanel" role="tabpanel" aria-labelledby="tab-ai">
<div class="row">
<label for="ai-provider">Provider</label>
<select id="ai-provider">
<option value="none">None</option>
<option value="openai">OpenAI</option>
<option value="deepseek">DeepSeek</option>
<option value="anthropic">Claude</option>
</select>
</div>
<div class="row">
<label for="ai-model">Model</label>
<input id="ai-model" type="text" placeholder="e.g. gpt-4o, deepseek-chat" />
</div>
<div class="row">
<label for="ai-temp">Temperature</label>
<input id="ai-temp" type="range" min="0" max="2" step="0.1" value="0.4" />
</div>
<div class="row">
<label for="ai-key">API Key</label>
<input id="ai-key" type="text" placeholder="sk-..." />
</div>
</section>
</div>
<!-- Fullscreen Blocks overlay -->
<div id="blocksOverlay" class="overlay" aria-modal="true" role="dialog" aria-labelledby="blocksTitle">
<div class="overlay-header">
<div id="blocksTitle" class="overlay-title">Visual Blocks</div>
<button id="blocksClose" class="overlay-close" aria-label="Close">✕</button>
</div>
<div class="overlay-body">
<div id="blocksCanvas" class="blocks-canvas"></div>
</div>
</div>
<!-- Fullscreen Console overlay -->
<div id="consoleOverlay" class="overlay" aria-modal="true" role="dialog" aria-labelledby="consoleTitle">
<div class="overlay-header">
<div id="consoleTitle" class="overlay-title">Console</div>
<div class="console-controls">
<button id="clearConsole" class="console-btn" title="Clear console">🗑️</button>
<button id="runCode" class="console-btn" title="Run code">▶️</button>
</div>
<button id="consoleClose" class="overlay-close" aria-label="Close">✕</button>
</div>
<div class="overlay-body">
<div id="consoleOutput" class="console-output" aria-live="polite"></div>
</div>
<div class="overlay-footer">
<form id="consoleForm" class="console-form">
<input id="consoleInput" class="console-input" placeholder="Enter JavaScript command..." autocomplete="off" />
<button class="console-submit" type="submit">Run</button>
</form>
</div>
</div>
<!-- Fullscreen AI prompt overlay -->
<div id="aiOverlay" class="overlay" aria-modal="true" role="dialog" aria-labelledby="aiTitle">
<div class="overlay-header">
<div id="aiTitle" class="overlay-title">AI Assistant</div>
<button id="overlayClose" class="overlay-close" aria-label="Close">✕</button>
</div>
<div class="overlay-body">
<div id="messages" class="messages" aria-live="polite" aria-relevant="additions"></div>
</div>
<div class="overlay-footer">
<form id="promptForm" class="promptbar">
<textarea id="prompt" class="prompt" placeholder="Ask anything about the code… (paste or type, it expands)" rows="1"></textarea>
<button class="askbtn" id="askBtn" type="submit">Ask</button>
</form>
</div>
</div>
<div id="editor"></div>
<!-- Ace (minimal) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.6/ace.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.6/ext-language_tools.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.6/mode-html.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.6/mode-javascript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.6/mode-php.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.6/theme-monokai.min.js"></script>
<script src="editor.js"></script>
<script src="navigation.js"></script>
<script src="save.js"></script>
<script src="blocksCore.js"></script> <!-- Load core first -->
<script src="blocksView.js"></script> <!-- Then view -->
<script src="blocksControl.js"></script> <!-- Finally controller -->
<script src="console.js"></script>
<script src="ai.js"></script>
</body>
</html>