Structure & style the app
Lesson 1 of 4 — the markup and CSS the rest of the course brings to life.
Semantic structure for a small app and how a stylesheet turns bare markup into something you would actually use.
Prerequisites
None. If you can open a file, you can do this lesson.
Step 112 min
Lay down the markup and the look
GoalA static todo layout exists and looks finished — before a line of behaviour.
Good apps are built shape-first. We write the index.html structure (a form, a <ul>, a footer with filter buttons) and a styles.css that makes it calm and dark. Two rows are hard-coded so you can see the design; lesson 2 replaces them with real, JavaScript-driven items.
<!doctype html><html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Todo</title> <link rel="stylesheet" href="styles.css" /> </head> <body> <main class="app"> <h1>Today</h1> <form id="new-todo"> <input id="title" name="title" placeholder="What needs doing?" autocomplete="off" /> <button type="submit">Add</button> </form> <ul id="list" class="list"> <li><span class="check"></span><span class="title">Read the brief</span><button class="remove" aria-label="Delete">×</button></li> <li class="done"><span class="check"></span><span class="title">Open the editor</span><button class="remove" aria-label="Delete">×</button></li> </ul> <footer class="bar"> <span id="count">1 left</span> <span class="filters"> <button data-filter="all" class="active">All</button> <button data-filter="active">Active</button> <button data-filter="done">Done</button> </span> </footer> </main> <script src="app.js"></script> </body></html>* { box-sizing: border-box; }body { margin: 0; min-height: 100vh; display: grid; place-items: start center; padding: 6vh 16px; font-family: system-ui, -apple-system, sans-serif; background: #0b0e14; color: #e7ecf3;}.app { width: 100%; max-width: 460px; }h1 { font-size: 22px; letter-spacing: -0.01em; margin: 0 0 16px; }#new-todo { display: flex; gap: 8px; margin-bottom: 18px; }#title { flex: 1; padding: 11px 14px; border-radius: 10px; border: 1px solid #232a36; background: #11151c; color: inherit; font-size: 15px;}#title:focus { outline: none; border-color: #6ea8fe; }#new-todo button { padding: 0 18px; border-radius: 10px; border: 1px solid #2b3340; background: #6ea8fe; color: #0b0e14; font-weight: 600; cursor: pointer;}.list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }.list li { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 10px; background: #11151c; border: 1px solid #1c2330;}.check { width: 18px; height: 18px; flex: none; border-radius: 999px; border: 1.5px solid #3a4456; cursor: pointer;}.list li.done .check { background: #4ade80; border-color: #4ade80; }.list li.done .title { color: #5b6675; text-decoration: line-through; }.title { flex: 1; }.remove { border: none; background: none; color: #5b6675; font-size: 20px; line-height: 1; cursor: pointer;}.remove:hover { color: #f87171; }.bar { display: flex; justify-content: space-between; align-items: center; margin-top: 16px; font-size: 13px; color: #8b93a3;}.filters { display: flex; gap: 4px; }.filters button { border: 1px solid transparent; background: none; color: inherit; padding: 4px 10px; border-radius: 8px; cursor: pointer;}.filters button.active { border-color: #2b3340; color: #e7ecf3; }// Step 2 brings this page to life.// For now the rows in index.html are hard-coded so you can see the design.Before lesson 2
In Code, change the <h1> from "Today" to your own list name and re-run the preview.
Concepts covered · 1
More like this
Add todos with JavaScript
Wire the form so typing and pressing Add creates a real item. You will hold the todos in an array and render the list from it — the pattern every UI framework formalises later.
Complete & delete
Click a row to toggle it done; click the × to delete it. You will do it with a single listener on the list — event delegation — instead of one per row.
Orchestrate agents without the codebase rotting
Putting it together: context, guardrails, and a verification loop that lets you run coding agents across a real codebase without it drifting into an incoherent pile. This is the senior loop at full speed.
Liked this one?
Pass it on
Discussion
Be the first to ask
Your questions stay private with the team. We can pin answers to share with everyone.
Sign in to ask a question privately on this tutorial.
Sign inNo pinned answers yet for this tutorial.