The brief
You are building a landing page for a study group: a header with navigation, a hero with a big headline and a call to action, a three-card feature grid, a signup form, and a footer. Every tool comes from this course, and each carries its lesson number so you can jump back.
The skeleton (lesson 2-1) with semantic regions (lesson 3-3):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Study Group</title> <link rel="stylesheet" href="styles.css"> </head> <body> <header class="site-header">...the lesson 6-3 navbar...</header> <main> <section class="hero"> <h1>Learn to build the web</h1> <a class="cta" href="#signup">Join us</a> </section> <section class="features">...three articles...</section> <section id="signup">...the form, next lesson...</section> </main> <footer>© Study Group</footer> </body> </html>
Note the viewport meta tag from lesson 7-2. Without it, none of the responsive work below matters on phones.
The stylesheet, section by section
* { box-sizing: border-box; } /* lesson 5-2 */
body {
margin: 0;
font-family: system-ui, sans-serif; /* lesson 4-2 */
line-height: 1.5;
}
.site-header {
display: flex; /* lesson 6-3 */
justify-content: space-between;
align-items: center;
padding: 12px 24px;
}
.hero {
display: flex; /* centering recipe, 6-2 */
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 60vh; /* lesson 5-3 */
text-align: center;
}
.hero h1 {
font-size: clamp(2rem, 5vw, 3.5rem); /* lesson 7-3 */
}
.features {
display: grid; /* lesson 7-1 */
grid-template-columns: 1fr;
gap: 16px;
padding: 24px;
}
@media (min-width: 768px) { /* lesson 7-2 */
.features { grid-template-columns: repeat(3, 1fr); }
}Mobile-first: one column of cards by default, three from 768px up.
Horizontal centering inside a column
In a hero using flex-direction: column, the horizontal centering comes from align-items: center.
In a column the main axis is vertical, so justify-content centers vertically and align-items handles the cross axis, which is now horizontal.
| Property | Axis in a column | Direction |
|---|---|---|
justify-content | main | vertical |
align-items | cross | horizontal |
This is the lesson 6-1 axis swap appearing in real code. Reading flex-direction before either alignment property is what keeps it straight, since the property names never change even though their effects do.
The landing page, assembled
A small responsive page built from the pieces of this course, with a centered hero, a card grid, and one breakpoint.
CSS
* { box-sizing: border-box; }
body {
margin: 0;
font-family: system-ui, sans-serif;
line-height: 1.5;
}
.site-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 24px;
border-bottom: 2px solid #d4af37;
}
.site-nav { display: flex; gap: 16px; }
.hero {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 60vh;
text-align: center;
}
.hero h1 { font-size: clamp(2rem, 5vw, 3.5rem); }
.cta {
background: #d4af37;
color: black;
padding: 10px 24px;
border-radius: 20px;
text-decoration: none;
}
.features {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
padding: 24px;
}
.card { border: 1px solid gray; border-radius: 8px; padding: 16px; }
@media (min-width: 768px) {
.features { grid-template-columns: repeat(3, 1fr); }
}
footer { padding: 16px 24px; border-top: 1px solid gray; }| Section | Technique | Lesson |
|---|---|---|
.site-header | flex with space-between | 6-3 |
.hero | column flex, centered on both axes | 6-2 |
.hero h1 | clamp for fluid type | 7-3 |
.features | grid, one column by default | 7-1 |
| the media query | three columns from 768px | 7-2 |
@media (min-width: 768px) applies its rules only from 768px up, so the narrow layout is the default and the wider one takes over at the breakpoint. That order is what mobile-first means in practice.
The * { box-sizing: border-box; } line at the top is the lesson 5-2 reset, and every padding value below it can then be read as space inside a known width rather than as extra width.
What switches the grid to three columns
Feature cards showing three columns only from 768px up are switched by a media query, written @media (min-width: 768px) { ... }.
| Width | Rule in effect | Columns |
|---|---|---|
| below 768px | the base rule | 1 |
| 768px and up | the query override | 3 |
Below the breakpoint only the base one-column rule applies, and at 768px and up the query's three-column override takes over.
It is the lesson 7-2 tool, and its syntax starts with an @ sign, which marks it as an at-rule rather than an ordinary selector. Because the override must win at equal specificity, the query has to appear after the base rule in the file.