Single-file mobile-first web app for students attending East Meets West 2026 (Thursday, April 9, Sheraton Waikiki), now paired with a learner-friendly explainer page. Deployed to GitHub Pages.
https://lpcode808.github.io/EMW2026
https://lpcode808.github.io/EMW2026/code-guide.html
Primary attendee app: index.html — all CSS, JS, and data are embedded. No build step, no dependencies, no backend.
Companion explainer: code-guide.html — a mobile-friendly teaching page that links from the live app and explains the real code structure for students and conference learners.
- Data lives in two JS
constarrays at the top of the<script>block:SCHEDULEandSPEAKERS - Notes persist in
localStoragekeyemw2026_notes - Fonts loaded via Google Fonts: Sen (display/headings) + Manrope (body)
Dark mode adaptation of HSG-Branding (~/Coding/HSG-Branding/). CSS custom properties:
| Token | Value | Role |
|---|---|---|
--bg |
#001329 |
Page background |
--surface |
#002040 |
Cards, session rows |
--teal |
#07a8a8 |
Primary accent, CTAs, active states |
--orange |
#c8531d |
Keynote/pitch badges |
--lime |
#afcd53 |
Student summary, networking badges |
--text |
#fff7eb |
Body text |
Accordion animation uses max-height transitions with cubic-bezier(0.16, 1, 0.3, 1). Tap targets are minimum 44px throughout.
- Schedule — 24 Thursday schedule items, including the all-day Exhibitors Hall row plus the accordion session flow. Each expands to: meta (speaker/location/time), description, Student Summary sub-toggle, session note inline, external link.
- Speakers — 38 Thursday speaker entries, including the published VC 1-on-1 roster, alphabetical and searchable. Tap → shows company + session chips + a
g.airesearch link + a person-note field. Speaker rows support quick swipe-left to toggle a star on mobile, with a tap fallback button in expanded details plus top-of-list controls to pull starred people up top or clear them with confirmation. Tapping a session chip jumps to Schedule tab and opens that accordion. - Notes — quick-note composer for unlinked notes, saved session/person notes, export modal, clipboard button.
{
id: "thu-01", // unique, sequential
time: "9:15 AM",
timeEnd: "9:20 AM",
title: "...",
type: "keynote", // see badge types below
speaker: "Name · Name2", // · separated for multi-speaker
location: "...",
description: "...", // factual, from original PDF
studentSummary: "...", // student-friendly AI rewrite — FILL IN before event
subItems: [ // optional nested list (e.g. VC firm list)
{ title: "...", speaker: "..." }
]
}keynote fireside panel pitch roundtable networking mindfulness ceremony meal break welcome presentation announcement background
Meal/break/background items render at 60% opacity — intentionally de-emphasized.
{
name: "Full Name",
role: "Job Title",
company: "Organization",
sessions: ["thu-04", "thu-22"] // array of session IDs they appear in
}| Function | Purpose |
|---|---|
renderSchedule() |
Builds schedule HTML from SCHEDULE, attaches all events |
renderSpeakers(filter) |
Builds speakers list, accepts search string |
renderNotesTab() |
Renders saved notes sorted by schedule order |
toggleSession(id) |
Opens/closes a session accordion |
toggleSummary(id) |
Opens/closes the Student Summary sub-accordion |
toggleNotePanel(btn) |
Opens/closes a session or person note textarea |
saveNote(type, id, text) |
Persists typed notes, preserving original creation timestamp |
buildExportText() |
Formats all notes as plain text for clipboard export |
openSessionContext(id, opts) |
Switches to Schedule and optionally opens the note editor |
openSpeakerContext(id, opts) |
Switches to Speakers and optionally opens the person note editor |
showToast(msg) |
Shows 2-second bottom toast notification |
Notes are stored as typed objects keyed by context:
session:<sessionId>for inline session notesspeaker:<speakerId>for notes attached to a speaker profilegeneral:quick-note-<timestamp>for unlinked quick notes created from the Notes-tab composer
Each note stores:
{
key: "session:thu-04",
type: "session" | "speaker" | "general",
entityId: "thu-04",
text: "...",
createdAt: 1775020500000,
updatedAt: 1775020500000
}createdAt is the real device-local capture time source for the note UI/export (formatted on the client with Intl.DateTimeFormat). Existing legacy session notes are migrated automatically on load.
Speaker stars are stored separately in localStorage key emw2026_starred_speakers as a simple array of speaker IDs.
- Event-day data spot check: Compare the local Thursday speaker/session list against the official EMW 2026 site before shipping any new content changes, especially for closing-panel names and VC meeting participants.
- Bookmark/star sessions: Could add a ⭐ toggle per session stored in localStorage alongside notes.
- Speaker photos: Could add a
photofield to SPEAKERS and render<img>in the avatar circle instead of initials. - Share notes: Clipboard export is live; a future pass could add
navigator.share()on supported mobile browsers. - Filter by type: A row of badge-type filter pills above the schedule list (e.g., tap "Keynote" to show only keynotes).
Original conference data came from two PDFs placed in ~/Coding/HSG-Branding/ at build time. Schedule covers Thursday April 9 only — the group is not attending Wednesday April 8 (Summit at Koʻolau Ballrooms).
sw.js provides offline support via a stale-while-revalidate cache. It pre-caches index.html, podcast.html, code-guide.html, and favicon.svg on first visit so the app works without WiFi.
Important: After changing any cached file, bump the CACHE_NAME version in sw.js (e.g. emw2026-v1 → emw2026-v2). Without this, returning visitors may see stale content until the background revalidate completes on their next visit. The old cache is automatically cleaned up when the new version activates.
# If you changed index.html, podcast.html, code-guide.html, or favicon.svg, bump CACHE_NAME in sw.js first!
git add index.html sw.js
git commit -m "your message"
git push
# → live at https://lpcode808.github.io/EMW2026 within ~60 seconds