Code

style.css — the form and a media query

Now style the form and add the one media query that tunes the page for phones. A block of form rules and a responsive block join style.css; everything above stays as it was.

Styling every field at once

input:not([type="checkbox"]):not([type="radio"]),
select,
textarea {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  padding: 0.65rem 1rem;
  font: inherit;
  width: 100%;
}

Look at that selector. It styles every input except checkboxes and radios (which need their own look), plus selects and textareas — so your text field, email field, dropdown and message box all match from one rule. The reason it's written with :not() rather than listing input[type="text"], input[type="email"], … is a real trap: an exact list like input[type="text"] does not match type="email", so the day you add an email field it silently comes out unstyled. :not(checkbox):not(radio) covers every type there is, and every type there ever will be.

font: inherit matters more than it looks: form controls don't inherit the page font by default, so without it your inputs would fall back to the browser's dated default. And the focus ring you wrote back in the links lesson already covers these fields — it named input, select and textarea then, for exactly this moment.

The form's shape

The rest is layout: .form-card is the bordered panel with a max-width so lines don't run too long to read; .field spaces each label-and-input pair; .form-actions right-aligns the button above a divider; .required paints the * in the danger colour; .hint sets the small print under the message box. Nothing exotic — the interesting decision was the :not() selector; the rest is spacing and colour from tokens you already have.

One media query, fine-tuning the edges

@media (max-width: 640px) {
  main { padding: 1.5rem 1rem 3rem; }
  .grid { grid-template-columns: 1fr; }
  .navbar { flex-wrap: wrap; gap: 0.75rem; padding: 0.85rem 1rem; }
  .nav-links { order: 3; width: 100%; overflow-x: auto; }
  .nav-link { font-size: 0.875rem; padding: 0.4rem 0.75rem; }
  .form-card { padding: 1.25rem; }
  .form-actions { flex-direction: column-reverse; }
  .form-actions .btn { width: 100%; }
}

Every rule here is a nudge, not a rebuild:

  • .grid { grid-template-columns: 1fr } — the gallery already collapses toward one column on its own, but at exactly 640px auto-fill might still squeeze in two cramped columns. This forces a clean single column on a phone. It's the perfect example of the division: auto-fill does the responsive work, the media query trims one awkward edge.
  • The navbar wraps and lets its links become a full-width, scrollable row instead of overflowing.
  • The form loses some padding, and its action button goes full-width — a comfortable tap target on a phone.

Resize the window past 640px and watch it all switch at once. Below that line, the page is a phone layout; above it, a desktop one. That single breakpoint, on top of a gallery that was already responsive, is all this page needs.