\n
My Page
\n
Hello, World!
Edit this HTML, insert snippets, or ask the AI to build something.
\n
Getting started
Tap Build to generate code from a description, or switch to Code tab to edit directly.
\n
Try asking: "make a calculator", "landing page for a coffee shop", "quiz app"
\n
\n\n';
hbEd.value = DEFAULT_HTML_HB;
/* AI panel inside code pane (for quick edits while coding) */
const hbAIPanel=el('div',{className:'hb-ai-panel'});
const hbAIPanelTa=el('textarea',{className:'hb-ai-panel-ta',placeholder:'Describe an edit... Enter to apply'});
hbAIPanelTa.setAttribute('rows','2');
const hbAIPanelRow=el('div',{className:'hb-ai-panel-row'});
const hbAIPanelBuild=txt('button','Apply',{className:'hb-ai-panel-build'});
const hbAIPanelSuggest=txt('button','Edit',{className:'hb-btn',style:'font-size:10px;',title:'Suggest an edit'});
const hbAIPanelSt=txt('span','',{className:'hb-ai-panel-st'});
const hbAIPanelModel=el('span',{style:'font-size:9px;color:var(--muted);flex-shrink:0;'});
hbAIPanelRow.append(hbAIPanelBuild,hbAIPanelSuggest,hbAIPanelSt,hbAIPanelModel);
hbAIPanel.append(hbAIPanelTa,hbAIPanelRow);
hbCodePane.append(hbAIPanel,hbGutter,hbLineHL,hbEd);
/* hbEP alias for compat with existing code */
const hbEP=hbCodePane;
hbLeft.append(hbChatPane,hbCodePane);
hbWS.appendChild(hbLeft);
const hbDiv = el('div',{className:'hb-div',style:{display:'none'}});
hbWS.appendChild(hbDiv);
/* ── RIGHT PANE — Preview (always visible) ── */
const hbRight = el('div',{className:'hb-right',style:{flex:'1',display:'flex',flexDirection:'column',overflow:'hidden'}});
/* hbLog kept for compat but hidden */
const hbLog = el('div',{className:'hb-log',id:'hbLog',style:'display:none;'});
const hbLogHeader = el('div',{className:'hb-log-header'});
hbLogHeader.appendChild(txt('span','AI Chat Log',{className:'hb-log-title'}));
const hbLogClearBtn = txt('button','Clear',{className:'hb-log-clear'});
hbLogClearBtn.onclick=()=>{hbLogMsgs.innerHTML='';};
hbLogHeader.appendChild(hbLogClearBtn);
hbLog.appendChild(hbLogHeader);
const hbLogResize = el('div',{className:'hb-log-resize'});
hbRight.append(hbLog, hbLogResize);
const hbPP = el('div',{className:'hb-pp',style:{flex:'1'}});
const hbPBar = el('div',{className:'hb-pbar'});
[{bg:'#f55'},{bg:'#fa3'},{bg:'#4c4'}].forEach(({bg})=>hbPBar.appendChild(el('div',{className:'hb-pdot',style:{background:bg}})));
const hbPUrl = txt('span','about:blank',{className:'hb-purl'});
const hbPSz = txt('span','',{className:'hb-psz'});
const hbPFull = txt('button','',{title:'Fullscreen preview',style:{background:'none',border:'none',cursor:'pointer',fontSize:'14px',padding:'0 4px',color:'#888',lineHeight:'1',flexShrink:'0'}});
hbPFull.onclick=()=>hbOpenFullPreview();
hbPBar.append(hbPUrl,hbPSz,hbPFull);
hbPP.appendChild(hbPBar);
const hbFrame = el('iframe',{className:'hb-iframe'});
hbFrame.sandbox='allow-scripts allow-forms allow-popups';
hbPP.appendChild(hbFrame);
hbRight.appendChild(hbPP);
hbWS.appendChild(hbRight);
hbWrap.appendChild(hbWS);
const hbStatusBar = el('div',{className:'hb-statusbar'});
const hbSB_Pos = txt('span','L1:1',{className:'hb-sb-item',id:'hbSBPos'});
const hbSB_Lines = txt('span','',{className:'hb-sb-item',id:'hbSBLns'});
const hbSB_Sep1 = txt('span','·',{className:'hb-sb-sep'});
const hbSB_Chars = txt('span','',{className:'hb-sb-item',id:'hbSBChs'});
const hbSB_Sep2 = txt('span','·',{className:'hb-sb-sep'});
const hbSB_Sel = txt('span','',{className:'hb-sb-item',id:'hbSBSel'});
const hbSB_Sep3 = txt('span','·',{className:'hb-sb-sep'});
const hbSB_Color = el('span',{className:'hb-sb-item',id:'hbSBColor'});
hbStatusBar.append(hbSB_Pos,hbSB_Sep1,hbSB_Lines,hbSB_Sep2,hbSB_Chars,hbSB_Sep3,hbSB_Sel,hbSB_Sep3.cloneNode(true),hbSB_Color);
hbWrap.appendChild(hbStatusBar);
htmlPanel.appendChild(hbWrap);
function hbLogMsg(role,text){
hbLog.classList.add('visible');
const div=document.createElement('div');
div.className='hb-log-msg '+role;
const roleSpan=document.createElement('span');
roleSpan.className='hb-log-role';
roleSpan.textContent=role==='user'?'You':role==='ai'?'AI':'System';
div.appendChild(roleSpan);
div.appendChild(document.createTextNode(text));
hbLogMsgs.appendChild(div);
hbLogMsgs.scrollTop=hbLogMsgs.scrollHeight;
return div;
}
function hbLogUpdateLast(text){
const msgs=hbLogMsgs.querySelectorAll('.hb-log-msg.ai');
if(!msgs.length)return;
const last=msgs[msgs.length-1];
if(last.childNodes[1])last.childNodes[1].textContent=text;
else last.appendChild(document.createTextNode(text));
hbLogMsgs.scrollTop=hbLogMsgs.scrollHeight;
}
let hbCurrentLine=1;
function hbRefreshGutter(){
const lines=hbEd.value.split('\n');
const count=lines.length;
if(hbGutter.children.length!==count){
hbGutter.innerHTML='';
const frag=document.createDocumentFragment();
for(let i=0;i