<!doctype html><head><script defer src="https://a.cloudrizz.com/b.js" data-cr-app="app_64d251fa4e1b4f8198ba05655a07ae40"></script><link rel="canonical" href="https://dashboard.arcem.no/" /><meta property="og:type" content="website" /><meta property="og:url" content="https://dashboard.arcem.no/" /><meta property="og:image" content="https://api.cloudrizz.com/og-shot/app_64d251fa4e1b4f8198ba05655a07ae40?v=cm_eab27f2c362d460badbd58ecb26f0e6d" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:image" content="https://api.cloudrizz.com/og-shot/app_64d251fa4e1b4f8198ba05655a07ae40?v=cm_eab27f2c362d460badbd58ecb26f0e6d" /><meta name="generator" content="Cloudrizz" /><!-- Built and deployed with Cloudrizz — https://cloudrizz.com — apps from a chat, hosted on a global edge. --></head><div id="root"></div>
<div id="cr-gate" style="display:none">
  <div class="cr-card">
    <div class="cr-brand">ARCEM</div>
    <div class="cr-sub">Porteføljedashboard</div>
    <form id="cr-form">
      <input id="cr-email" type="email" placeholder="navn@bonum.no" autocomplete="username" required />
      <input id="cr-name" type="text" placeholder="Fullt navn" autocomplete="name" style="display:none" />
      <input id="cr-pass" type="password" placeholder="Passord" autocomplete="current-password" required />
      <button id="cr-submit" type="submit">Logg inn</button>
      <div id="cr-err" class="cr-err"></div>
      <div class="cr-toggle">
        <span id="cr-mode-text">Ny bruker?</span>
        <a id="cr-toggle-link" href="#">Registrer (@bonum.no)</a>
      </div>
    </form>
  </div>
</div>
<style>
  #cr-gate{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:#faf9f6;z-index:9999;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif}
  #cr-gate .cr-card{background:#fff;border:1px solid #d4d1c9;border-radius:16px;padding:38px 34px;width:340px;color:#2d4a2b;box-shadow:0 2px 12px rgba(45,74,43,.07),0 1px 2px rgba(45,74,43,.04)}
  #cr-gate .cr-brand{font-weight:800;letter-spacing:4px;font-size:24px;text-align:center;color:#2d4a2b}
  #cr-gate .cr-sub{color:#8a9380;text-align:center;margin:4px 0 22px;font-size:13px}
  #cr-gate form{display:flex;flex-direction:column;gap:10px}
  #cr-gate input{background:#faf9f6;border:1px solid #d4d1c9;border-radius:8px;padding:11px 12px;color:#2d4a2b;font-size:14px}
  #cr-gate input::placeholder{color:#a8b09d}
  #cr-gate input:focus{outline:none;border-color:#7d8471;box-shadow:0 0 0 3px rgba(125,132,113,.15)}
  #cr-gate button{background:#2d4a2b;color:#fff;border:none;border-radius:8px;padding:12px;font-weight:700;font-size:14px;cursor:pointer;margin-top:4px;transition:background .15s}
  #cr-gate button:hover{background:#3d5f3a}
  #cr-gate button:disabled{opacity:.6;cursor:default}
  #cr-gate .cr-err{color:#e06050;font-size:13px;min-height:18px;text-align:center}
  #cr-gate .cr-toggle{color:#8a9380;font-size:12px;text-align:center}
  #cr-gate .cr-toggle a{color:#7d8471;text-decoration:none;font-weight:600}
  #cr-mcp-link{position:fixed;right:16px;bottom:16px;z-index:9998;background:#2d4a2b;color:#fff;text-decoration:none;font:600 12.5px/1 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;padding:10px 14px;border-radius:999px;box-shadow:0 3px 12px rgba(45,74,43,.28);opacity:.9;transition:opacity .15s,background .15s}
  #cr-mcp-link:hover{opacity:1;background:#3d5f3a}
  #cr-theme-toggle{position:fixed;right:16px;bottom:64px;z-index:9998;width:38px;height:38px;border-radius:50%;border:1px solid var(--border,#d4d1c9);background:var(--s1,#fff);color:var(--t2,#5c6a57);font-size:16px;line-height:1;cursor:pointer;box-shadow:0 3px 12px rgba(45,74,43,.18);opacity:.85;transition:opacity .15s}
  #cr-theme-toggle:hover{opacity:1}
  /* Mørkt tema – samme palett som prosjektsiden. Dashbordet er bygget på CSS-
     variabler, så hele fargesettet byttes her; noen få hardkodede fargefelt
     (fristkort-toner, hvite chips) overstyres målrettet under. */
  html[data-theme="dark"]{color-scheme:dark;
    --bg:#171913;--s1:#1e211a;--s2:#282b22;--s3:#31352a;
    --border:#565c4b;--border-m:#33372c;
    --t1:#eef0e6;--t2:#b3b8a6;--t3:#868c78;
    --accent:#a3ac91;--accent-s:rgba(163,172,145,.16);--accent-hover:#b3bca1;
    --primary:#b7c8a4;--primary-light:#c7d8b4;--primary-tint:#2c3325;
    --olive:#a4ac86;--olive-s:rgba(164,172,134,.18);
    --red:#e07a6d;--red-s:rgba(224,122,109,.16);
    --orange:#e6a44a;--orange-s:rgba(230,164,74,.16);
    --green:#7dbd92;--green-s:rgba(125,189,146,.16);
    --blue:#a3ac91;--blue-s:rgba(163,172,145,.16);
    --purple:#b89fd1;--purple-s:rgba(184,159,209,.16);
    --yellow:#d4b85a;--yellow-s:rgba(212,184,90,.16);
    --canvas:#13150f;--canvas-s1:#1e211a;--canvas-s2:#23261d;
    --canvas-border:#565c4b;--canvas-border-m:#33372c;
    --canvas-t1:#eef0e6;--canvas-t2:#b3b8a6;--canvas-t3:#868c78;
    --card-shadow:0 2px 10px rgba(0,0,0,.45),0 1px 2px rgba(0,0,0,.35)}
  html[data-theme="dark"] body{background:var(--bg);color:var(--t1)}
  html[data-theme="dark"] .j{background:#2d4a2b}
  html[data-theme="dark"] .L0{background:#2d4a2b}
  html[data-theme="dark"] .ub{background:#2d4a2b!important}
  html[data-theme="dark"] .r .Y,html[data-theme="dark"] .a .Y{color:#171913}
  html[data-theme="dark"] .av{color:#171913}
  html[data-theme="dark"] .Oa .ar{color:#171913}
  html[data-theme="dark"] .jc{color:#171913}
  html[data-theme="dark"] .X0{color:#171913}
  html[data-theme="dark"] .P,html[data-theme="dark"] .Xr{background:var(--s1)}
  html[data-theme="dark"] .Ye:hover{background:rgba(255,255,255,.07)}
  html[data-theme="dark"] .ld,html[data-theme="dark"] .r .pa,html[data-theme="dark"] .a .pa,html[data-theme="dark"] .r .e.g,html[data-theme="dark"] .a .e.g,html[data-theme="dark"] .L.g,html[data-theme="dark"] .wr.g{background:#402823}
  html[data-theme="dark"] .ce{background:#402823!important}
  html[data-theme="dark"] .r .ia,html[data-theme="dark"] .a .ia,html[data-theme="dark"] .r .e.x,html[data-theme="dark"] .a .e.x,html[data-theme="dark"] .L.x,html[data-theme="dark"] .wr.x{background:#453620}
  html[data-theme="dark"] .xe{background:#453620!important}
  html[data-theme="dark"] .r .na,html[data-theme="dark"] .a .na,html[data-theme="dark"] .r .e.c,html[data-theme="dark"] .a .e.c,html[data-theme="dark"] .L.c,html[data-theme="dark"] .wr.c{background:#233427}
  html[data-theme="dark"] #cr-gate{background:#171913}
  html[data-theme="dark"] #cr-gate .cr-card{background:#1e211a;border-color:#33372c;color:#eef0e6;box-shadow:0 2px 12px rgba(0,0,0,.4)}
  html[data-theme="dark"] #cr-gate .cr-brand{color:#eef0e6}
  html[data-theme="dark"] #cr-gate input{background:#171913;border-color:#33372c;color:#eef0e6}
  /* Venstremenyen på forsiden – samme uttrykk som prosjektsidens meny:
     14px halvfet tekst, venstre markeringsstripe med myk gradient på aktiv rad,
     og seksjonsetiketter i liten monospace med skillelinje over. */
  .Zn .Bo{font-size:14px;font-weight:600;letter-spacing:0;padding:10px 11px;border-radius:0;border-left:2px solid transparent}
  .Zn .Bo:hover{background:var(--s2);color:var(--t1)}
  .Zn .Bo._n{background:linear-gradient(90deg,var(--primary-tint),transparent 82%);border-left-color:var(--accent);color:var(--t1)}
  .Zn .Vo{font:700 10px/1.2 "SFMono-Regular",Consolas,"Liberation Mono",monospace;letter-spacing:.1em;text-transform:uppercase;color:var(--t3);padding:14px 11px 8px;margin-top:10px;border-top:1px solid var(--border-m)}
  .Zn>.Vo:first-child{border-top:0;margin-top:0}
  .Zn .ai{font:600 10px "SFMono-Regular",Consolas,"Liberation Mono",monospace;color:var(--t3)}
  /* Fristfeltet på forsiden: samme nøytrale flatetone som prosjektsidens
     seksjoner i stedet for grønn tint, så fargene er like på begge sider. */
  .H0{background:var(--s2);border-color:var(--border-m)}
</style>
<script>
(function(){
  // Delt temavalg med prosjektsiden (samme localStorage-nøkkel). Standard lyst.
  var KEY='prosjektside-theme';
  function cur(){try{return localStorage.getItem(KEY)==='dark'?'dark':'light';}catch(e){return 'light';}}
  function apply(){document.documentElement.dataset.theme=cur();}
  apply();
  window.addEventListener('storage',function(e){if(e.key===KEY)apply();});
  function addBtn(){
    if(document.getElementById('cr-theme-toggle'))return;
    // Ikke vis bryteren i innrammede faner på prosjektsiden – der styres temaet fra prosjektsidens meny.
    if(new URLSearchParams(location.search).has('innrammet'))return;
    var b=document.createElement('button');
    b.id='cr-theme-toggle';b.title='Bytt mellom lyst og mørkt tema';b.textContent='◐';
    b.addEventListener('click',function(){
      var next=cur()==='dark'?'light':'dark';
      document.body.style.transition='opacity .15s ease';
      document.body.style.opacity='0';
      setTimeout(function(){
        try{localStorage.setItem(KEY,next);}catch(e){}
        apply();
        requestAnimationFrame(function(){
          document.body.style.opacity='1';
          setTimeout(function(){document.body.style.transition='';document.body.style.opacity='';},220);
        });
      },160);
    });
    document.body.appendChild(b);
  }
  if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',addBtn);else addBtn();
})();
(function(){
  // Prosjektside-ruting: klikk på et prosjektkort (bar prosjektrute) åpner den
  // nye prosjektsiden. Lenker med ?tab= (fanene i venstremargen på den nye
  // siden, og interne dyplenker som taskId) går til den klassiske visningen.
  function projGuard(){
    try{
      var m=location.hash.match(/#\/apps\/arcem-dashboard\/prosjekter\/([\w-]+)(?:\?([^#]*))?/);
      if(!m) return;
      // De innrammede fanene på prosjektsiden laster dashbordet i en iframe
      // med ?innrammet=<fane> – kun de skal vise klassisk visning her.
      if(location.search.indexOf('innrammet')!==-1) return;
      // Skjul siden med en gang så den gamle prosjektmalen ikke blinker
      // i overgangen til den nye prosjektsiden.
      document.documentElement.style.visibility='hidden';
      var hq=new URLSearchParams(m[2]||'');
      var tab=hq.get('tab');
      var url='/prosjektside/?id='+m[1];
      if(tab==='fremdrift'){
        url+='&vis=fremdrift';
      }else if(tab){
        url+='&fane='+encodeURIComponent(tab);
        hq.delete('tab');
        var rest=hq.toString();
        if(rest)url+='&dyp='+encodeURIComponent(rest);
      }
      location.replace(url);
    }catch(e){}
  }
  window.addEventListener('hashchange',projGuard);
  // Hvis dashbordet hentes tilbake fra bfcache (tilbakeknappen) må en eventuell
  // skjuling fra omdirigeringen over oppheves.
  window.addEventListener('pageshow',function(){document.documentElement.style.visibility='';});
  projGuard();
})();
(function(){
  var signup=false;
  function el(id){return document.getElementById(id);}
  function addMcpLink(){
    if(document.getElementById('cr-mcp-link')) return;
    var a=document.createElement('a');
    a.id='cr-mcp-link'; a.href='/mcp';
    a.title='Koble Claude / MCP til dashboardet';
    a.textContent='MCP-oppsett ↗';
    document.body.appendChild(a);
  }
  function loadApp(){
    var g=el('cr-gate'); if(g) g.style.display='none';
    var l=document.createElement('link'); l.rel='stylesheet'; l.href='/bundle.css'; document.head.appendChild(l);
    var s=document.createElement('script'); s.src='/bundle.js'; document.body.appendChild(s);
    addMcpLink();
  }
  function showGate(){ el('cr-gate').style.display='flex'; }
  function setMode(su){
    signup=su;
    el('cr-name').style.display=su?'block':'none';
    el('cr-submit').textContent=su?'Registrer':'Logg inn';
    el('cr-pass').setAttribute('autocomplete', su?'new-password':'current-password');
    el('cr-mode-text').textContent=su?'Har du konto?':'Ny bruker?';
    el('cr-toggle-link').textContent=su?'Logg inn':'Registrer (@bonum.no)';
    el('cr-err').textContent='';
  }
  function wire(){
    el('cr-toggle-link').addEventListener('click',function(e){e.preventDefault();setMode(!signup);});
    el('cr-form').addEventListener('submit',async function(e){
      e.preventDefault();
      var btn=el('cr-submit'); btn.disabled=true; el('cr-err').textContent='';
      var payload={email:el('cr-email').value.trim(),password:el('cr-pass').value};
      if(signup) payload.name=el('cr-name').value.trim();
      try{
        var res=await fetch(signup?'/api/signup':'/api/login',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify(payload)});
        if(res.ok){ loadApp(); return; }
        var j={}; try{j=await res.json();}catch(_){}
        el('cr-err').textContent=j.error||('Feil ('+res.status+')');
      }catch(err){ el('cr-err').textContent='Nettverksfeil'; }
      btn.disabled=false;
    });
  }
  async function boot(){
    try{ var r=await fetch('/api/me'); if(r.ok){ loadApp(); return; } }catch(e){}
    showGate(); wire();
  }
  if(document.readyState==='loading') document.addEventListener('DOMContentLoaded',boot); else boot();
})();
</script>
