To-Do List Online - Small Study Tools
🌙 Dark
✅ Tasks · Drag & Drop · PNG · PDF
Free To-Do List Online: Minimalist Visual Task Manager Organise your tasks beautifully. Drag to reorder, set priorities and export your list as PNG or PDF. Pro Mode adds categories, sub-tasks, due dates, multiple lists, themes and stats.
● Pro Version is Free for now
Simple
Pro — Power Lists
✓ Categories · Sub-tasks · Due dates · Multiple lists · Themes · Stats · Bulk actions unlocked
No tasks yet
Add your first task to get started
All
Active
Completed
🔴 High
⭐ Starred
⚠️ Overdue
↕ Priority
✓ All done
↩ Uncheck all
🗑 Delete completed
✕ Clear all
✨ Try Sample Data
📋
Your list is empty — add a task above!
0 tasks
Clear completed
Clear all
Choose a theme for your PNG/PDF export
Download PNG
Download PDF
Your list data never leaves your browser — all processing is local.
`;const blob=new Blob([html],{type:'text/html'});
const a=document.createElement('a'); a.download='todo-list.html'; a.href=URL.createObjectURL(blob); a.click();
toast('PDF report downloaded — open and Print → Save as PDF');
}// ─────────────────────────────────────────────────────────────
// CONFETTI
// ─────────────────────────────────────────────────────────────
function confetti(){
const canvas=document.getElementById('confCanvas');
const ctx=canvas.getContext('2d');
canvas.width=window.innerWidth; canvas.height=window.innerHeight;
canvas.style.display='block';
const parts=Array.from({length:80},()=>({
x:Math.random()*canvas.width, y:-20,
vx:(Math.random()-.5)*6, vy:Math.random()*4+2,
r:Math.random()*6+3, a:1,
col:['#ef4444','#f59e0b','#10b981','#3b82f6','#8b5cf6','#f97316'][Math.floor(Math.random()*6)],
rot:Math.random()*360, rSpeed:(Math.random()-.5)*8
}));
let f=0;
(function ani(){
ctx.clearRect(0,0,canvas.width,canvas.height);
let alive=false;
parts.forEach(p=>{
p.x+=p.vx; p.y+=p.vy; p.vy+=.1; p.rot+=p.rSpeed;
if(p.y
/g,'>'); }
function toast(msg){ const t=document.getElementById('toast'); t.textContent=msg; t.classList.add('show'); setTimeout(()=>t.classList.remove('show'),2600); }
function toggleDark(){ isDark=!isDark; document.body.classList.toggle('dark',isDark); document.getElementById('darkBtn').textContent=isDark?'☀️ Light':'🌙 Dark'; try{localStorage.setItem('sst_todo_dark',isDark?'1':'0');}catch(e){} }
function setAppMode(m){
appMode=m;
document.getElementById('btnSimple').classList.toggle('active',m==='simple');
document.getElementById('btnPro').classList.toggle('active',m==='pro');
document.body.classList.toggle('pro-mode',m==='pro');
const pb=document.getElementById('proBar'); if(pb) pb.style.display=m==='pro'?'flex':'none';
try{localStorage.setItem('sst_todo_mode',m);}catch(e){}
buildListTabs(); render();
}// Keyboard
document.addEventListener('keydown',e=>{
if(e.key==='Escape'&&document.activeElement===document.getElementById('taskInput')) document.getElementById('taskInput').blur();
});// ─────────────────────────────────────────────────────────────
// SAMPLE DATA
// ─────────────────────────────────────────────────────────────
function loadSampleData() {
if(tasks.filter(t=>t.list===curList).length && !confirm('Replace current list with sample data?')) return;
tasks = tasks.filter(t=>t.list!==curList); // clear current list only
const today = new Date().toISOString().slice(0,10);
const tomorrow = new Date(Date.now()+86400000).toISOString().slice(0,10);
const yesterday = new Date(Date.now()-86400000).toISOString().slice(0,10);
const samples = [
{text:'Complete assignment draft', prio:'hi', cat:'study', due:today, starred:true, note:'Focus on introduction and methodology sections',
subs:[{text:'Write introduction',done:true},{text:'Literature review',done:false},{text:'Methodology section',done:false}]},
{text:'Review lecture notes', prio:'hi', cat:'study', due:today, starred:false, note:'', subs:[]},
{text:'Submit group project report',prio:'hi', cat:'work', due:tomorrow, starred:false, note:'Check formatting before submitting', subs:[]},
{text:'Buy groceries', prio:'med', cat:'shopping', due:'', starred:false, note:'', subs:[{text:'Milk and bread',done:true},{text:'Fruits & veg',done:false}]},
{text:'30 minute walk', prio:'med', cat:'health', due:today, starred:false, note:'', subs:[]},
{text:'Call dentist for appointment',prio:'lo', cat:'personal', due:tomorrow, starred:false, note:'', subs:[]},
{text:'Read 20 pages of textbook', prio:'med', cat:'study', due:'', starred:false, note:'', subs:[]},
{text:'Pay electricity bill', prio:'hi', cat:'personal', due:yesterday, starred:false, note:'⚠️ Already overdue!', subs:[]},
{text:'Reply to emails', prio:'lo', cat:'work', due:'', starred:false, note:'', subs:[]},
{text:'Plan weekend study schedule',prio:'lo', cat:'study', due:'', starred:false, note:'', subs:[]},
];
// Mark some done
const doneIdx = [1, 3];
samples.forEach((s,i) => {
tasks.push({
id:nextId++, text:s.text, done:doneIdx.includes(i),
prio:s.prio, cat:s.cat, due:s.due, starred:s.starred,
note:s.note, subs:s.subs||[], list:curList,
_noteOpen:false, _subsOpen:false
});
});
save(); buildListTabs(); render();
toast('✨ Sample data loaded!');
}// Start
init();