Wiki — Internal Company Handbook Landing
A friendly internal company-handbook home in the Notion and GitLab-handbook spirit, built with plain HTML, CSS and vanilla JavaScript. It pairs a warm welcome hero, a live search preview with keyboard navigation, and a time-of-day greeting with collapsible quick-link cards for Onboarding, Policies, Benefits, Engineering and People Ops, plus new-this-week updates, most-viewed pages and a who-to-ask contacts strip using CSS-drawn avatars.
MCP
Codice
:root {
/* Palette override — internal handbook, brand-neutral light + friendly accent */
--bg: #ffffff;
--bg-2: #f6f7f9;
--panel: #ffffff;
--ink: #1a1a1f;
--ink-2: #3a3a42;
--muted: #6b7280;
--line: rgba(20, 20, 30, 0.10);
--line-2: rgba(20, 20, 30, 0.18);
--link: #0284c7;
--link-hover: #0369a1;
--accent: #0ea5e9;
--accent-2: #f97316;
--note: #2563eb;
--tip: #16a34a;
--warn: #d97706;
--danger: #dc2626;
--code-bg: #f4f4f6;
--kbd-bg: #eceef2;
--r-sm: 6px;
--r-md: 10px;
--r-lg: 14px;
--r-xl: 20px;
--shadow: 0 1px 2px rgba(20, 20, 30, 0.04), 0 6px 20px rgba(20, 20, 30, 0.05);
--shadow-hi: 0 4px 12px rgba(20, 20, 30, 0.08), 0 16px 40px rgba(14, 165, 233, 0.10);
--topbar-h: 60px;
--sidebar-w: 248px;
font-family: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: calc(var(--topbar-h) + 14px); }
body {
margin: 0;
background: var(--bg-2);
color: var(--ink);
font-size: 15px;
line-height: 1.55;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); text-decoration: underline; }
code {
font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 0.86em;
background: var(--code-bg);
border: 1px solid var(--line);
border-radius: var(--r-sm);
padding: 0.08em 0.4em;
}
kbd {
font-family: "JetBrains Mono", ui-monospace, monospace;
font-size: 11px;
background: var(--kbd-bg);
border: 1px solid var(--line-2);
border-bottom-width: 2px;
border-radius: 5px;
padding: 1px 6px;
color: var(--ink-2);
}
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
border-radius: 4px;
}
.skip-link {
position: fixed;
left: 12px;
top: -60px;
z-index: 100;
background: var(--ink);
color: #fff;
padding: 8px 14px;
border-radius: var(--r-sm);
transition: top 0.18s ease;
}
.skip-link:focus { top: 12px; }
/* ===== Topbar ===== */
.topbar {
position: sticky;
top: 0;
z-index: 40;
height: var(--topbar-h);
display: flex;
align-items: center;
gap: 14px;
padding: 0 18px;
background: rgba(255, 255, 255, 0.85);
backdrop-filter: saturate(180%) blur(12px);
border-bottom: 1px solid var(--line);
}
.nav-toggle {
display: none;
flex-direction: column;
justify-content: center;
gap: 4px;
width: 38px;
height: 38px;
border: 1px solid var(--line);
border-radius: var(--r-sm);
background: var(--panel);
cursor: pointer;
}
.nav-toggle span {
width: 18px;
height: 2px;
background: var(--ink-2);
border-radius: 2px;
margin: 0 auto;
transition: transform 0.2s;
}
.brand {
display: flex;
align-items: center;
gap: 9px;
font-weight: 800;
color: var(--ink);
letter-spacing: -0.01em;
}
.brand:hover { text-decoration: none; }
.brand-mark {
display: grid;
place-items: center;
width: 30px;
height: 30px;
border-radius: 9px;
background: linear-gradient(135deg, var(--accent), var(--accent-2));
color: #fff;
font-weight: 800;
box-shadow: 0 2px 8px rgba(14, 165, 233, 0.35);
}
.brand-text span { color: var(--accent); }
.topbar-search {
position: relative;
flex: 1;
max-width: 440px;
margin: 0 auto;
display: flex;
align-items: center;
gap: 8px;
background: var(--bg-2);
border: 1px solid var(--line);
border-radius: 999px;
padding: 0 12px;
height: 38px;
transition: border-color 0.15s, box-shadow 0.15s;
}
.topbar-search:focus-within {
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.14);
background: #fff;
}
.ts-icon { width: 16px; height: 16px; fill: var(--muted); flex-shrink: 0; }
.topbar-search input {
flex: 1;
border: 0;
background: transparent;
font: inherit;
font-size: 13.5px;
color: var(--ink);
outline: none;
}
.topbar-search kbd { flex-shrink: 0; }
.topbar-user { margin-left: auto; }
.user-chip {
display: flex;
align-items: center;
gap: 8px;
border: 1px solid var(--line);
background: var(--panel);
border-radius: 999px;
padding: 4px 12px 4px 4px;
cursor: pointer;
font: inherit;
font-weight: 600;
font-size: 13px;
color: var(--ink-2);
transition: background 0.15s, border-color 0.15s;
}
.user-chip:hover { background: var(--bg-2); border-color: var(--line-2); }
/* ===== Avatars (CSS-drawn) ===== */
.avatar {
--hue: 200;
display: inline-grid;
place-items: center;
width: 26px;
height: 26px;
border-radius: 50%;
background: linear-gradient(135deg, hsl(var(--hue) 78% 62%), hsl(calc(var(--hue) + 40) 80% 52%));
color: #fff;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.01em;
box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.35);
}
.avatar::after { content: attr(data-initials); }
.avatar--lg { width: 56px; height: 56px; font-size: 19px; }
/* ===== Shell layout ===== */
.shell {
display: grid;
grid-template-columns: var(--sidebar-w) 1fr;
align-items: start;
max-width: 1320px;
margin: 0 auto;
}
/* ===== Sidebar ===== */
.sidebar {
position: sticky;
top: var(--topbar-h);
align-self: start;
height: calc(100vh - var(--topbar-h));
overflow-y: auto;
border-right: 1px solid var(--line);
background: var(--bg);
}
.sidebar-inner { padding: 22px 16px 40px; }
.side-label {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--muted);
margin: 22px 8px 8px;
}
.side-label:first-child { margin-top: 4px; }
.side-nav { list-style: none; margin: 0; padding: 0; }
.side-nav a {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 10px;
border-radius: var(--r-sm);
color: var(--ink-2);
font-weight: 500;
font-size: 14px;
}
.side-nav a:hover { background: var(--bg-2); color: var(--ink); text-decoration: none; }
.side-nav a.active { background: rgba(14, 165, 233, 0.10); color: var(--link-hover); font-weight: 600; }
.side-nav .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--c, var(--accent)); flex-shrink: 0; }
.side-nav--muted a { font-size: 13.5px; color: var(--muted); }
.side-nav--muted a:hover { color: var(--ink); }
.side-card {
margin-top: 26px;
padding: 14px;
background: linear-gradient(160deg, rgba(14, 165, 233, 0.08), rgba(249, 115, 22, 0.06));
border: 1px solid var(--line);
border-radius: var(--r-md);
font-size: 13px;
color: var(--ink-2);
}
.side-card strong { display: block; color: var(--ink); margin-bottom: 4px; }
.side-card code { font-size: 0.82em; }
.scrim {
position: fixed;
inset: var(--topbar-h) 0 0 0;
background: rgba(15, 20, 30, 0.4);
z-index: 25;
}
/* ===== Main ===== */
.main {
min-width: 0;
padding: 28px clamp(18px, 4vw, 48px) 60px;
}
.block { margin-top: 46px; }
.block-head h2 {
margin: 0;
font-size: 21px;
font-weight: 800;
letter-spacing: -0.015em;
color: var(--ink);
}
.block-head p { margin: 4px 0 0; color: var(--muted); font-size: 14px; }
/* ===== Hero ===== */
.hero {
position: relative;
overflow: hidden;
margin-top: 18px;
padding: 38px clamp(20px, 4vw, 44px) 34px;
background: var(--panel);
border: 1px solid var(--line);
border-radius: var(--r-xl);
box-shadow: var(--shadow);
}
.hero-glow {
position: absolute;
inset: -40% -10% auto auto;
width: 420px;
height: 420px;
background: radial-gradient(circle at center, rgba(14, 165, 233, 0.18), transparent 62%),
radial-gradient(circle at 70% 40%, rgba(249, 115, 22, 0.14), transparent 60%);
filter: blur(8px);
pointer-events: none;
}
.greeting {
position: relative;
margin: 0 0 6px;
font-weight: 600;
font-size: 14px;
color: var(--accent-2);
}
.hero h1 {
position: relative;
margin: 0 0 10px;
font-size: clamp(28px, 4.4vw, 40px);
font-weight: 800;
letter-spacing: -0.025em;
line-height: 1.08;
}
.hero h1 span { color: var(--accent); }
.hero-sub {
position: relative;
max-width: 620px;
margin: 0 0 22px;
color: var(--ink-2);
font-size: 15.5px;
line-height: 1.6;
}
.hero-search {
position: relative;
max-width: 600px;
display: flex;
align-items: center;
gap: 10px;
background: var(--bg);
border: 1.5px solid var(--line-2);
border-radius: var(--r-lg);
padding: 0 14px;
height: 52px;
box-shadow: var(--shadow);
transition: border-color 0.15s, box-shadow 0.15s;
}
.hero-search:focus-within {
border-color: var(--accent);
box-shadow: 0 0 0 4px rgba(14, 165, 233, 0.14), var(--shadow);
}
.hs-icon { width: 20px; height: 20px; fill: var(--muted); flex-shrink: 0; }
.hero-search input {
flex: 1;
border: 0;
background: transparent;
font: inherit;
font-size: 15px;
color: var(--ink);
outline: none;
}
.search-results {
position: absolute;
top: calc(100% + 8px);
left: 0;
right: 0;
z-index: 30;
background: var(--panel);
border: 1px solid var(--line-2);
border-radius: var(--r-md);
box-shadow: var(--shadow-hi);
padding: 6px;
max-height: 340px;
overflow-y: auto;
}
.sr-group-label {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--muted);
padding: 8px 10px 4px;
}
.sr-item {
display: flex;
align-items: center;
gap: 10px;
padding: 9px 10px;
border-radius: var(--r-sm);
cursor: pointer;
color: var(--ink);
}
.sr-item:hover, .sr-item.is-active { background: var(--bg-2); }
.sr-item .sr-emoji { font-size: 16px; }
.sr-item .sr-text { flex: 1; min-width: 0; }
.sr-item .sr-title { font-weight: 600; font-size: 14px; }
.sr-item .sr-title mark { background: rgba(249, 115, 22, 0.28); color: inherit; border-radius: 3px; padding: 0 1px; }
.sr-item .sr-cat { font-size: 12px; color: var(--muted); }
.sr-item .sr-arrow { color: var(--muted); font-size: 13px; }
.sr-empty { padding: 18px 12px; text-align: center; color: var(--muted); font-size: 14px; }
.hero-chips {
position: relative;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
margin-top: 16px;
}
.chip-label { font-size: 13px; color: var(--muted); font-weight: 500; }
.chip {
border: 1px solid var(--line);
background: var(--bg-2);
color: var(--ink-2);
border-radius: 999px;
padding: 5px 13px;
font: inherit;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: background 0.14s, border-color 0.14s, color 0.14s, transform 0.1s;
}
.chip:hover { background: rgba(14, 165, 233, 0.10); border-color: var(--accent); color: var(--link-hover); }
.chip:active { transform: translateY(1px); }
/* ===== Quick-link grid ===== */
.ql-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(248px, 1fr));
gap: 16px;
margin-top: 18px;
}
.ql-card {
--accent-c: var(--accent);
background: var(--panel);
border: 1px solid var(--line);
border-radius: var(--r-lg);
overflow: hidden;
box-shadow: var(--shadow);
transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.ql-card:hover {
transform: translateY(-3px);
box-shadow: var(--shadow-hi);
border-color: color-mix(in srgb, var(--accent-c) 55%, var(--line-2));
}
.ql-toggle {
display: flex;
align-items: center;
gap: 12px;
width: 100%;
border: 0;
background: transparent;
cursor: pointer;
padding: 16px 16px;
text-align: left;
font: inherit;
border-left: 3px solid var(--accent-c);
}
.ql-icon {
display: grid;
place-items: center;
width: 38px;
height: 38px;
border-radius: 10px;
font-size: 19px;
background: color-mix(in srgb, var(--accent-c) 14%, transparent);
flex-shrink: 0;
}
.ql-title {
display: flex;
flex-direction: column;
font-weight: 700;
font-size: 15px;
color: var(--ink);
flex: 1;
}
.ql-title small { font-weight: 500; font-size: 12px; color: var(--muted); margin-top: 1px; }
.chev { width: 18px; height: 18px; fill: none; stroke: var(--muted); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; transition: transform 0.22s ease; }
.ql-toggle[aria-expanded="false"] .chev { transform: rotate(-90deg); }
.ql-body {
display: grid;
grid-template-rows: 1fr;
transition: grid-template-rows 0.26s ease;
}
.ql-body > ul { overflow: hidden; }
.ql-card.is-collapsed .ql-body { grid-template-rows: 0fr; }
.ql-body ul {
list-style: none;
margin: 0;
padding: 0 16px 14px 56px;
}
.ql-body li { margin: 0; }
.ql-body a {
display: block;
padding: 6px 0;
font-size: 13.5px;
color: var(--ink-2);
border-bottom: 1px dashed transparent;
}
.ql-body a:hover { color: var(--link-hover); text-decoration: none; border-bottom-color: var(--line-2); }
.ql-body code { font-size: 0.8em; }
.ql-card--cta {
background: linear-gradient(160deg, rgba(14, 165, 233, 0.07), rgba(249, 115, 22, 0.06));
display: flex;
}
.ql-cta { padding: 18px; }
.ql-cta h3 { margin: 10px 0 4px; font-size: 15px; font-weight: 700; }
.ql-cta p { margin: 0 0 12px; font-size: 13px; color: var(--ink-2); }
.btn-ghost {
display: inline-block;
font-size: 13px;
font-weight: 600;
color: var(--link-hover);
padding: 7px 13px;
border: 1px solid var(--accent);
border-radius: var(--r-sm);
background: var(--bg);
}
.btn-ghost:hover { background: var(--accent); color: #fff; text-decoration: none; }
/* ===== Two columns ===== */
.columns {
display: grid;
grid-template-columns: 1.25fr 1fr;
gap: 28px;
align-items: start;
}
.col { min-width: 0; }
.update-list, .popular-list { list-style: none; margin: 16px 0 0; padding: 0; }
.update-list li {
display: flex;
gap: 12px;
padding: 13px 0;
border-bottom: 1px solid var(--line);
}
.update-list li:last-child { border-bottom: 0; }
.up-tag {
flex-shrink: 0;
height: fit-content;
font-size: 10.5px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 3px 8px;
border-radius: 999px;
margin-top: 2px;
}
.up-tag--new { background: rgba(22, 163, 74, 0.12); color: #15803d; }
.up-tag--edit { background: rgba(14, 165, 233, 0.12); color: var(--link-hover); }
.update-list a { font-weight: 600; font-size: 14.5px; color: var(--ink); }
.update-list a:hover { color: var(--link-hover); }
.update-list p { margin: 2px 0 0; font-size: 13px; color: var(--ink-2); }
.up-meta { display: block; margin-top: 3px; color: var(--muted); font-size: 12px; }
.popular-list { counter-reset: pop; }
.popular-list li {
display: flex;
align-items: center;
gap: 12px;
padding: 11px 12px;
border-radius: var(--r-md);
transition: background 0.14s;
}
.popular-list li:hover { background: var(--panel); box-shadow: var(--shadow); }
.rank {
display: grid;
place-items: center;
width: 24px;
height: 24px;
border-radius: 7px;
font-weight: 700;
font-size: 12.5px;
background: var(--bg-2);
color: var(--ink-2);
flex-shrink: 0;
}
.popular-list li:nth-child(1) .rank { background: rgba(249, 115, 22, 0.16); color: var(--accent-2); }
.popular-list li:nth-child(2) .rank { background: rgba(14, 165, 233, 0.16); color: var(--link-hover); }
.popular-list a { flex: 1; font-weight: 500; font-size: 14px; color: var(--ink); }
.popular-list a:hover { color: var(--link-hover); }
.views {
font-family: "JetBrains Mono", monospace;
font-size: 12px;
color: var(--muted);
flex-shrink: 0;
}
/* ===== Contacts ===== */
.contacts-strip {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 14px;
margin-top: 18px;
}
.contact {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 4px;
padding: 20px 14px 16px;
background: var(--panel);
border: 1px solid var(--line);
border-radius: var(--r-lg);
box-shadow: var(--shadow);
transition: transform 0.18s, box-shadow 0.18s;
}
.contact:hover { transform: translateY(-3px); box-shadow: var(--shadow-hi); }
.contact strong { margin-top: 8px; font-size: 14.5px; color: var(--ink); }
.contact .role { font-size: 12.5px; color: var(--muted); }
.contact-meta {
margin-top: 8px;
font-family: "JetBrains Mono", monospace;
font-size: 11.5px;
color: var(--link-hover);
background: rgba(14, 165, 233, 0.10);
padding: 3px 9px;
border-radius: 999px;
opacity: 0;
transform: translateY(4px);
transition: opacity 0.18s, transform 0.18s;
}
.contact:hover .contact-meta, .contact:focus-within .contact-meta { opacity: 1; transform: translateY(0); }
/* ===== Footer ===== */
.foot {
margin-top: 56px;
padding-top: 22px;
border-top: 1px solid var(--line);
color: var(--muted);
font-size: 13px;
}
.foot p { margin: 0 0 4px; }
.foot-note { font-style: italic; opacity: 0.85; }
/* ===== Toast ===== */
.toast {
position: fixed;
left: 50%;
bottom: 26px;
transform: translate(-50%, 24px);
background: var(--ink);
color: #fff;
padding: 11px 18px;
border-radius: 999px;
font-size: 13.5px;
font-weight: 500;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28);
opacity: 0;
pointer-events: none;
transition: opacity 0.22s, transform 0.22s;
z-index: 60;
max-width: 90vw;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
/* ===== Responsive ===== */
@media (max-width: 820px) {
.shell { grid-template-columns: 1fr; }
.nav-toggle { display: flex; }
.sidebar {
position: fixed;
top: var(--topbar-h);
left: 0;
bottom: 0;
width: 280px;
height: auto;
z-index: 30;
transform: translateX(-100%);
transition: transform 0.24s ease;
box-shadow: 6px 0 28px rgba(20, 20, 30, 0.12);
}
.sidebar.open { transform: translateX(0); }
.columns { grid-template-columns: 1fr; gap: 36px; }
.topbar-search { display: none; }
}
@media (max-width: 520px) {
body { font-size: 14.5px; }
.topbar { gap: 10px; padding: 0 12px; }
.brand-text { display: none; }
.user-name { display: none; }
.user-chip { padding: 4px; }
.main { padding: 20px 16px 48px; }
.hero { padding: 28px 18px 26px; border-radius: var(--r-lg); }
.hero-search { height: 48px; }
.ql-grid { grid-template-columns: 1fr; }
.contacts-strip { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}
@media (prefers-reduced-motion: reduce) {
* { transition: none !important; scroll-behavior: auto !important; }
}(function () {
"use strict";
/* ---------- Toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer;
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, 2400);
}
/* ---------- Time-of-day greeting (simulated) ---------- */
var greetingEl = document.getElementById("greeting");
var NAME = "Maya";
function refreshGreeting() {
// Simulate "company time" — drifts so the demo shows different greetings.
var h = new Date().getHours();
var word, emoji;
if (h < 5) { word = "Working late"; emoji = "🌙"; }
else if (h < 12) { word = "Good morning"; emoji = "👋"; }
else if (h < 17) { word = "Good afternoon"; emoji = "☀️"; }
else if (h < 21) { word = "Good evening"; emoji = "🌆"; }
else { word = "Working late"; emoji = "🌙"; }
if (greetingEl) greetingEl.textContent = word + ", " + NAME + " " + emoji;
}
refreshGreeting();
setInterval(refreshGreeting, 60000);
/* ---------- Search index + preview ---------- */
var INDEX = [
{ title: "First week checklist", cat: "Onboarding", emoji: "🚀", kw: "onboarding start new hire checklist first week" },
{ title: "Setting up your laptop & SSO", cat: "Onboarding", emoji: "💻", kw: "laptop sso login setup device" },
{ title: "Onboarding buddy program v2", cat: "Onboarding", emoji: "🤝", kw: "buddy mentor onboarding match" },
{ title: "Code of conduct", cat: "Policies", emoji: "📐", kw: "conduct behavior policy ethics" },
{ title: "Remote & hybrid work", cat: "Policies", emoji: "🏠", kw: "remote hybrid work from home wfh" },
{ title: "Expense & reimbursement", cat: "Policies", emoji: "🧾", kw: "expense reimbursement travel money receipt per diem" },
{ title: "Security & data handling", cat: "Policies", emoji: "🔐", kw: "security data handling privacy vpn" },
{ title: "VPN & SSO setup guide", cat: "Engineering", emoji: "🔌", kw: "vpn network connect setup sso access" },
{ title: "Health & dental coverage", cat: "Benefits", emoji: "🩺", kw: "health dental insurance coverage medical benefits" },
{ title: "Parental leave & family support", cat: "Benefits", emoji: "👶", kw: "parental maternity paternity leave family baby time off" },
{ title: "Learning & growth stipend", cat: "Benefits", emoji: "📚", kw: "learning growth stipend education course budget" },
{ title: "401(k) & equity basics", cat: "Benefits", emoji: "📈", kw: "401k equity stock retirement benefits" },
{ title: "Dev environment setup", cat: "Engineering", emoji: "🛠️", kw: "dev environment setup local engineering" },
{ title: "On-call & incident response", cat: "Engineering", emoji: "🚨", kw: "on-call oncall incident pager nimbus rotation" },
{ title: "Code review guidelines", cat: "Engineering", emoji: "🔎", kw: "code review pull request guidelines engineering" },
{ title: "Deploying to Nimbus", cat: "Engineering", emoji: "🚀", kw: "deploy nimbus release ship production" },
{ title: "How to request time off", cat: "People Ops", emoji: "🌴", kw: "time off pto vacation leave request holiday" },
{ title: "Performance & growth cycles", cat: "People Ops", emoji: "🌱", kw: "performance review growth promotion cycle" },
{ title: "Internal transfers", cat: "People Ops", emoji: "🔁", kw: "internal transfer move team role change" },
{ title: "Org chart & teams", cat: "People Ops", emoji: "🗂️", kw: "org chart teams structure people" }
];
var heroInput = document.getElementById("heroSearch");
var resultsBox = document.getElementById("searchResults");
var activeIndex = -1;
var currentMatches = [];
function escapeHtml(s) {
return s.replace(/[&<>"']/g, function (c) {
return { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[c];
});
}
function highlight(title, q) {
var safe = escapeHtml(title);
if (!q) return safe;
var i = title.toLowerCase().indexOf(q.toLowerCase());
if (i < 0) return safe;
var pre = escapeHtml(title.slice(0, i));
var mid = escapeHtml(title.slice(i, i + q.length));
var post = escapeHtml(title.slice(i + q.length));
return pre + "<mark>" + mid + "</mark>" + post;
}
function search(q) {
var query = q.trim().toLowerCase();
if (!query) return [];
return INDEX.filter(function (item) {
return (item.title + " " + item.cat + " " + item.kw).toLowerCase().indexOf(query) > -1;
}).slice(0, 7);
}
function renderResults(q) {
currentMatches = search(q);
activeIndex = -1;
if (!q.trim()) {
closeResults();
return;
}
if (!currentMatches.length) {
resultsBox.innerHTML = '<div class="sr-empty">No pages match “' + escapeHtml(q) + '”. Try a broader term.</div>';
} else {
var html = '<div class="sr-group-label">' + currentMatches.length + ' result' + (currentMatches.length > 1 ? "s" : "") + "</div>";
html += currentMatches.map(function (item, idx) {
return '<div class="sr-item" role="option" data-idx="' + idx + '">' +
'<span class="sr-emoji" aria-hidden="true">' + item.emoji + "</span>" +
'<span class="sr-text"><span class="sr-title">' + highlight(item.title, q) + "</span>" +
'<span class="sr-cat">' + escapeHtml(item.cat) + "</span></span>" +
'<span class="sr-arrow" aria-hidden="true">↵</span></div>';
}).join("");
resultsBox.innerHTML = html;
}
openResults();
}
function openResults() {
resultsBox.hidden = false;
heroInput.setAttribute("aria-expanded", "true");
}
function closeResults() {
resultsBox.hidden = true;
heroInput.setAttribute("aria-expanded", "false");
activeIndex = -1;
}
function setActive(idx) {
var items = resultsBox.querySelectorAll(".sr-item");
if (!items.length) return;
activeIndex = (idx + items.length) % items.length;
items.forEach(function (el, i) {
el.classList.toggle("is-active", i === activeIndex);
});
items[activeIndex].scrollIntoView({ block: "nearest" });
}
function pick(idx) {
if (idx < 0 || idx >= currentMatches.length) return;
var item = currentMatches[idx];
toast("Opening “" + item.title + "” · " + item.cat);
closeResults();
}
if (heroInput) {
heroInput.addEventListener("input", function () {
renderResults(heroInput.value);
});
heroInput.addEventListener("focus", function () {
if (heroInput.value.trim()) renderResults(heroInput.value);
});
heroInput.addEventListener("keydown", function (e) {
if (resultsBox.hidden) return;
if (e.key === "ArrowDown") { e.preventDefault(); setActive(activeIndex + 1); }
else if (e.key === "ArrowUp") { e.preventDefault(); setActive(activeIndex - 1); }
else if (e.key === "Enter") {
e.preventDefault();
pick(activeIndex >= 0 ? activeIndex : 0);
} else if (e.key === "Escape") { closeResults(); }
});
resultsBox.addEventListener("mousedown", function (e) {
var item = e.target.closest(".sr-item");
if (item) { e.preventDefault(); pick(parseInt(item.dataset.idx, 10)); }
});
}
document.addEventListener("click", function (e) {
if (!e.target.closest(".hero-search")) closeResults();
});
/* ---------- Popular-search chips ---------- */
document.querySelectorAll(".chip[data-q]").forEach(function (chip) {
chip.addEventListener("click", function () {
heroInput.value = chip.dataset.q;
heroInput.focus();
renderResults(chip.dataset.q);
});
});
/* ---------- Top search → focuses hero ---------- */
var topSearch = document.getElementById("topSearch");
if (topSearch) {
topSearch.addEventListener("focus", function () {
topSearch.blur();
heroInput.scrollIntoView({ behavior: "smooth", block: "center" });
setTimeout(function () { heroInput.focus(); }, 240);
});
}
/* ---------- "/" keyboard shortcut ---------- */
document.addEventListener("keydown", function (e) {
if (e.key === "/" && document.activeElement !== heroInput &&
!/^(input|textarea)$/i.test(document.activeElement.tagName)) {
e.preventDefault();
heroInput.focus();
}
});
/* ---------- Collapsible quick-link sections ---------- */
document.querySelectorAll(".ql-toggle").forEach(function (btn) {
var card = btn.closest(".ql-card");
var accent = card.getAttribute("data-accent");
if (accent) card.style.setProperty("--accent-c", accent);
btn.addEventListener("click", function () {
var collapsed = card.classList.toggle("is-collapsed");
btn.setAttribute("aria-expanded", String(!collapsed));
});
});
/* ---------- Set quick-link card accents (CTA + cards) ---------- */
document.querySelectorAll(".ql-card[data-accent]").forEach(function (card) {
card.style.setProperty("--accent-c", card.getAttribute("data-accent"));
});
/* ---------- Avatar hue ---------- */
document.querySelectorAll(".avatar[data-hue]").forEach(function (av) {
av.style.setProperty("--hue", av.getAttribute("data-hue"));
});
/* ---------- Mobile sidebar drawer ---------- */
var navToggle = document.getElementById("navToggle");
var sidebar = document.getElementById("sidebar");
var scrim = document.getElementById("scrim");
function setDrawer(open) {
sidebar.classList.toggle("open", open);
scrim.hidden = !open;
navToggle.setAttribute("aria-expanded", String(open));
}
if (navToggle) navToggle.addEventListener("click", function () {
setDrawer(!sidebar.classList.contains("open"));
});
if (scrim) scrim.addEventListener("click", function () { setDrawer(false); });
/* ---------- Sidebar active link via scroll spy ---------- */
var sideLinks = Array.prototype.slice.call(document.querySelectorAll(".side-nav a[href^='#']"));
var sections = sideLinks
.map(function (a) { return document.getElementById(a.getAttribute("href").slice(1)); })
.filter(Boolean);
sideLinks.forEach(function (a) {
a.addEventListener("click", function () {
if (window.innerWidth <= 820) setDrawer(false);
});
});
if ("IntersectionObserver" in window && sections.length) {
var spy = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
var id = entry.target.id;
sideLinks.forEach(function (a) {
a.classList.toggle("active", a.getAttribute("href") === "#" + id);
});
}
});
}, { rootMargin: "-45% 0px -50% 0px", threshold: 0 });
sections.forEach(function (s) { spy.observe(s); });
}
/* ---------- User chip + contact channel copy ---------- */
var userChip = document.getElementById("userChip");
if (userChip) userChip.addEventListener("click", function () {
toast("Signed in as Maya Okafor · Engineering");
});
document.querySelectorAll(".contact").forEach(function (c) {
c.addEventListener("click", function () {
var name = c.querySelector("strong").textContent;
var ch = c.querySelector(".contact-meta").textContent;
toast("Say hi to " + name + " in " + ch);
});
});
/* ---------- Update + popular link clicks ---------- */
document.querySelectorAll(".update-list a, .popular-list a").forEach(function (a) {
a.addEventListener("click", function (e) {
e.preventDefault();
toast("Opening “" + a.textContent.trim() + "”");
});
});
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Acme Handbook — Internal Company Wiki</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<!-- Top bar -->
<header class="topbar">
<button class="nav-toggle" id="navToggle" aria-label="Open navigation" aria-expanded="false" aria-controls="sidebar">
<span></span><span></span><span></span>
</button>
<a class="brand" href="#main" aria-label="Acme Handbook home">
<span class="brand-mark" aria-hidden="true">A</span>
<span class="brand-text">Acme <span>Handbook</span></span>
</a>
<div class="topbar-search" role="search">
<svg class="ts-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M11 4a7 7 0 1 1-4.95 11.95l-3.3 3.3-1.4-1.4 3.3-3.3A7 7 0 0 1 11 4Zm0 2a5 5 0 1 0 0 10 5 5 0 0 0 0-10Z"/></svg>
<input id="topSearch" type="search" placeholder="Search the handbook…" aria-label="Search the handbook" autocomplete="off" />
<kbd>/</kbd>
</div>
<div class="topbar-user">
<button class="user-chip" id="userChip" aria-label="Account: Maya Okafor">
<span class="avatar" data-initials="MO" data-hue="200" aria-hidden="true"></span>
<span class="user-name">Maya O.</span>
</button>
</div>
</header>
<div class="shell">
<!-- Sidebar -->
<nav class="sidebar" id="sidebar" aria-label="Handbook sections">
<div class="sidebar-inner">
<p class="side-label">Browse</p>
<ul class="side-nav">
<li><a href="#welcome" class="active"><span class="dot" style="--c:#0ea5e9"></span>Home</a></li>
<li><a href="#onboarding"><span class="dot" style="--c:#f97316"></span>Onboarding</a></li>
<li><a href="#policies"><span class="dot" style="--c:#8b5cf6"></span>Policies</a></li>
<li><a href="#benefits"><span class="dot" style="--c:#16a34a"></span>Benefits</a></li>
<li><a href="#engineering"><span class="dot" style="--c:#dc2626"></span>Engineering</a></li>
<li><a href="#people"><span class="dot" style="--c:#d97706"></span>People Ops</a></li>
</ul>
<p class="side-label">Quick help</p>
<ul class="side-nav side-nav--muted">
<li><a href="#contacts">Who to ask</a></li>
<li><a href="#updates">Recently updated</a></li>
<li><a href="#popular">Most viewed</a></li>
</ul>
<div class="side-card">
<strong>Can't find it?</strong>
<p>Ask in <code>#ask-peopleops</code> on Slack — someone usually replies within the hour.</p>
</div>
</div>
</nav>
<div class="scrim" id="scrim" hidden></div>
<!-- Main -->
<main class="main" id="main">
<!-- Hero -->
<section class="hero" id="welcome">
<div class="hero-glow" aria-hidden="true"></div>
<p class="greeting" id="greeting">Good morning, Maya 👋</p>
<h1>Welcome to the <span>Acme Handbook</span></h1>
<p class="hero-sub">Everything you need to work at Acme Robotics — onboarding checklists, policies, benefits, engineering playbooks and the people who can help. Public to every employee, edited in the open.</p>
<div class="hero-search" role="search">
<svg class="hs-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M11 4a7 7 0 1 1-4.95 11.95l-3.3 3.3-1.4-1.4 3.3-3.3A7 7 0 0 1 11 4Zm0 2a5 5 0 1 0 0 10 5 5 0 0 0 0-10Z"/></svg>
<input id="heroSearch" type="search" placeholder="Try “parental leave”, “VPN setup”, “expense policy”…" aria-label="Search the handbook" aria-expanded="false" aria-controls="searchResults" autocomplete="off" />
<div class="search-results" id="searchResults" role="listbox" aria-label="Search suggestions" hidden></div>
</div>
<div class="hero-chips" aria-label="Popular searches">
<span class="chip-label">Popular:</span>
<button class="chip" data-q="onboarding">Onboarding</button>
<button class="chip" data-q="leave">Time off</button>
<button class="chip" data-q="vpn">VPN setup</button>
<button class="chip" data-q="expense">Expenses</button>
</div>
</section>
<!-- Quick links -->
<section class="block" aria-labelledby="ql-h">
<div class="block-head">
<h2 id="ql-h">Jump to a section</h2>
<p>Five core areas of the handbook. Click a header to collapse it.</p>
</div>
<div class="ql-grid" id="qlGrid">
<article class="ql-card" data-accent="#0ea5e9" id="onboarding">
<button class="ql-toggle" aria-expanded="true" aria-controls="ql-body-1">
<span class="ql-icon" aria-hidden="true">🚀</span>
<span class="ql-title">Onboarding<small>14 pages</small></span>
<svg class="chev" viewBox="0 0 24 24" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div class="ql-body" id="ql-body-1">
<ul>
<li><a href="#">Your first week checklist</a></li>
<li><a href="#">Setting up your laptop & SSO</a></li>
<li><a href="#">Meet your onboarding buddy</a></li>
<li><a href="#">Company values & rituals</a></li>
</ul>
</div>
</article>
<article class="ql-card" data-accent="#8b5cf6" id="policies">
<button class="ql-toggle" aria-expanded="true" aria-controls="ql-body-2">
<span class="ql-icon" aria-hidden="true">📐</span>
<span class="ql-title">Policies<small>22 pages</small></span>
<svg class="chev" viewBox="0 0 24 24" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div class="ql-body" id="ql-body-2">
<ul>
<li><a href="#">Code of conduct</a></li>
<li><a href="#">Remote & hybrid work</a></li>
<li><a href="#">Expense & reimbursement</a></li>
<li><a href="#">Security & data handling</a></li>
</ul>
</div>
</article>
<article class="ql-card" data-accent="#16a34a" id="benefits">
<button class="ql-toggle" aria-expanded="true" aria-controls="ql-body-3">
<span class="ql-icon" aria-hidden="true">🌿</span>
<span class="ql-title">Benefits<small>18 pages</small></span>
<svg class="chev" viewBox="0 0 24 24" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div class="ql-body" id="ql-body-3">
<ul>
<li><a href="#">Health & dental coverage</a></li>
<li><a href="#">Parental leave & family support</a></li>
<li><a href="#">Learning & growth stipend</a></li>
<li><a href="#">401(k) & equity basics</a></li>
</ul>
</div>
</article>
<article class="ql-card" data-accent="#dc2626" id="engineering">
<button class="ql-toggle" aria-expanded="true" aria-controls="ql-body-4">
<span class="ql-icon" aria-hidden="true">🛠️</span>
<span class="ql-title">Engineering<small>41 pages</small></span>
<svg class="chev" viewBox="0 0 24 24" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div class="ql-body" id="ql-body-4">
<ul>
<li><a href="#">Dev environment setup</a></li>
<li><a href="#">On-call & incident response</a></li>
<li><a href="#">Code review guidelines</a></li>
<li><a href="#">Deploying to <code>Nimbus</code></a></li>
</ul>
</div>
</article>
<article class="ql-card" data-accent="#d97706" id="people">
<button class="ql-toggle" aria-expanded="true" aria-controls="ql-body-5">
<span class="ql-icon" aria-hidden="true">🧑🤝🧑</span>
<span class="ql-title">People Ops<small>16 pages</small></span>
<svg class="chev" viewBox="0 0 24 24" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div class="ql-body" id="ql-body-5">
<ul>
<li><a href="#">Performance & growth cycles</a></li>
<li><a href="#">Requesting time off</a></li>
<li><a href="#">Internal transfers</a></li>
<li><a href="#">Org chart & teams</a></li>
</ul>
</div>
</article>
<article class="ql-card ql-card--cta" data-accent="#0ea5e9">
<div class="ql-cta">
<span class="ql-icon" aria-hidden="true">✏️</span>
<h3>Edit this handbook</h3>
<p>Spotted something out of date? Anyone can open a change request.</p>
<a class="btn-ghost" href="#">Propose an edit →</a>
</div>
</article>
</div>
</section>
<!-- Two column: updates + popular -->
<section class="block columns" aria-label="Activity">
<div class="col">
<div class="block-head" id="updates">
<h2>New this week</h2>
<p>Pages added or revised in the last 7 days.</p>
</div>
<ul class="update-list">
<li>
<span class="up-tag up-tag--new">New</span>
<div>
<a href="#">2026 remote work allowance</a>
<p>Home-office stipend raised to $1,000/yr. <span class="up-meta">Policies · 2 days ago · Priya N.</span></p>
</div>
</li>
<li>
<span class="up-tag up-tag--edit">Edited</span>
<div>
<a href="#">On-call rotation for Project Nimbus</a>
<p>Added the new EU follow-the-sun shift. <span class="up-meta">Engineering · 3 days ago · Diego R.</span></p>
</div>
</li>
<li>
<span class="up-tag up-tag--edit">Edited</span>
<div>
<a href="#">Parental leave: phased return</a>
<p>Clarified the 4-week ramp-back option. <span class="up-meta">Benefits · 4 days ago · Sara L.</span></p>
</div>
</li>
<li>
<span class="up-tag up-tag--new">New</span>
<div>
<a href="#">Onboarding buddy program v2</a>
<p>How buddies are matched and what to expect. <span class="up-meta">Onboarding · 5 days ago · Maya O.</span></p>
</div>
</li>
<li>
<span class="up-tag up-tag--edit">Edited</span>
<div>
<a href="#">Expense policy — travel caps</a>
<p>Updated per-diem rates for 2026. <span class="up-meta">Policies · 6 days ago · Finance Team</span></p>
</div>
</li>
</ul>
</div>
<div class="col">
<div class="block-head" id="popular">
<h2>Most viewed</h2>
<p>What the company reads most this quarter.</p>
</div>
<ol class="popular-list">
<li>
<span class="rank">1</span>
<a href="#">How to request time off</a>
<span class="views">8.4k</span>
</li>
<li>
<span class="rank">2</span>
<a href="#">VPN & SSO setup guide</a>
<span class="views">6.1k</span>
</li>
<li>
<span class="rank">3</span>
<a href="#">Expense & reimbursement</a>
<span class="views">5.7k</span>
</li>
<li>
<span class="rank">4</span>
<a href="#">Code review guidelines</a>
<span class="views">4.9k</span>
</li>
<li>
<span class="rank">5</span>
<a href="#">Health & dental coverage</a>
<span class="views">4.2k</span>
</li>
<li>
<span class="rank">6</span>
<a href="#">Your first week checklist</a>
<span class="views">3.8k</span>
</li>
</ol>
</div>
</section>
<!-- Who to ask -->
<section class="block" aria-labelledby="contacts-h" id="contacts">
<div class="block-head">
<h2 id="contacts-h">Who to ask</h2>
<p>Real humans behind each area. Hover a card for their channel.</p>
</div>
<div class="contacts-strip">
<article class="contact">
<span class="avatar avatar--lg" data-initials="PN" data-hue="200" aria-hidden="true"></span>
<strong>Priya Nair</strong>
<span class="role">People Ops Lead</span>
<span class="contact-meta">#ask-peopleops</span>
</article>
<article class="contact">
<span class="avatar avatar--lg" data-initials="DR" data-hue="20" aria-hidden="true"></span>
<strong>Diego Reyes</strong>
<span class="role">Eng. Manager, Nimbus</span>
<span class="contact-meta">#nimbus-eng</span>
</article>
<article class="contact">
<span class="avatar avatar--lg" data-initials="SL" data-hue="150" aria-hidden="true"></span>
<strong>Sara Lindqvist</strong>
<span class="role">Benefits Specialist</span>
<span class="contact-meta">#ask-benefits</span>
</article>
<article class="contact">
<span class="avatar avatar--lg" data-initials="TK" data-hue="280" aria-hidden="true"></span>
<strong>Tomás Krause</strong>
<span class="role">IT & Security</span>
<span class="contact-meta">#it-helpdesk</span>
</article>
<article class="contact">
<span class="avatar avatar--lg" data-initials="AO" data-hue="330" aria-hidden="true"></span>
<strong>Amara Obi</strong>
<span class="role">Onboarding Buddy Coord.</span>
<span class="contact-meta">#onboarding</span>
</article>
</div>
</section>
<footer class="foot">
<p>Acme Robotics — Internal Handbook · Last full review June 2026 · Edited in the open by everyone.</p>
<p class="foot-note">Illustrative UI only — fictional articles, products, and data.</p>
</footer>
</main>
</div>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Internal Company Handbook Landing
A calm, approachable home page for an internal company handbook in the spirit of a Notion workspace or the GitLab handbook. A welcome hero greets the employee by name with a greeting that adapts to the time of day, anchored by a large search bar whose live preview filters a small index of handbook pages and supports full keyboard navigation — arrow keys, Enter to open, and Esc to dismiss. Press / anywhere to jump straight into search, or click a popular chip to pre-fill the query.
Below the hero, five collapsible quick-link cards cover Onboarding, Policies, Benefits, Engineering and People Ops, each with its own accent color, page count and a clickable header that folds the section away. A two-column activity area lists pages added or revised this week alongside a ranked most-viewed list, and a who-to-ask contacts strip introduces the humans behind each area with CSS-drawn gradient avatars that reveal their Slack channel on hover.
Everything is a single self-contained set of HTML, CSS and vanilla JavaScript — no frameworks or build step. The layout uses a persistent left sidebar with scroll-spy highlighting that collapses to a drawer on small screens, semantic landmarks, visible focus rings, and a small toast() helper for lightweight feedback when links and contacts are clicked.
Illustrative UI only — fictional articles, products, and data.