CultureHub is a pure-browser app for managing company culture events — check-ins, leaderboards, photo galleries, and printable reports. No sign-up, no server, no cloud. All data lives in your browser.
Eight pages, one CSS file, one data layer. Add people, run events, check in attendees, and celebrate winners — all without leaving the browser.
No install, no build step, no account. Open the HTML file and you're done.
checkin.html on a tablet or laptop at your event.
As people arrive, tap their card. Winners get 3 pts, attendees get 1 pt.
The leaderboard on dashboard.html updates live — put it on a screen for the room.
Six built-in types, each with a distinct color badge for quick visual scanning.
Everything lives in a single culturehub_data key in localStorage
as a JSON object with three top-level keys.
{
"version": 1,
"settings": {
"orgName": "Our Organization",
"theme": "dark" // legacy default; live theme ("dark"|"dim"|"light") + accent color are separate localStorage keys
},
"people": [
{
"id": "lx3k8a", // uid() — base36 timestamp + random
"name": "Alice Johnson",
"team": "Engineering",
"email": "alice@company.com",
"avatar": "" // reserved, auto-generated from initials
}
],
"events": [
{
"id": "m2p9xq",
"title": "Summer Trivia Night",
"date": "2025-07-15", // ISO date string
"type": "Game",
"description": "Teams compete in trivia!",
"location": "Rooftop",
"gallery": [
{ "id": "…", "url": "data:image/jpeg;base64,…", "caption": "" }
],
"attendees": [
{
"personId": "lx3k8a", // foreign key → people[].id
"checkedIn": true,
"points": 3,
"isWinner": true
}
]
}
]
}
localStorage, which browsers typically
cap at 5–10 MB. Use the built-in Backup feature regularly,
and delete old photos if you hit the limit.
A "Storage full" toast will appear if the quota is exceeded.
No framework, no bundler, no build step — pure HTML, CSS, and vanilla JS. Three files drive everything.
data.js
data layer
An IIFE that wraps all localStorage access behind a clean API.
Every mutation calls save(), which serialises the whole object to
localStorage and fires a CustomEvent so every page re-renders reactively.
window.CH // global singleton
CH.getPeople() CH.addPerson(…)
CH.getEvents() CH.addEvent(…)
CH.checkIn(…) CH.toggleWinner(…)
CH.getLeaderboard() CH.exportBackup()
CH.getPersonStats() CH.importBackup()
utils.js
UI helpers
Shared utilities loaded on every page after data.js.
Provides the nav template, theme + accent system, toast notifications,
modal helpers, avatar generation, date formatting, and PDF report builders.
Theme.toggle() Accent.apply(name) openModal(html) toast(msg, type) avatarEl(name, size) confirmDialog(msg) eventTypeBadge(type) fmtDate(dateStr) navHTML() generateReport(…)
style.css
design system
A single CSS file with a complete token-based design system.
Dark, Dim, and Light themes are declared as CSS custom properties on
html[data-theme], with Violet, Blue, Orange, and Red accent overrides layered on top via
html[data-theme][data-accent]. Components are utility-first with
semantic class names.
.card .btn-primary .badge-accent .modal .stat-card .progress-bar .avatar .chip .type-game .grid-2 .form-control .empty-state
Every page follows the same pattern: inject nav, call render(), and subscribe to
the culturehub:updated event so the page re-renders whenever data changes
(even if changed in another tab on the same origin).
// Every page — verbatim pattern document.getElementById('nav-root') .innerHTML = navHTML(); setActiveNav(); function render() { /* build innerHTML */ } window.addEventListener( 'culturehub:updated', render); render();
<script> in
<head> that reads the theme and accent from localStorage and sets
data-theme / data-accent on <html> before the stylesheet is parsed —
eliminating the flash of default (wrong) colors on load.
culturehub/ ├── index.html Home — stats overview, top-5 leaderboard, upcoming events ├── events.html Create / edit events, filter by type ├── roster.html Add / import people, view per-person stats ├── checkin.html Day-of attendance with check-in and winner flags ├── dashboard.html Live leaderboard, TV mode, clickable stat breakdowns, ticker ├── search.html Global search across people & events with detail panel ├── gallery.html Per-event photo grids with drag-drop upload and slideshow ├── settings.html Org name, appearance (theme/accent), backup/restore, import, danger zone │ ├── data.js CH singleton — all CRUD, leaderboard, import/export ├── utils.js Theme + Accent system, toasts, modals, avatars, date helpers, PDF reports ├── style.css Complete design system — Dark/Dim/Light themes × 5 accent colors │ └── docs/ └── index.html ← you are here
The Backup button (nav bar) or Settings → Download Backup JSON saves
the full culturehub_data object as a dated .json file.
Photos are embedded as base64 — the file is self-contained.
culturehub-backup-YYYY-MM-DD.json
Settings → Restore — load a backup file or paste JSON directly.
The restore validates the people and events keys before writing,
then fires culturehub:updated so all open tabs refresh.
Available throughout the app.