This is a submission for the DEV Weekend Challenge: Community
The Community
I built this for student developers and beginner hackers in my local tech community.
We participate in hackathons regularly — both online and offline — but we struggled with:
- Keeping track of upcoming hackathons
- Managing deadlines (registration, submission, demo day)
- Tracking ideas across multiple events
- Remembering which teammates joined which hackathon
Most of us used scattered tools like notes apps, Discord messages, or spreadsheets. There wasn’t a simple, focused tool built specifically for hackathon participants.
As someone who actively participates in hackathons, I wanted to build something tailored to our workflow.
What I Built
I built HackTrack, a lightweight hackathon tracker designed specifically for student builders.
It helps users:
- 🗓 Track upcoming hackathons
- ⏰ Monitor registration & submission deadlines
- 💡 Store project ideas for each event
- 👥 Keep track of teammates
- ✅ Mark hackathons as registered, submitted, or completed
The goal is simple:
Help builders stay organized so they can focus on building instead of scrambling at the last minute.
Demo
Code
<!DOCTYPE html>
Kathi Corp — Hackathon Tracker
:root { --gold: #c9a84c; --gold-light: #e8c97a; --gold-dim: rgba(201,168,76,0.18); --gold-glow: rgba(201,168,76,0.35); --crimson: #8b0000; --crimson-light: #c0000a; --bg: #07090f; --surface: rgba(255,255,255,0.035); --surface-hover: rgba(255,255,255,0.065); --border: rgba(201,168,76,0.18); --border-strong: rgba(201,168,76,0.45); --text: #ede8df; --muted: #7a7160; --muted2: #a89e88; --danger: #c0392b; } * { margin:0; padding:0; box-sizing:border-box; } body { background:var(--bg); color:var(--text); font-family:'Inter',sans-serif; min-height:100vh; overflow-x:hidden; } body::before { content:''; position:fixed; inset:0; background: radial-gradient(ellipse 70% 50% at 15% 10%, rgba(139,0,0,0.12) 0%, transparent 60%), radial-gradient(ellipse 60% 40% at 85% 90%, rgba(201,168,76,0.08) 0%, transparent 55%); pointer-events:none; z-index:0; } .swords-bg { position:fixed; inset:0; display:flex; align-items:center; justify-content:center; pointer-events:none; z-index:0; opacity:0.35; filter: drop-shadow(0 0 18px rgba(139,0,0,0.8)); } body::after { content:''; position:fixed; inset:0; background-image:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,0,0,0.03) 2px,rgba(0,0,0,0.03) 4px); pointer-events:none; z-index:0; } *{ position:relative; z-index:1; } /* HEADER */ header { border-bottom:1px solid var(--border); padding:2rem 3rem; display:flex; align-items:center; justify-content:center; gap:1.5rem; background:rgba(7,9,15,0.85); backdrop-filter:blur(32px); position:sticky; top:0; z-index:100; } header::after { content:''; position:absolute; bottom:0; left:0; right:0; height:1px; background:linear-gradient(90deg,transparent,var(--gold),transparent); opacity:0.5; } .crest { width:48px; height:48px; border:1.5px solid #8b0000; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:1.4rem; box-shadow:0 0 20px rgba(139,0,0,0.5),inset 0 0 12px rgba(139,0,0,0.15); flex-shrink:0; background:rgba(139,0,0,0.08); filter:drop-shadow(0 0 6px rgba(139,0,0,0.7)); } .brand { display:flex; flex-direction:column; gap:0.1rem; } .brand-name { font-family:'Cormorant Garamond',serif; font-size:1.65rem; font-weight:600; color:#ede8df; letter-spacing:0.12em; text-transform:uppercase; line-height:1; text-shadow: none; } .brand-sub { font-size:0.6rem; letter-spacing:0.25em; text-transform:uppercase; color:var(--muted); } .divider-v { width:1px; height:36px; background:linear-gradient(to bottom,transparent,var(--border-strong),transparent); margin:0 0.5rem; } .total-pill { font-family:'Cormorant Garamond',serif; font-size:1.1rem; color:#ede8df; letter-spacing:0.06em; border:1px solid var(--border); padding:0.4rem 1.1rem; border-radius:40px; background:var(--gold-dim); box-shadow:0 0 12px var(--gold-glow); } /* MAIN */ main { max-width:1000px; margin:0 auto; padding:3rem 2.5rem; } /* STATS */ .stats { display:grid; grid-template-columns:repeat(3,1fr); gap:1px; margin-bottom:2.5rem; border:1px solid var(--border); border-radius:16px; overflow:hidden; background:var(--border); box-shadow:0 8px 48px rgba(0,0,0,0.5); } .stat { background:rgba(7,9,15,0.96); padding:2rem 2rem 1.75rem; display:flex; flex-direction:column; gap:0.5rem; transition:background 0.3s; } .stat:hover { background:rgba(201,168,76,0.04); } .stat-num { font-family:'Cormorant Garamond',serif; font-size:3.5rem; font-weight:700; line-height:1; letter-spacing:-0.02em; } .form-title { font-family:'Cormorant Garamond',serif; font-size:1.2rem; letter-spacing:0.18em; text-transform:uppercase; color:#ede8df; margin-bottom:1.75rem; display:flex; align-items:center; gap:1rem; } .stat:nth-child(1) .stat-num { color:#ede8df; text-shadow:none; } .filter-btn.active { color:#ede8df; background:rgba(201,168,76,0.08); text-shadow:none; } .card-date-row.event-date { color:#ede8df; opacity:0.85; } .modal-title { font-family:'Cormorant Garamond',serif; font-size:1.3rem; letter-spacing:0.18em; text-transform:uppercase; color:#ede8df; margin-bottom:1.75rem; display:flex; align-items:center; gap:1rem; } .card-name { font-family:'Cormorant Garamond',serif; font-size:1.2rem; font-weight:600; color:#ede8df; letter-spacing:0.01em; line-height:1.3; } .btn-primary { background:linear-gradient(135deg,rgba(201,168,76,0.15),rgba(201,168,76,0.08)); border-color:var(--gold); color:#ede8df; box-shadow:0 0 20px rgba(201,168,76,0.15); } .btn-primary:hover { background:linear-gradient(135deg,rgba(201,168,76,0.25),rgba(201,168,76,0.12)); box-shadow:0 0 30px rgba(201,168,76,0.3); color:#fff; } .edit-btn { color:#ede8df; } .edit-btn:hover { color:#fff; background:rgba(201,168,76,0.12); border-color:rgba(201,168,76,0.35); } .stat:nth-child(2) .stat-num { color:#e8b84b; text-shadow:0 0 40px rgba(232,184,75,0.4); } .stat:nth-child(3) .stat-num { color:var(--muted2); } .stat-label { font-size:0.62rem; letter-spacing:0.2em; text-transform:uppercase; color:var(--muted); font-weight:500; } .stat-line { width:32px; height:1.5px; border-radius:1px; margin-bottom:0.25rem; } .stat:nth-child(1) .stat-line { background:var(--gold); box-shadow:0 0 8px var(--gold-glow); } .stat:nth-child(2) .stat-line { background:#e8b84b; } .stat:nth-child(3) .stat-line { background:var(--muted); } /* ADD BUTTON */ .add-btn { width:100%; margin-bottom:1.5rem; padding:1rem 2rem; background:transparent; border:1px solid var(--border-strong); border-radius:12px; color:#ede8df; font-family:'Cormorant Garamond',serif; font-size:1.1rem; letter-spacing:0.2em; text-transform:uppercase; cursor:pointer; display:flex; align-items:center; justify-content:center; gap:1rem; transition:all 0.35s; position:relative; overflow:hidden; } .add-btn::before { content:''; position:absolute; inset:0; background:linear-gradient(135deg,transparent 40%,rgba(201,168,76,0.06) 100%); opacity:0; transition:opacity 0.35s; } .add-btn:hover { border-color:var(--gold); box-shadow:0 0 30px var(--gold-glow),inset 0 0 20px rgba(201,168,76,0.05); color:#fff; text-shadow:none; } .add-btn:hover::before { opacity:1; } .add-btn .ornament { font-size:1rem; letter-spacing:0; color:#8b0000; text-shadow:0 0 10px rgba(139,0,0,0.6); } /* FORM */ .add-section { background:rgba(201,168,76,0.03); border:1px solid var(--border-strong); border-radius:16px; padding:2.25rem; margin-bottom:1.75rem; animation:reveal 0.4s cubic-bezier(0.16,1,0.3,1); box-shadow:0 20px 60px rgba(0,0,0,0.6),0 0 60px rgba(201,168,76,0.04); backdrop-filter:blur(12px); } @keyframes reveal { from{opacity:0;transform:translateY(-20px) scale(0.98)} to{opacity:1;transform:translateY(0) scale(1)} } .form-title { font-family:'Cormorant Garamond',serif; font-size:1.2rem; letter-spacing:0.18em; text-transform:uppercase; color:var(--gold); margin-bottom:1.75rem; display:flex; align-items:center; gap:1rem; } .form-title::before,.form-title::after { content:''; flex:1; height:1px; background:linear-gradient(to right,transparent,var(--border-strong)); } .form-title::after { background:linear-gradient(to left,transparent,var(--border-strong)); } .form-grid { display:grid; grid-template-columns:1fr 1fr; gap:1.25rem; } .form-group { display:flex; flex-direction:column; gap:0.55rem; } .form-group.full { grid-column:1/-1; } label { font-size:0.6rem; font-weight:600; letter-spacing:0.2em; text-transform:uppercase; color:var(--muted); } input,select,textarea { background:rgba(255,255,255,0.03); border:1px solid var(--border); border-radius:8px; color:var(--text); font-family:'Inter',sans-serif; font-size:0.85rem; padding:0.8rem 1rem; outline:none; transition:border-color 0.25s,box-shadow 0.25s; } input:focus,select:focus,textarea:focus { border-color:var(--gold); box-shadow:0 0 0 3px rgba(201,168,76,0.12),0 0 20px rgba(201,168,76,0.08); } input::placeholder,textarea::placeholder { color:var(--muted); font-size:0.8rem; } select option { background:#0f1117; color:var(--text); } textarea { resize:vertical; min-height:72px; } .btn-row { display:flex; gap:0.75rem; justify-content:flex-end; margin-top:1.5rem; } .btn { font-family:'Cormorant Garamond',serif; font-size:0.95rem; letter-spacing:0.15em; text-transform:uppercase; padding:0.7rem 1.75rem; border-radius:8px; cursor:pointer; border:1px solid; transition:all 0.25s; } .btn-primary { background:linear-gradient(135deg,rgba(201,168,76,0.15),rgba(201,168,76,0.08)); border-color:var(--gold); color:var(--gold-light); box-shadow:0 0 20px rgba(201,168,76,0.15); } .btn-primary:hover { background:linear-gradient(135deg,rgba(201,168,76,0.25),rgba(201,168,76,0.12)); box-shadow:0 0 30px rgba(201,168,76,0.3); color:#fff; } .btn-ghost { background:transparent; border-color:var(--border); color:var(--muted2); } .btn-ghost:hover { border-color:var(--muted2); color:var(--text); } /* FILTERS */ .filters { display:flex; gap:0; margin-bottom:1.5rem; border:1px solid var(--border); border-radius:12px; overflow:hidden; background:rgba(255,255,255,0.02); backdrop-filter:blur(8px); } .filter-btn { flex:1; background:transparent; border:none; color:var(--muted2); font-family:'Cormorant Garamond',serif; font-size:0.9rem; letter-spacing:0.12em; text-transform:uppercase; padding:0.75rem 1rem; cursor:pointer; transition:all 0.25s; border-right:1px solid var(--border); position:relative; } .filter-btn:last-child { border-right:none; } .filter-btn:hover { color:var(--gold); background:rgba(201,168,76,0.04); } .filter-btn.active { color:var(--gold-light); background:rgba(201,168,76,0.08); text-shadow:0 0 20px var(--gold-glow); } .filter-btn.active::after { content:''; position:absolute; bottom:0; left:0; right:0; height:1.5px; background:var(--gold); box-shadow:0 0 8px var(--gold-glow); } /* BLOCK GRID */ #hackList { display:grid; grid-template-columns:repeat(2,1fr); gap:1.25rem; } /* CARDS */ .card { display:flex; flex-direction:column; background:rgba(255,255,255,0.025); border:1px solid var(--border); border-radius:16px; animation:cardIn 0.4s ease; cursor:default; backdrop-filter:blur(4px); position:relative; overflow:hidden; transition:all 0.3s cubic-bezier(0.16,1,0.3,1); } .card::before { content:''; position:absolute; top:0; left:0; right:0; height:2px; background:linear-gradient(90deg,transparent,var(--gold),transparent); opacity:0; transition:opacity 0.3s; } .card:hover { background:rgba(201,168,76,0.04); border-color:rgba(201,168,76,0.35); transform:translateY(-4px); box-shadow:0 12px 48px rgba(0,0,0,0.5),0 0 30px rgba(201,168,76,0.06); } .card:hover::before { opacity:1; } @keyframes cardIn { from{opacity:0;transform:translateY(14px) scale(0.97)} to{opacity:1;transform:translateY(0) scale(1)} } .card-header { padding:1.4rem 1.4rem 1rem; display:flex; flex-direction:column; gap:0.5rem; flex:1; } .card-footer { padding:0.9rem 1.4rem; border-top:1px solid var(--border); display:flex; align-items:center; justify-content:space-between; background:rgba(0,0,0,0.15); } .card-name { font-family:'Cormorant Garamond',serif; font-size:1.2rem; font-weight:600; color:var(--text); letter-spacing:0.01em; line-height:1.3; } .card-platform { font-size:0.7rem; color:var(--muted); letter-spacing:0.1em; text-transform:uppercase; } .card-dates { display:flex; flex-direction:column; gap:0.25rem; margin-top:0.5rem; } .card-date-row { display:flex; align-items:center; gap:0.5rem; font-size:0.72rem; color:var(--muted2); } .card-date-row .dot { width:4px; height:4px; border-radius:50%; background:var(--muted); flex-shrink:0; } .card-date-row.event-date { color:var(--gold); opacity:0.85; } .card-date-row.event-date .dot { background:var(--gold); box-shadow:0 0 6px var(--gold); } .card-notes { font-size:0.73rem; color:var(--muted2); font-style:italic; line-height:1.6; padding:0.75rem 1.4rem; border-top:1px dashed rgba(201,168,76,0.12); display:none; } .card:hover .card-notes { display:block; } .card-actions { display:flex; align-items:center; gap:0.4rem; } .status-badge { display:inline-flex; align-items:center; gap:0.4rem; font-size:0.6rem; font-weight:600; letter-spacing:0.15em; text-transform:uppercase; padding:0.3rem 0.75rem; border-radius:20px; border:1px solid; } .status-badge::before { content:''; width:5px; height:5px; border-radius:50%; background:currentColor; box-shadow:0 0 6px currentColor; } .status-waitlisted { background:rgba(201,168,76,0.08); color:#d4aa50; border-color:rgba(201,168,76,0.3); } .status-withdrawn { background:rgba(120,113,108,0.1); color:#92877c; border-color:rgba(120,113,108,0.25); } .status-applied { background:rgba(59,130,246,0.08); color:#6baed6; border-color:rgba(59,130,246,0.25); } .status-accepted { background:rgba(34,197,94,0.08); color:#6fcf97; border-color:rgba(34,197,94,0.25); } .status-rejected { background:rgba(239,68,68,0.08); color:#f87171; border-color:rgba(239,68,68,0.25); } .icon-btn { background:transparent; border:1px solid transparent; border-radius:8px; cursor:pointer; font-size:0.75rem; padding:0.35rem 0.5rem; display:flex; align-items:center; justify-content:center; opacity:0; transition:all 0.2s; } .card:hover .icon-btn { opacity:1; } .edit-btn { color:var(--gold); } .edit-btn:hover { color:var(--gold-light); background:rgba(201,168,76,0.12); border-color:rgba(201,168,76,0.35); } .delete-btn { color:#8b0000; text-shadow:0 0 8px rgba(139,0,0,0.5); } .delete-btn:hover { color:#ff1a1a; background:rgba(139,0,0,0.15); border-color:rgba(139,0,0,0.4); text-shadow:0 0 12px rgba(139,0,0,0.8); } /* EDIT MODAL */ .modal-overlay { position:fixed; inset:0; background:rgba(0,0,0,0.75); backdrop-filter:blur(8px); z-index:500; display:flex; align-items:center; justify-content:center; animation:fadeOverlay 0.25s ease; } @keyframes fadeOverlay { from{opacity:0} to{opacity:1} } .modal { background:#0e1219; border:1px solid var(--border-strong); border-radius:20px; padding:2.5rem; width:min(580px,92vw); box-shadow:0 40px 100px rgba(0,0,0,0.8),0 0 60px rgba(201,168,76,0.06); animation:modalIn 0.35s cubic-bezier(0.16,1,0.3,1); position:relative; overflow:hidden; } .modal::before { content:''; position:absolute; top:0; left:0; right:0; height:2px; background:linear-gradient(90deg,transparent,var(--gold),transparent); } @keyframes modalIn { from{opacity:0;transform:translateY(-24px) scale(0.96)} to{opacity:1;transform:translateY(0) scale(1)} } .modal-title { font-family:'Cormorant Garamond',serif; font-size:1.3rem; letter-spacing:0.18em; text-transform:uppercase; color:var(--gold); margin-bottom:1.75rem; display:flex; align-items:center; gap:1rem; } .modal-title::before,.modal-title::after { content:''; flex:1; height:1px; background:linear-gradient(to right,transparent,var(--border-strong)); } .modal-title::after { background:linear-gradient(to left,transparent,var(--border-strong)); } .modal-close { position:absolute; top:1rem; right:1rem; background:transparent; border:none; color:var(--muted); font-size:1rem; cursor:pointer; padding:0.4rem 0.6rem; border-radius:6px; transition:all 0.2s; } .modal-close:hover { color:#ff1a1a; background:rgba(139,0,0,0.12); } /* EMPTY */ .empty { text-align:center; padding:6rem 2rem; } .empty-seal { font-family:'Cormorant Garamond',serif; font-size:5rem; font-weight:700; color:var(--gold); opacity:0.06; letter-spacing:0.1em; line-height:1; text-transform:uppercase; margin-bottom:1.5rem; } .empty p { font-size:0.78rem; letter-spacing:0.15em; text-transform:uppercase; color:var(--muted); } .empty .ornament { font-size:1.5rem; color:#8b0000; opacity:0.6; display:block; margin:1rem 0; letter-spacing:0.3em; text-shadow:0 0 12px rgba(139,0,0,0.6); } ::-webkit-scrollbar { width:4px; } ::-webkit-scrollbar-track { background:transparent; } ::-webkit-scrollbar-thumb { background:var(--border-strong); border-radius:2px; } @media(max-width:640px){ header{padding:1.25rem 1.5rem;} main{padding:1.5rem 1rem;} #hackList{grid-template-columns:1fr;} .form-grid{grid-template-columns:1fr;} .stats{grid-template-columns:repeat(3,1fr);} }
⚔️
Kathi Corp
Hackathon Intelligence
Private Registry
<span id="totalCount">0</span> Entries
0Total Logged
0Waitlisted
0Withdrawn
✦ Log New Hackathon ✦
New Entry
Hackathon Name *
Platform / Organizer
Application Date
Event Date
Status
Waitlisted
Withdrawn
Applied
Accepted
Rejected
Notes
Dismiss
Record Entry →
All
Waitlisted
Withdrawn
Applied
Accepted
Rejected
✕ Edit Entry Hackathon Name * Platform / Organizer Application Date Event Date Status Waitlisted Withdrawn Applied Accepted Rejected Notes Cancel Save Changes → let data = JSON.parse(localStorage.getItem('kc-hacks') || '[]'); let filter = 'all'; let editId = null; const save = () => localStorage.setItem('kc-hacks', JSON.stringify(data)); function toggleForm() { const f = document.getElementById('addForm'); f.style.display = f.style.display === 'none' ? 'block' : 'none'; if (f.style.display === 'block') document.getElementById('f-name').focus(); } function setFilter(f, btn) { filter = f; document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); render(); } function addEntry() { const name = document.getElementById('f-name').value.trim(); if (!name) { flash('f-name'); return; } data.unshift({ id: Date.now(), name, platform: document.getElementById('f-platform').value.trim(), date: document.getElementById('f-date').value, event: document.getElementById('f-event').value, status: document.getElementById('f-status').value, notes: document.getElementById('f-notes').value.trim() }); save(); ['f-name','f-platform','f-notes'].forEach(id => document.getElementById(id).value = ''); ['f-date','f-event'].forEach(id => document.getElementById(id).value = ''); document.getElementById('f-status').value = 'waitlisted'; toggleForm(); render(); } function openEditModal(id) { const h = data.find(x => x.id === id); if (!h) return; editId = id; document.getElementById('e-name').value = h.name; document.getElementById('e-platform').value = h.platform || ''; document.getElementById('e-date').value = h.date || ''; document.getElementById('e-event').value = h.event || ''; document.getElementById('e-status').value = h.status; document.getElementById('e-notes').value = h.notes || ''; document.getElementById('editModal').style.display = 'flex'; setTimeout(() => document.getElementById('e-name').focus(), 50); } function closeEditModal() { document.getElementById('editModal').style.display = 'none'; editId = null; } function closeModal(e) { if (e.target === document.getElementById('editModal')) closeEditModal(); } function saveEdit() { const name = document.getElementById('e-name').value.trim(); if (!name) { flash('e-name'); return; } const idx = data.findIndex(x => x.id === editId); if (idx === -1) return; data[idx] = { ...data[idx], name, platform: document.getElementById('e-platform').value.trim(), date: document.getElementById('e-date').value, event: document.getElementById('e-event').value, status: document.getElementById('e-status').value, notes: document.getElementById('e-notes').value.trim() }; save(); closeEditModal(); render(); } function del(id) { data = data.filter(h => h.id !== id); save(); render(); } function flash(id) { const el = document.getElementById(id); el.style.borderColor = 'var(--danger)'; el.style.boxShadow = '0 0 0 3px rgba(192,0,10,0.15)'; setTimeout(() => { el.style.borderColor = ''; el.style.boxShadow = ''; }, 1600); } function fmt(d) { if (!d) return null; const [y,m,day] = d.split('-'); return `${['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'][+m-1]} ${+day}, ${y}`; } function esc(s) { return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"'); } function render() { const counts = {}; data.forEach(h => counts[h.status] = (counts[h.status]||0)+1); document.getElementById('s-total').textContent = data.length; document.getElementById('s-waitlisted').textContent = counts.waitlisted || 0; document.getElementById('s-withdrawn').textContent = counts.withdrawn || 0; document.getElementById('totalCount').textContent = data.length; const list = document.getElementById('hackList'); const filtered = filter === 'all' ? data : data.filter(h => h.status === filter); if (data.length === 0) { list.innerHTML = `<div class="empty" style="grid-column:1/-1"> <div class="empty-seal">No Records</div> <span class="ornament">— ✦ —</span> <p>Your registry awaits its first entry</p> </div>`; return; } if (!filtered.length) { list.innerHTML = `<div class="empty" style="grid-column:1/-1"><p style="padding:3rem 0">No entries match this filter</p></div>`; return; } list.innerHTML = filtered.map(h => ` <div class="card"> <div class="card-header"> <div class="card-name">${esc(h.name)}</div> ${h.platform ? `<div class="card-platform">${esc(h.platform)}</div>` : ''} <div class="card-dates"> ${h.date ? `<div class="card-date-row"><span class="dot"></span>Applied: ${fmt(h.date)}</div>` : ''} <div class="card-date-row event-date"> <span class="dot"></span>Event: ${h.event ? fmt(h.event) : '<span style="color:var(--muted);font-style:italic">TBA</span>'} </div> </div> </div> ${h.notes ? `<div class="card-notes">${esc(h.notes)}</div>` : ''} <div class="card-footer"> <span class="status-badge status-${h.status}">${h.status}</span> <div class="card-actions"> <button class="icon-btn edit-btn" onclick="openEditModal(${h.id})" title="Edit">✎</button> <button class="icon-btn delete-btn" onclick="del(${h.id})" title="Remove">✕</button> </div> </div> </div> `).join(''); } document.addEventListener('keydown', e => { if (e.key === 'Escape') closeEditModal(); if (e.key === 'Enter') { if (document.getElementById('addForm').style.display !== 'none' && document.activeElement.id === 'f-name') addEntry(); if (document.getElementById('editModal').style.display !== 'none' && document.activeElement.id === 'e-name') saveEdit(); } }); render();
How I Built It
-
index.html– App structure -
style.css– UI styling -
script.js– Application logic
--Architecture:-
- Hackathons are stored as JavaScript objects.
- Data is saved to localStorage as JSON.
- The UI dynamically renders using DOM manipulation.
- Countdown logic recalculates time remaining on page load.
<!-- Team Submissions: Please pick one member to publish the submission and credit teammates by listing their DEV usernames directly in the body of the post. -->This was a solo project built entirely by me during the weekend challenge.
Top comments (0)