This mini project builds three accessible page templates from one design-system HTML contract: a marketing landing page, a documentation page, and a settings form. Reuse the same shell, alert component, and button patterns from the previous lesson. CSS is minimal – the point is structure you could hand to any theme.
Shared page shell
Start every template with the same skeleton. Save it as shell.html partial or copy the block into each file:
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Page title - Codeskill Design System</title>
<link rel="stylesheet" href="ds.css">
</head>
<body class="ds-page">
<a class="ds-skip-link" href="#main">Skip to content</a>
<header class="ds-header">
<a class="ds-logo" href="/">Codeskill</a>
<nav class="ds-nav" aria-label="Primary">
<ul>
<li><a href="/docs/" aria-current="page">Docs</a></li>
<li><a href="/courses/">Courses</a></li>
</ul>
</nav>
</header>
<main id="main" class="ds-main">
<!-- page content -->
</main>
<footer class="ds-footer">
<p>© 2026 Codeskill</p>
</footer>
</body>
</html>
Template 1: landing page
Inside <main>, use a hero section, feature grid, and call to action. One <h1>, logical heading levels, real links:
<section class="ds-hero" aria-labelledby="hero-title">
<h1 id="hero-title">Learn HTML properly</h1>
<p class="ds-lead">Structured tutorials from beginner to advanced.</p>
<a class="ds-button ds-button--primary" href="/html/">Start with HTML</a>
</section>
<section class="ds-features" aria-labelledby="features-title">
<h2 id="features-title">What you get</h2>
<ul class="ds-feature-list">
<li class="ds-feature">
<h3>Clear structure</h3>
<p>Lessons that build on each other.</p>
</li>
<li class="ds-feature">
<h3>Real markup</h3>
<p>Patterns you can use in production.</p>
</li>
</ul>
</section>
Template 2: documentation page
Docs need in-page navigation, breadcrumbs, and an article region:
<nav class="ds-breadcrumb" aria-label="Breadcrumb">
<ol>
<li><a href="/docs/">Docs</a></li>
<li><a href="/docs/html/">HTML</a></li>
<li aria-current="page">Design system templates</li>
</ol>
</nav>
<div class="ds-docs-layout">
<nav class="ds-sidebar" aria-label="On this page">
<ul>
<li><a href="#shell">Shared shell</a></li>
<li><a href="#landing">Landing template</a></li>
<li><a href="#settings">Settings form</a></li>
</ul>
</nav>
<article class="ds-article">
<h1>Design system page templates</h1>
<section id="shell">
<h2>Shared shell</h2>
<p>Every page uses the same landmarks and skip link.</p>
</section>
<!-- more sections -->
</article>
</div>
Template 3: settings form
Forms use fieldsets, labels, describedby hints, and an alert region for errors:
<h1>Account settings</h1>
<div class="ds-alert ds-alert--info" role="status">
<p>Changes apply after you save.</p>
</div>
<form class="ds-form" action="/settings" method="post" novalidate>
<fieldset class="ds-fieldset">
<legend>Profile</legend>
<div class="ds-field">
<label for="display-name">Display name</label>
<input type="text" id="display-name" name="display_name"
autocomplete="name" required
aria-describedby="display-name-hint">
<p id="display-name-hint" class="ds-hint">Shown on your public profile.</p>
</div>
<div class="ds-field">
<label for="email">Email</label>
<input type="email" id="email" name="email"
autocomplete="email" required>
</div>
</fieldset>
<fieldset class="ds-fieldset">
<legend>Notifications</legend>
<label class="ds-choice">
<input type="checkbox" name="notify_course" value="1">
<span>Email me when new courses publish</span>
</label>
</fieldset>
<div class="ds-form-actions">
<button type="submit" class="ds-button ds-button--primary">Save changes</button>
<a class="ds-button ds-button--secondary" href="/account/">Cancel</a>
</div>
</form>
Checklist before you ship
- Validate HTML (validator.w3.org or equivalent)
- One
<h1>per template; heading levels do not skip - Keyboard through nav, form, and any interactive components
- Run Lighthouse accessibility on each template
- Compare all three side by side – shell and component class names match
Stretch goals
Add a dismissible alert with a native <dialog> for destructive actions. Convert ds-button to a custom element with declarative shadow DOM. Document each template in a short README listing required classes and landmarks. That README is part of the design system contract – the next developer should not have to guess.

