diff --git a/static/opax.html b/static/opax.html index 552a005..0657e84 100644 --- a/static/opax.html +++ b/static/opax.html @@ -283,6 +283,17 @@ .roi-sub{font-size:12px;color:var(--text-dim);margin-top:4px;line-height:1.5} .roi-divider{width:1px;height:60px;background:var(--border);flex-shrink:0} @media(max-width:600px){.roi-divider{display:none}.roi-box{gap:16px}} + + /* BROWSER PANEL */ + .browser-bar{display:flex;align-items:center;gap:8px;padding:10px 16px;border-bottom:1px solid var(--border);background:var(--bg-2);flex-shrink:0} + .browser-url-input{flex:1;background:var(--bg-3);border:1px solid var(--border);border-radius:8px;padding:6px 12px;font-family:var(--mono);font-size:12px;color:var(--text);outline:none;transition:border-color .2s} + .browser-url-input:focus{border-color:var(--accent)} + .browser-url-input::placeholder{color:var(--text-faint)} + .browser-go-btn{padding:6px 14px;border-radius:8px;background:var(--accent);color:#fff;font-size:12px;font-weight:600;transition:background .14s;white-space:nowrap} + .browser-go-btn:hover{background:#6a4cff} + .browser-frame{flex:1;border:none;width:100%;height:100%;background:var(--bg)} + .browser-error{display:none;flex:1;align-items:center;justify-content:center;flex-direction:column;gap:12px;color:var(--text-faint);font-family:var(--mono);font-size:13px} + .browser-error.show{display:flex} @@ -332,6 +343,9 @@ +
@@ -565,6 +579,30 @@
+ +
+
+
🌐
+
+
Browser
+
Intern dokumentasjonsleser ¡ /docs/ proxy
+
+
+ +
+
+
+ + +
+
+ ⚠️ + Kunne ikke laste siden +
+ +
+ @@ -575,7 +613,6 @@ const AGENT_URL = '' const USER_ID = 'chris' const STORAGE_KEY = 'jason_history_v2' const SESSION_KEY = 'jason_session_v2' -const GH_RAW = 'https://raw.githubusercontent.com/vauco-saas/OSVauco/main/' const GH_BLOB = 'https://github.com/vauco-saas/OSVauco/blob/main/' const MD_DOCS = [ @@ -598,6 +635,7 @@ const PANEL_META = { sites: ['Sites & Moduler', 'Alle Vauco-flater'], terminal: ['Terminal', 'OPAX agent · Cloud Run'], md: ['MD — Dokumenter', 'Kjerndoks · vauco-saas/OSVauco'], + browser: ['Browser', 'Intern dokumentasjonsleser · /docs/ proxy'], } const SITES_DATA = [ @@ -648,7 +686,6 @@ function updatePricing(val){ renderTierGrid(spend) - // ROI: 15% of spend saved via CostGuard optimisation const savings = spend * 0.15 const net_monthly = savings - tier.price const net_annual = net_monthly * 12 @@ -706,6 +743,26 @@ function initPricing(){ updatePricing(slider.value) } +// BROWSER PANEL +function browserNav(){ + const raw = document.getElementById('browser-url').value.trim() + if(!raw) return + const url = raw.startsWith('http') ? raw : '/docs/'+raw.replace(/^\/docs\//,'') + document.getElementById('browser-error').classList.remove('show') + document.getElementById('browser-frame').src = url +} +function browserRefresh(){ + const f = document.getElementById('browser-frame') + if(f.src) f.src = f.src +} +function browserFrameLoad(){ + document.getElementById('browser-error').classList.remove('show') +} +function browserFrameError(){ + document.getElementById('browser-error-msg').textContent = 'Siden kunne ikke lastes — sjekk URL eller /docs/-proxy' + document.getElementById('browser-error').classList.add('show') +} + // BUILD STATUS POLL async function pollBuild(){ try{ @@ -893,7 +950,10 @@ async function openMd(path, name){ const viewer=document.getElementById('md-viewer') viewer.innerHTML='
⏳ Laster '+esc(path)+'...
' try{ - const raw=await fetch(GH_RAW+path+'?t='+Date.now()).then(r=>{ if(!r.ok) throw new Error('HTTP '+r.status); return r.text() }) + // OQ-30: bruk /docs/ proxy i stedet for GH_RAW + const res = await fetch('/docs/'+path+'?t='+Date.now()) + if(!res.ok) throw new Error('HTTP '+res.status) + const raw = await res.text() viewer.innerHTML=renderMd(raw) }catch(e){ viewer.innerHTML=`
❌ Kunne ikke laste: ${esc(e.message)}
` @@ -1047,7 +1107,6 @@ function exportHistory(){ } ;(function(){ const h=lh();if(!h.length)return;h.forEach(m=>appendMsg(m.role,m.text,m.ts));document.getElementById('messages').scrollTop=99999 })() inp.focus() -// Init pricing on load so slider is ready if user navigates directly renderTierGrid(5000) updatePricing(5000)