Code

style.css — style the structure

The markup is right; now style it. This step adds rules to style.css — the tokens, reset and body from last lesson stay exactly as they were, and everything below them is new. We'll walk the parts that teach something.

Framing the page

main {
  max-width: 1200px;
  margin: 0 auto;
  padding: 2rem 1.5rem 4rem;
}

max-width stops the content stretching to absurd widths on a large monitor; margin: 0 auto centres it. This one rule is why the whole page sits in a comfortable column instead of running edge to edge.

The navbar and hero

The .navbar is a flex row (display: flex) that sticks to the top as you scroll (position: sticky; top: 0). The .nav-link.active rule is what paints the current page's pill — and it's declared after .nav-link:hover, so on the active link the "you are here" style still wins when your pointer is over it. The hero borrows just two rules — .hero-text h1 for the big title and .hero-sub for the muted intro line.

The cards, and one positioning trick

Why does the ♡ sit neatly in the corner of each picture instead of pushing the layout around? Look at two rules together:

.card-header { position: relative; }

.fav-btn {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  /* … */
}

position: absolute takes the button out of the normal flow and pins it by coordinates — but relative to what? — to the nearest ancestor that is itself positioned. That's why .card-header is position: relative: it becomes the anchor, so the button sits 0.75rem from the top-right of its own picture, not of the whole page. Remove position: relative from the header and every ♡ jumps to the corner of the viewport. This pairing — a relative parent holding an absolute child — is one of the most reused patterns in CSS.

The image rule is small but does real work:

.picture-card img { width: 100%; height: 200px; object-fit: cover; display: block; }

The three source pictures have wildly different shapes, yet every card is the same height. height: 200px fixes the box; object-fit: cover fills it without squashing the image, cropping the overflow instead. You'll meet object-fit properly in the client-side track.

.skip-link { position: absolute; top: -100px; /* … */ }
.skip-link:focus { top: 0; }

That's the whole trick to "invisible until focused": the link is parked 100px above the top edge, out of sight. When a keyboard user tabs to it, :focus matches and it slides down to top: 0. No JavaScript — the browser's focus handling does all of it.

One thing you may notice: the three cards are stacked in a single column, not spread across the page. That's expected. The <div class="grid"> around them has no rule yet — arranging cards into a responsive grid is its own lesson, and the class is already there waiting for it. For now, a styled stack is a perfectly honest halfway point.