Code

style.css — reset, variables, theme

Now create style.css next to index.html. The code column has the whole file; we'll walk it top to bottom.

What is inherited, and what isn't

body { font-family: system-ui; color: #e6e8f0; line-height: 1.5; }

Text properties — font, colour, line height — are inherited by children. That's why one rule on body styles the whole page. Box properties — margin, padding, border — are not. That asymmetry is deliberate, and it's why stylesheets start with a few rules on body.

The three lines at the top of every real stylesheet

* { box-sizing: border-box; margin: 0; padding: 0; }

border-box means width includes padding and border, so a 300px box is 300px wide — which is what everyone expects, and not the default. margin: 0; padding: 0; removes the browser's own default spacing so you start from a known state rather than fighting invisible gaps.

Where does the space between two paragraphs come from, if you set no margin? Think. — From the browser's default stylesheet. Every browser has one, they differ slightly, and that's what this reset is for.

Custom properties: dark and light theme almost for free

At the top of the file is a block of colours. These are CSS variables (custom properties):

:root,
[data-theme="dark"] {
  --bg: #0b0e1a;
  --surface: #141a2e;
  --text: #e6e8f0;
  --accent: #6f8dff;
  /* …and a few more */
}
[data-theme="light"] { --bg: #f6f7fb; --text: #1b1f2e; /* … */ }

body { background: var(--bg); color: var(--text); }

Now change one attribute on <html> in the dev tools — data-theme="light" — and watch the whole page change. No JavaScript, no second stylesheet, no duplicated rules.

Name the role, not the colour. --bg and --surface, not --dark-blue. A variable named after its colour is a lie the moment you add a light theme. Name what it's for and the second theme costs you nothing.

This is why you avoid hardcoded colours. Every colour written directly into a rule is a place the theme won't reach. Later, a theme toggle in the next track — the client-side one — is three lines of JavaScript that flip that one attribute; but only if you were disciplined here.