Step 1: Set up the project
Time to build. Make sure you're in ~/dev — that's the workspace root you set up earlier. Start Claude Code:
cd ~/dev
claude
Paste this prompt:
Set up my project:
1. Create ~/dev/web-dev/p1
2. Download the project materials from https://learnbydirectingai.dev/materials/webdev/p1/materials.zip and extract them into that folder
3. Read CLAUDE.md — it's the project governance file
4. Open VS Code in ~/dev/web-dev/p1 and install the Claude Code and Live Server extensions if not already installed
If anything needs admin access, tell me what to run in a separate terminal.
One prompt — everything the project needs is in there. Claude creates the folder, downloads and extracts the materials, reads the governance file, opens VS Code, and installs the extensions. If something needs admin access, Claude will tell you what to run in a separate terminal. Wait for it to finish before moving on.
That prompt works because it points Claude at a file that already contains the full project context — the client, the tech stack, the tickets, the verification targets. Without CLAUDE.md, you'd need to paste all of that into every prompt. With it, Claude knows what it's building and why.
Step 2: Switch to VS Code
Open VS Code. You should see the project folder in the file tree on the left — prd.md, mockup-description.md, CLAUDE.md, the photos/ directory with Yasmine's product images.
Open the Claude Code extension in the sidebar. Click the spark icon in the activity bar on the far left. The Claude Code panel opens on the right side of the window. This is your workspace for the rest of the project: file tree on the left, editor in the center, Claude on the right.
Claude reads CLAUDE.md automatically when it starts in a project directory. Look at the Claude Code panel — it should acknowledge the project context: Yasmine's portfolio site, the ticket structure, the tech stack, the verification targets.
This is the difference between the "first look" demo in P0 and real project work. In the demo, Claude had one prompt and nothing else. Here, Claude has the full project governance file. It knows the client, the color palette, the semantic HTML requirements, the ticket breakdown. Every directive you give from here builds on that context.
Step 3: Run T0 — Project setup
In the Claude Code sidebar, type:
Run T0.
That's it. Claude has CLAUDE.md — it knows what T0 means. T0 initializes Git, creates the GitHub repo, generates backlog.md from the ticket list, creates GitHub issues for T1 through T7, sets up a project board, and copies the product photos into images/ as web-optimized versions.
This is ticket-driven workflow. You direct by ticket ID, not by describing every detail of what to build. The governance file carries the context.
Watch Claude work. It will run a sequence of commands — git init, GitHub CLI calls, file operations. When it finishes, check the acceptance criteria:
- The GitHub repo exists (Claude will share the URL)
backlog.mdis in the project root with all tickets listed- GitHub issues exist for T1 through T7
- The project board is populated
Open the project board link. All the tickets are laid out — T1 through T7 in the "To Do" column. This is the shape of the work ahead. Eight specific tickets, each one moving the site forward.
Check the images/ directory in the file tree. The product photos should be there — web-optimized versions of Yasmine's leather goods, ready for the gallery.
Step 4: Run T1 — Site structure
Run T1.
Claude builds the HTML skeleton: index.html, about.html, contact.html. Shared navigation linking all three pages. Semantic HTML throughout — <nav>, <main>, <section>, <footer>.
When Claude finishes, check the output. Right-click index.html in the file tree and select "Open with Live Server." The page opens in your browser. Live Server watches for file changes and reloads automatically — you'll see updates as Claude builds.
Click through the navigation. All three pages should load. The links should work between them. There's no styling yet — just raw HTML structure. That's expected. The structure comes first. T2 adds the visual layer.
Look at the HTML source. You should see semantic elements — <nav> for navigation, <main> for content, <section> for distinct content blocks, <footer> at the bottom. These aren't interchangeable containers. A <nav> tells screen readers "this is navigation." A <section> creates a document landmark that assistive technology can announce and jump to. A <div> does neither. AI sometimes defaults to <div> for everything — check that Claude used the right elements.
Step 5: Run T2 — Responsive CSS
Run T2.
CSS (Cascading Style Sheets) is the language that controls how HTML looks -- colors, layout, spacing, typography. It lives in a separate file from the HTML structure. Claude writes css/styles.css -- mobile-first, starting at 375px. The color palette from mockup-description.md: cream background (#FDF5E6), saddle brown headings (#8B4513), warm sand section backgrounds (#D2B48C), burgundy accents (#6B1C23), dark brown text (#3E2723). Google Fonts loaded for typography. A media query is a CSS rule that applies different styles based on the screen size, so the same page can look right on a phone and on a desktop. Media queries expand the layout at 768px and 1280px.
Refresh the browser. The page should transform — Yasmine's color palette applied, typography loaded, layout structured.
Before moving to the next ticket, open the site in your browser and resize the window from phone to desktop width. Watch how the layout shifts at each breakpoint. That is the CSS you just directed Claude to write.
Now resize. Drag the browser window narrow, down to phone width. The layout should adapt. No horizontal scrollbar. Text stays readable. Navigation adjusts. Drag it wide again — the layout expands to use the space. Try the three key widths: 375px (phone), 768px (tablet), 1280px (desktop). AI can generate CSS that looks correct at one width and breaks at another. Checking all three is your responsibility.
Step 6: Run T3 — Portfolio gallery
Run T3.
Claude builds the gallery on index.html — a responsive grid of Yasmine's leather goods. Each photo in a <figure> element with a <figcaption> describing the piece. The images from photos/ — the structured saddle bag, the cognac wallet, the embossed folio, the crossbody in burgundy. Six to eight pieces displayed at large size, minimum 600px wide on desktop, full width on mobile.
This is the first time you see the directed work rendered as a real page. Yasmine's craftsmanship displayed the way it deserves — large, with texture visible, with captions that describe each piece. The saddle-stitching, the brass hardware, the grain of the vegetable-tanned leather. The site frames the work; it doesn't compete with it.
Check the alt text. Open the HTML source and look at each <img> tag. Every image should have a descriptive alt attribute — not "image" or "photo" or "leather bag," but something that describes the specific piece. AI commonly generates generic or missing alt text. Screen readers read these descriptions aloud. A gallery owner in Paris using assistive technology should hear what each piece is.
Now resize to 375px. The three-column grid should collapse to a single column. Images go full width. Captions stay beneath their photos. No cropping, no distortion, no horizontal scroll.
While you're checking, glance at the HTML source for any external resources — font imports, CDN links, image sources. AI sometimes generates these with http:// instead of https://. On a deployed HTTPS site, mixed HTTP content gets blocked by the browser. Flag anything that's not HTTPS.
Step 7: Run T4 — Process page
Run T4.
Claude writes the process page — about.html. Yasmine's story: vegetable tanning and why she refuses chrome tanning, the hand-stitching technique and traditional tools, her grandmother's influence. Inline workshop images breaking up the text. The tone should read like a craftsperson describing her own work, not marketing copy.
Check the heading hierarchy in the source. The main heading should be <h2> (under the page's <h1> which is the site name), subsections <h3>, and no levels skipped. AI frequently jumps from <h1> to <h3> or uses headings for visual sizing instead of document structure. A broken heading hierarchy fails html-validate and confuses screen readers that use headings to navigate.
Read the content. Does it sound like Yasmine talking about her craft, or does it sound like a brochure? The difference matters. Yasmine has opinions — she refuses chrome tanning because it produces uniform, lifeless leather. Her grandmother taught her to read the grain. The process page should carry that voice.
Step 8: Run T5 — Contact form
Run T5.
Claude builds the contact form on contact.html. Three fields: Name (text input), Email (email input), Message (textarea). Each field with an associated <label> element. The form has the netlify attribute. Normally, when someone submits a form on a website, the data has to go to a separate program (a backend server) that processes it. Static sites don't have one, so Netlify provides form handling as a service -- the netlify attribute on the form is what connects it. Submit button styled with the burgundy accent (#6B1C23).
Check the form. Every field should have a visible label, not just a placeholder. Labels matter for accessibility -- screen readers announce them, and clicking a label focuses the associated input. Without that netlify attribute, submissions go nowhere.
Step 9: Check the build
The site is built. A commit is a saved snapshot of your code at a specific point -- like a checkpoint you can return to. Each ticket gets its own commit so you can see exactly what changed and when. Six tickets, six commits. Open the Git history -- each commit should reference a ticket ID. T0: Project setup. T1: Site structure. T2: Responsive CSS. This is the first form of professional communication: describing what was built and why, one ticket at a time.
Now verify the whole thing. Open index.html in the browser with Live Server.
✓ Check: Visit index.html in the browser. All three pages load. Navigation works between them. Gallery shows Yasmine's leather goods at large size. Process page tells her story. Contact form has three labeled fields. Resize the browser to 375px width — layout adapts, no horizontal scrolling, images scale.