Passion Taste 3–4 hours Code Club · 01 of 02

A Real Page for One Real Person

Real HTML, CSS, JavaScript. Plain text files. By the end of this project, a real web page lives at a real URL on the actual internet — and one person you can name has used it.

A web page is three text files sitting on a server somewhere. HTML is the structure. CSS is the look. JavaScript is the behavior. That's the whole thing.

Most "code for kids" platforms hide this from you behind drag-and-drop blocks. We're not going to. The reason is leverage: the HTML/CSS/JS you write here will run, unchanged, on any computer in the world for the next 10+ years. That's a much better deal than learning a platform-specific block language whose servers might not exist when you're 18.

The rule about Claude

You can use Claude in claude.ai the entire time. You can paste in Claude's HTML wholesale. The rule is: the part that's only you must be visibly only you. The choice of what to build, who it's for, and what to keep — those are yours.

Step by step

  1. Pick a person and a useful, weird thing.

    Not "a website about my dog" — too vague. Pick someone, and something useful for them. "A page for my brother that picks his next book based on the last 5 books he liked." Or "A page for my piano teacher that picks one of her sight-reading drills with a 60-second timer."

    The constraint: this page should not exist on the internet yet, because only you would have built it.

  2. Set up three files in a folder.

    Make a folder on your desktop. Inside it, three files (just open a text editor and Save As):

    my-page/ ├── index.html # the structure ├── style.css # the look └── script.js # the behavior

    Open them in any text editor. VS Code is what most engineers use — it's free, takes 5 minutes to install. Double-click index.html — it opens in your browser. You're shipping in a browser already.

  3. Write the HTML structure.

    HTML is just labels around your content. <h1> for the big title, <p> for paragraphs, <button> for buttons, <input> for things people type into. See the worked example for the full file.

  4. Make it not look like 1996 with CSS.

    The default browser styles are ugly. CSS is the cure. Don't try to learn all of CSS — learn five things and you can build a clean page: color, font, spacing, max-width, hover. That's enough to look intentional. The rest is restraint.

  5. Make it do something with JavaScript.

    JavaScript runs in the browser when the user does something. The pattern is always: find an element → listen for a click → do something → put the result on the page. Once you have this loop, you have all of front-end.

  6. Deploy to a real URL with Netlify Drop.

    Open app.netlify.com/drop in your browser. Drag your folder onto the page. Get a public URL. That's it. No GitHub, no command line, no account needed for the demo. Send the URL to your named person.

    Watch them click around. Note what surprises you.

A complete worked example

"What should Owen read next?" — the page in three files. Tabs are the three real files in the folder. Together they're ~120 lines and run on any browser.

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>What should Owen read next?</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main>
    <h1>Hey Owen.</h1>
    <p class="lead">Pick a vibe. I'll suggest your next book.</p>

    <div class="vibes">
      <button class="vibe" data-vibe="weird-scifi">weird sci-fi</button>
      <button class="vibe" data-vibe="real-history">real history</button>
      <button class="vibe" data-vibe="graphic">graphic novels</button>
    </div>

    <article class="result" id="result">
      <p class="placeholder">Pick a vibe to begin.</p>
    </article>
  </main>
  <script src="script.js"></script>
</body>
</html>
style.css · ~50 lines, considered restraint
/* color & font — the five tools */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
  font-family: 'Georgia', serif;
  background: #FAF4DF;
  color: #1F2230;
  line-height: 1.65;
  padding: 30px 20px;
}
main {
  max-width: 600px;
  margin: 0 auto;
}

/* the big title */
h1 {
  font-size: 2.4rem;
  margin-bottom: 8px;
  letter-spacing: -0.02em;
}
.lead { color: #4D5266; margin-bottom: 30px; }

/* the buttons */
.vibes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 30px;
}
.vibe {
  font: inherit;
  padding: 14px 18px;
  background: #FFFCF0;
  color: #1F2230;
  border: 1px solid rgba(31,34,48,.15);
  border-radius: 12px;
  cursor: pointer;
}
.vibe:hover {
  border-color: #DC5C44;
  background: rgba(220,92,68,.08);
}

/* the result card */
.result {
  background: #FFFCF0;
  border: 1px solid rgba(31,34,48,.12);
  border-radius: 14px;
  padding: 22px;
  min-height: 100px;
}
.placeholder { color: #8A8FA3; font-style: italic; }

/* mobile — single column under 480px */
@media (max-width: 480px) {
  .vibes { grid-template-columns: 1fr; }
}
script.js · ~25 lines, the behavior
// 1. Owen's books — only YOU would have this list
const BOOKS = {
  'weird-scifi': [
    "Annihilation by Jeff VanderMeer",
    "Piranesi by Susanna Clarke",
    "Roadside Picnic by the Strugatsky brothers",
  ],
  'real-history': [
    "The Wager by David Grann",
    "Endurance by Alfred Lansing",
  ],
  'graphic': [
    "Saga, vol. 1 by Brian K. Vaughan",
    "Persepolis by Marjane Satrapi",
  ],
};

// 2. Find the buttons. Listen for clicks.
const buttons = document.querySelectorAll('.vibe');
const result = document.getElementById('result');

buttons.forEach((btn) => {
  btn.addEventListener('click', () => {
    const vibe = btn.dataset.vibe;
    const list = BOOKS[vibe];
    const pick = list[Math.floor(Math.random() * list.length)];
    result.innerHTML = `<p>Try: <strong>${pick}</strong></p>`;
  });
});

Live demo 1: try editing the page right here

Type into any of the three boxes. The preview updates as you type. This is exactly what your text editor + browser look like in real life. Try editing the book list. Try changing the colors. Break it on purpose, then unbreak it.

Live HTML / CSS / JS playground

Live demo 2: does it look right on a phone?

Half the people who'll see your page will see it on a phone. Click each button to see how the page looks at that width. If it doesn't look right at 380px, you skipped step 4.

Phone vs. desktop

What makes this hard

Three things will break for you. The file paths. Your index.html can't find style.css if they're not in the same folder. The JavaScript console. When something doesn't work, open the dev tools (F12) — there's usually a red error message that tells you the exact line. The phone test. Default web pages look terrible on phones unless you set the viewport meta tag and write at least one mobile rule.

The real hard part, though, is restraint. Once you can build, you'll want to add features. Resist. The page is good when one person uses it twice without you reminding them. Until then, it's not done — but adding features won't get you there. Watching them use it will.

Self-check before you ship

  • Three files in a folder. They open in any browser.
  • The page does one thing well, with at least one detail nobody but you would have included.
  • It looks intentional — not 1996, not corporate, just considered.
  • Works on a phone. I tested at 380px width or on my actual phone.
  • Deployed to a public URL I can text to my named person.
  • Named person has used it. I noticed at least one thing they did that I didn't expect.

Try it · once your page is live

A live URL is the floor. Want to push?

  1. Save the user's choice with localStorage. Three lines: localStorage.setItem('lastVibe', vibe), then on page load const last = localStorage.getItem('lastVibe'). Now your friend lands on the page, picks a vibe, leaves, comes back tomorrow — and the vibe is remembered. Real engineering, three lines.
  2. Make it work with the keyboard alone. Try driving your page with only the Tab key and Enter. Notice what's clunky. Add :focus-visible styles for a real focus ring. Now your page works for someone who can't use a mouse — about 5% of all internet users.
  3. Add an "About this page" section. Two paragraphs: who it's for, what it deliberately doesn't do. The "doesn't do" list is what real engineers call scope discipline — naming what's NOT in the project so future-you doesn't add it by accident.