// Chrome spoof — static-but-believable browser UI. const TABS = [ { title: 'New Tab', active: true }, { title: 'Meridian Docs', active: false }, { title: 'Search', active: false }, ]; const SHORTCUTS = [ { label: 'GitHub', url: 'https://github.com' }, { label: 'Gmail', url: 'https://mail.google.com' }, { label: 'YouTube', url: 'https://youtube.com' }, { label: 'Maps', url: 'https://maps.google.com' }, { label: 'Drive', url: 'https://drive.google.com' }, { label: 'Calendar', url: 'https://calendar.google.com' }, { label: 'Docs', url: 'https://docs.google.com' }, { label: 'Translate', url: 'https://translate.google.com' }, ]; export default { id: 'chrome', title: 'Chrome', render(container, api) { let activeTab = 0; let navUrl = ''; const root = document.createElement('div'); root.style.cssText = 'height:100%;display:flex;flex-direction:column;background:var(--bg-1);'; // Tab strip const tabStrip = document.createElement('div'); tabStrip.style.cssText = 'display:flex;background:var(--bg-2);border-bottom:1px solid var(--border);flex-shrink:0;overflow-x:auto;'; // New tab button const newTabBtn = document.createElement('button'); newTabBtn.style.cssText = 'padding:8px 12px;font-size:16px;border:none;background:transparent;color:var(--text-dim);cursor:pointer;flex-shrink:0;'; newTabBtn.textContent = '+'; newTabBtn.addEventListener('click', () => { const newIdx = TABS.length; TABS.push({ title: 'New Tab', active: true }); TABS.forEach((t) => { t.active = false; }); TABS[newIdx].active = true; activeTab = newIdx; navUrl = ''; updateTabBar(); updateBody(); }); function updateTabBar() { tabStrip.innerHTML = ''; TABS.forEach((tab, i) => { const btn = document.createElement('button'); btn.style.cssText = 'padding:8px 16px;font-size:12px;border:none;background:transparent;color:' + (tab.active ? 'var(--text)' : 'var(--text-dim)') + ';border-right:1px solid var(--border);cursor:pointer;transition:color 150ms;max-width:180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;'; btn.textContent = tab.title; btn.addEventListener('click', () => { activeTab = i; navUrl = SHORTCUTS[i] ? SHORTCUTS[i].url : ''; updateTabBar(); updateBody(); }); tabStrip.appendChild(btn); }); tabStrip.appendChild(newTabBtn); } updateTabBar(); root.appendChild(tabStrip); // Address bar const addrBar = document.createElement('div'); addrBar.style.cssText = 'display:flex;align-items:center;padding:6px 12px;gap:8px;background:var(--bg-2);border-bottom:1px solid var(--border);flex-shrink:0;'; const urlInput = document.createElement('input'); urlInput.type = 'text'; urlInput.value = navUrl || (SHORTCUTS[activeTab] ? SHORTCUTS[activeTab].url : ''); urlInput.style.cssText = 'flex:1;padding:6px 12px;background:var(--bg-3);border:1px solid var(--border);border-radius:20px;color:var(--text);font-size:13px;outline:none;'; urlInput.placeholder = 'Search or enter web address'; urlInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') { const val = urlInput.value.trim(); if (val) { navUrl = val; updateBody(); } } }); const reloadBtn = document.createElement('button'); reloadBtn.style.cssText = 'padding:4px 8px;background:transparent;border:none;color:var(--text-dim);cursor:pointer;font-size:14px;'; reloadBtn.textContent = '\u{21BB}'; reloadBtn.addEventListener('click', () => { updateBody(); }); addrBar.appendChild(urlInput); addrBar.appendChild(reloadBtn); root.appendChild(addrBar); // Body const body = document.createElement('div'); body.style.cssText = 'flex:1;overflow-y:auto;padding:40px 20px;background:var(--bg-1);'; function updateBody() { body.innerHTML = ''; urlInput.value = navUrl || (TABS[activeTab].title === 'New Tab' ? '' : TABS[activeTab].title.toLowerCase().replace(/\s+/g, '-') + '.meridian.dev'); if (activeTab === 0 && !navUrl) { // New tab page const titleEl = document.createElement('h2'); titleEl.style.cssText = 'font-size:22px;font-weight:500;color:var(--text);margin-bottom:28px;text-align:center;'; titleEl.textContent = 'Meridian Browser'; body.appendChild(titleEl); const grid = document.createElement('div'); grid.style.cssText = 'display:grid;grid-template-columns:repeat(4,1fr);gap:12px;max-width:600px;margin:0 auto;'; SHORTCUTS.forEach((sc) => { const tile = document.createElement('div'); tile.style.cssText = 'padding:16px 12px;background:var(--bg-2);border:1px solid var(--border);border-radius:8px;text-align:center;cursor:pointer;transition:background 150ms;'; tile.addEventListener('mouseenter', () => { tile.style.background = 'var(--bg-3)'; }); tile.addEventListener('mouseleave', () => { tile.style.background = 'var(--bg-2)'; }); tile.addEventListener('click', () => { navUrl = sc.url; TABS[0].title = sc.label; updateTabBar(); updateBody(); }); const tileIcon = document.createElement('div'); tileIcon.style.cssText = 'font-size:18px;font-weight:600;color:var(--accent);margin-bottom:4px;'; tileIcon.textContent = sc.label.charAt(0); const tileLabel = document.createElement('div'); tileLabel.style.cssText = 'font-size:11px;color:var(--text-dim);'; tileLabel.textContent = sc.label; tile.appendChild(tileIcon); tile.appendChild(tileLabel); grid.appendChild(tile); }); body.appendChild(grid); } else { // Simulated page const page = document.createElement('div'); page.style.cssText = 'max-width:600px;margin:0 auto;'; const heading = document.createElement('h2'); heading.style.cssText = 'font-size:22px;font-weight:500;color:var(--text);margin-bottom:12px;'; heading.textContent = 'Simulated page for ' + (navUrl || TABS[activeTab].title); page.appendChild(heading); const urlDisplay = document.createElement('div'); urlDisplay.style.cssText = 'font-size:12px;color:var(--text-dim);margin-bottom:24px;font-family:monospace;padding:8px 12px;background:var(--bg-2);border:1px solid var(--border);border-radius:4px;'; urlDisplay.textContent = navUrl || TABS[activeTab].title; page.appendChild(urlDisplay); const para = document.createElement('p'); para.style.cssText = 'font-size:14px;color:var(--text-dim);line-height:1.7;'; const displayUrl = navUrl || TABS[activeTab].title; para.textContent = 'This is a simulated page for ' + displayUrl + '. Meridian Browser does not make actual network requests — it is a spoof. Nothing to see here unless you count the aesthetic choices.'; page.appendChild(para); body.appendChild(page); } } root.appendChild(body); container.appendChild(root); updateBody(); }, };