1/* cerver shared top nav â the single source of truth for the header on 2 * EVERY page (landing included). A page drops in: 3 * <div id="cerver-nav" data-active="examples"></div> 4 * <script src="/nav.js" defer></script> 5 * Self-contained (own scoped styles), so it renders identically no matter 6 * what CSS the page loads. Edit this one file â every page updates. */ 7(function () { 8 var mount = document.getElementById("cerver-nav"); 9 if (!mount) return; 10 var active = mount.getAttribute("data-active") || ""; 11 12 // Menus, left â right. `mega` = multi-column panel; otherwise a simple 13 // single-column dropdown. `keys` decides when the trigger shows active. 14 var MENUS = [ 15 { label: "/products", keys: ["products"], mega: [ 16 { head: "CLI", items: [ 17 { t: "cerver run", s: "One-shot agent, single prompt", href: "/docs#quickstart" }, 18 { t: "cerver chat", s: "Multi-turn, resumable", href: "/docs#quickstart" }, 19 { t: "cerver compare", s: "Same prompt, side by side", href: "/docs#quickstart" }, 20 { t: "cerver computes", s: "Manage your machines", href: "/docs#compute-setup" } ] }, 21 { head: "API", items: [ 22 { t: "Sessions", s: "Create, run, peek, terminate", href: "/docs#session-example" }, 23 { t: "Computes", s: "List, attach, switch", href: "/docs#compute-setup" }, 24 { t: "Projects", s: "Namespaces for keys + billing", href: "/docs#endpoints" }, 25 { t: "Auth", s: "Device-code login, key minting", href: "/docs#secrets" } ] }, 26 { head: "Platform", items: [ 27 { t: "Dashboard", s: "Sessions, usage, billing", href: "/dashboard" }, 28 { t: "Projects & Envs", s: "Per-project config + secrets", href: "/dashboard/projects" }, 29 { t: "Vaults", s: "Any vault â Infisical, Doppler, or paste keys", href: "/products#vaults" }, 30 { t: "Routing policies", s: "Your algorithm for model choice", href: "/policies" } ] }, 31 { head: "Chat", badge: "soon", items: [ 32 { t: "Headless chat", s: "Embed without UI work", href: "/chat" }, 33 { t: "Multi-tenant", s: "Per-user sessions, scoped", href: "/chat#multi-tenant" }, 34 { t: "Hot-swap", s: "Switch model + compute live", href: "/chat#cross-model" }, 35 { t: "Cross-model", s: "One widget, any model", href: "/chat#cross-model" } ] } ] }, 36 { label: "/use-cases", keys: ["developers", "agents", "app-backend", "teams", "finops"], items: [ 37 { t: "Developers", s: "Ship faster, always on the best agent", href: "/use-cases/developers", key: "developers" }, 38 { t: "AI agents", s: "Memory, compute & a model they can swap", href: "/use-cases/agents", key: "agents" }, 39 { t: "App backend", s: "Drop AI sessions in â forget the plumbing", href: "/use-cases/app-backend", key: "app-backend" }, 40 { t: "Teams", s: "Real model flexibility for every employee", href: "/use-cases/teams", key: "teams" }, 41 { t: "FinOps", s: "Query every session, cut the waste", href: "/use-cases/finops", key: "finops" } ] }, 42 { label: "/how-to", keys: ["docs", "examples"], items: [ 43 { t: "Docs", s: "API + CLI reference", href: "/docs", key: "docs" }, 44 { t: "Examples", s: "Apps built on Cerver", href: "/examples", key: "examples" } ] }, 45 { label: "/more", keys: ["pricing", "blog", "quickstart", "platform", "architecture"], items: [ 46 { t: "Quickstart", s: "Add AI to your app in two calls", href: "/quickstart", key: "quickstart" }, 47 { t: "Platform demo", s: "Many products, one platform â live", href: "/platform", key: "platform" }, 48 { t: "Architecture", s: "Vaults, computes, failover â live", href: "/architecture", key: "architecture" }, 49 { t: "Pricing", s: "Plans + cost calculator", href: "/pricing", key: "pricing" }, 50 { t: "Blog", s: "Notes on AI spend", href: "/blog", key: "blog" }, 51 { t: "Report", s: "The State of AI-Coding Spend 2026", href: "/report", key: "report" }, 52 { t: "Benchmarks", s: "Models priced by the job â cost & time to done", href: "/trials/", key: "benchmarks" } ] }, 53 ]; 54 var CTA = { label: "Get started", href: "/login" }; 55 56 var css = '' 57 + '#cerver-nav{display:block}' 58 + '#cerver-nav .cnav{position:relative;border-bottom:1px solid #d9d3c2;background:#f4f1e8;font-family:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace}' 59 + '#cerver-nav .cnav-wrap{max-width:1140px;margin:0 auto;padding:0 22px;height:62px;display:flex !important;align-items:center;justify-content:space-between}' 60 + '#cerver-nav .cnav-brand{display:inline-flex;align-items:center;gap:9px;font-weight:600;font-size:15px;color:#1b1a16;text-decoration:none}' 61 + '#cerver-nav .cnav-brand svg{display:block;color:#df7536}' 62 + '#cerver-nav .cnav-links{display:flex !important;align-items:center;gap:22px}' 63 + '#cerver-nav .cnav-links>
63a:not(.cnav-cta),#cerver-nav .cnav-ddt{font-size:13px;color:#6c685c;text-decoration:none;background:none;border:0;cursor:pointer;font-family:inherit;display:inline-flex;align-items:center;gap:5px;padding:0}' 64 + '#cerver-nav .cnav-dd{position:relative;display:inline-flex;align-items:center}' 65 + '#cerver-nav .cnav-ddt{padding:3px 8px;border-radius:0;transition:background .12s ease,color .12s ease}' 66 + '#cerver-nav .cnav-ddt.on{color:#1b1a16}' 67 // Negative (inverted) highlight on hover / forced-open: ink fill, cream text. 68 + '#cerver-nav .cnav-dd:hover .cnav-ddt,#cerver-nav .cnav-dd.cnav-force .cnav-ddt{background:#1b1a16;color:#f4f1e8}' 69 + '#cerver-nav .cnav-caret{font-size:8px}' 70 + '#cerver-nav .cnav-dd::after{content:"";position:absolute;top:100%;left:-14px;right:-14px;height:14px}' 71 + '#cerver-nav .cnav-pan{position:absolute;top:100%;left:50%;transform:translateX(-50%);margin-top:12px;min-width:250px;background:#fbf9f3;border:1px solid #d9d3c2;border-radius:0;padding:7px;box-shadow:0 16px 38px rgba(0,0,0,.13);display:none;z-index:80}' 72 + '#cerver-nav .cnav-dd.mega{position:static}' 73 + '#cerver-nav .cnav-mega{position:absolute;top:100%;right:22px;margin-top:11px;width:min(880px,calc(100vw - 44px));background:#fbf9f3;border:1px solid #d9d3c2;border-radius:0;padding:20px;box-shadow:0 18px 44px rgba(0,0,0,.13);display:none;z-index:80;grid-template-columns:repeat(4,1fr);gap:20px}' 74 + '#cerver-nav .cnav-mega::before{content:"";position:absolute;bottom:100%;left:0;right:0;height:13px}' 75 + '#cerver-nav .cnav-dd:hover .cnav-pan{display:block}' 76 + '#cerver-nav .cnav-dd:hover .cnav-mega{display:grid}' 77 // Force-open hook so anything on the page (e.g. a hero link) can pop a 78 // dropdown open via window.cerverNav.open(label). 79 + '#cerver-nav .cnav-dd.cnav-force .cnav-pan{display:block}' 80 + '#cerver-nav .cnav-dd.cnav-force .cnav-mega{display:grid}' 81 + '#cerver-nav .cnav-col-h{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:#6c685c;border-bottom:1px solid #d9d3c2;padding-bottom:8px;margin-bottom:9px;display:flex;gap:6px;align-items:center}' 82 + '#cerver-nav .cnav-badge{font-size:8px;font-weight:700;text-transform:uppercase;color:#df7536;background:rgba(223,117,54,.12);padding:2px 5px;border-radius:0}' 83 + '#cerver-nav .cnav-it{display:block;text-decoration:none;padding:7px 10px;border-radius:0}' 84 + '#cerver-nav .cnav-it:hover{background:#eae5d7}' 85 + '#cerver-nav .cnav-it .t{display:block;font-size:13px;font-weight:600;color:#df7536}' 86 + '#cerver-nav .cnav-it .s{display:block;font-size:11px;color:#6c685c;line-height:1.3;margin-top:1px}' 87 + '#cerver-nav .cnav-cta{font-size:13px;color:#f4f1e8 !important;background:#1b1a16;border-radius:0;padding:7px 13px;font-weight:600;text-decoration:none}' 88 + '#cerver-nav .cnav-cta:hover{color:#1b1a16 !important;background:#df7536}' 89 + '#cerver-nav .cnav-burger{display:none;background:none;border:0;cursor:pointer;font-size:20px;color:#1b1a16;line-height:1;padding:4px}' 90 + '#cerver-nav .cnav-sheet{display:none;border-bottom:1px solid #d9d3c2;background:#f4f1e8;padding:4px 22px 20px;max-height:80vh;overflow:auto}' 91 + '#cerver-nav .cnav-acc{display:flex;justify-content:space-between;align-items:center;width:100%;padding:15px 0;font-size:15px;font-weight:600;color:#1b1a16;background:none;border:0;border-top:1px solid #eae5d7;cursor:pointer;font-family:inherit;text-align:left}' 92 + '#cerver-nav .cnav-accx{color:#df7536;font-size:18px;line-height:1}' 93 + '#cerver-nav .cnav-acc-b{display:none;padding:2px 0 12px 2px}' 94 + '#cerver-nav .cnav-acc-b.open{display:block}' 95 + '#cerver-nav .cnav-acc-b .sub{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:#9c988a;padding:10px 0 2px}' 96 + '#cerver-nav .cnav-acc-b a{display:block;padding:8px 0;font-size:14px;color:#6c685c;text-decoration:none}' 97 + '#cerver-nav .cnav-sheet-cta{display:block;text-align:center;margin:16px 0 2px;background:#1b1a16;color:#f4f1e8;border-radius:0;padding:13px;font-size:14px;font-weight:600;text-decoration:none}' 98 + '@media(max-width:860px){#cerver-nav .cnav-links{display:none !important}#cerver-nav .cnav-burger{display:block !important}#cerver-nav .cnav-sheet.open{display:block}}'; 99 100 // Topbar mark â matches the favicon (server-box monogram) with straight, 101 // sharp lines: a square frame + two bars joined by a left spine.
102 var mark = '<svg width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">' 103 + '<rect x="1.5" y="1.5" width="13" height="13" fill="none" stroke="currentColor" stroke-width="1.5"/>' 104 + '<rect x="4.4" y="4.4" width="7.2" height="2.1" fill="currentColor"/>' 105 + '<rect x="4.4" y="9.5" width="7.2" height="2.1" fill="currentColor"/>' 106 + '<rect x="4.4" y="4.4" width="2.1" height="7.2" fill="currentColor"/></svg>'; 107 108 function item(i) { 109 return '<a class="cnav-it" href="' + i.href + '"><span class="t">' + i.t 110 + '</span><span class="s">' + i.s + "</span></a>"; 111 } 112 function menu(m) { 113 var on = m.keys.indexOf(active) !== -1 ? " on" : ""; 114 var trigger = '<button class="cnav-ddt' + on + '" type="button">' + m.label 115 + '</button>'; 116 if (m.mega) { 117 var cols = m.mega.map(function (c) { 118 var head = '<div class="cnav-col-h">' + c.head 119 + (c.badge ? ' <span class="cnav-badge">' + c.badge + "</span>" : "") + "</div>"; 120 return "<div>" + head + c.items.map(item).join("") + "</div>"; 121 }).join(""); 122 return '<div class="cnav-dd mega">' + trigger + '<div class="cnav-mega">' + cols + "</div></div>"; 123 } 124 return '<div class="cnav-dd">' + trigger + '<div class="cnav-pan">' + m.items.map(item).join("") + "</div></div>"; 125 } 126 127 var desktop = MENUS.map(menu).join("") 128 + '<a class="cnav-cta" href="' + CTA.href + '">' + CTA.label + "</a>"; 129 130 var sheet = MENUS.map(function (m) { 131 var body; 132 if (m.mega) { 133 body = m.mega.map(function (c) { 134 return '<div class="sub">' + c.head + "</div>" 135 + c.items.map(function (i) { return '<a href="' + i.href + '">' + i.t + "</a>"; }).join(""); 136 }).join(""); 137 } else { 138 body = m.items.map(function (i) { return '<a href="' + i.href + '">' + i.t + "</a>"; }).join(""); 139 } 140 return '<button class="cnav-acc" type="button">' + m.label + '<span class="cnav-accx">+</span></button>' 141 + '<div class="cnav-acc-b">' + body + "</div>"; 142 }).join("") + '<a class="cnav-sheet-cta" href="' + CTA.href + '">' + CTA.label + "</a>"; 143 144 mount.innerHTML = "<style>" + css + "</style>" 145 + '<header class="cnav"><div class="cnav-wrap">' 146 + '<a class="cnav-brand" href="/" aria-label="Cerver â home">' + mark + "Cerver</a>" 147 + '<nav class="cnav-links" aria-label="Primary">' + desktop + "</nav>" 148 + '<button class="cnav-burger" type="button" aria-label="Menu" aria-expanded="false">â°</button>' 149 + '</div><div class="cnav-sheet">' + sheet + "</div></header>"; 150 151 var burger = mount.querySelector(".cnav-burger"); 152 var sheetEl = mount.querySelector(".cnav-sheet"); 153 if (burger && sheetEl) { 154 burger.addEventListener("click", function () { 155 var open = sheetEl.classList.toggle("open"); 156 burger.setAttribute("aria-expanded", open ? "true" : "false"); 157 }); 158 } 159 // Mobile accordions: tap a section header to expand its links. 160 mount.querySelectorAll(".cnav-acc").forEach(function (btn) { 161 btn.addEventListener("click", function () { 162 var body = btn.nextElementSibling; 163 var open = body.classList.toggle("open"); 164 var x = btn.querySelector(".cnav-accx"); 165 if (x) x.textContent = open ? "â" : "+"; 166 }); 167 }); 168 169 // Let the rest of the page open a dropdown by its label (case-insensitive, 170 // prefix match) â e.g. a hero link that previews the Use cases menu on hover. 171 function forceDd(label, on) { 172 var want = String(label || "").trim().toLowerCase(); 173 mount.querySelectorAll(".cnav-dd").forEach(function (dd) { 174 var t = dd.querySelector(".cnav-ddt"); 175 if (t && t.textContent.trim().toLowerCase().indexOf(want) === 0) 176 dd.classList.toggle("cnav-force", !!on); 177 }); 178 } 179 window.cerverNav = { 180 open: function (label) { forceDd(label, true); }, 181 close: function (label) { forceDd(label, false); }, 182 }; 183})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.