Skip to content

Basics / 02

Quick changes

Step-by-step recipes for the edits most people make first, including colors, fonts, corners, navigation, footer, favicon, and social image.

Browse the docs

Most of what makes a theme yours takes a few lines in two places: src/styles/theme.css for the look and src/config/ for the words and links. Run npm run dev while you edit and the browser updates as you save.

Change the brand color

The brand color is used for primary buttons, links, highlights, and soft tinted backgrounds. It’s five lines in src/styles/theme.css:

@theme {
  --color-brand: oklch(72% 0.14 220);        /* main color */
  --color-brand-hover: oklch(50% 0.14 220);  /* on hover */
  --color-brand-active: oklch(45% 0.13 220); /* when pressed */
  --color-brand-soft: oklch(95% 0.04 220);   /* pale tint */
  --color-brand-fg: oklch(16% 0.02 260);     /* text on brand */
}

Colors are written in OKLCH, which takes three numbers: lightness (0–100%), chroma or intensity (0 is gray, around 0.2 is vivid), and hue (0–360 around the color wheel). The easy way to recolor is to change only the last number in all four brand lines: 25 is red, 145 green, 220 blue, 290 violet. The hover, pressed, and soft versions stay in step automatically.

Prefer hex? Any CSS color works in theme.css, so --color-brand: #e11d48; is fine. Pick your own darker hex for -hover and -active, and a very pale one for -soft. oklch.com converts between the two.

Then check --color-brand-fg. It’s the text color on brand buttons, so use a dark value on a light brand color and a light value (oklch(98% 0.01 0) or #fff) on a dark one.

Change the accent colors

Most themes also use secondary and tertiary colors for badges, highlights, and supporting buttons. They follow the same five-line pattern as the brand color, so recolor them the same way.

Change the background and text colors

@theme {
  /* Surfaces, from the page background to borders */
  --color-bg: oklch(99% 0.002 260);
  --color-surface: oklch(97% 0.004 260);
  --color-elevated: oklch(95% 0.006 260);
  --color-line: oklch(90% 0.008 260);
  --color-line-soft: oklch(93% 0.006 260);

  /* Text, from lightest to darkest */
  --color-muted: oklch(53% 0.02 260);
  --color-soft: oklch(42% 0.025 260);
  --color-text: oklch(28% 0.02 260);
  --color-strong: oklch(16% 0.02 260);
}

For a warmer, cream-colored page, raise the chroma a touch and move the hue to around 80: --color-bg: oklch(98% 0.012 80);. Keep each surface step only slightly darker than the one before so cards and borders still read.

Keep enough contrast between --color-text and --color-bg. If body text gets hard to read on your phone in daylight, darken the text tokens.

Change the fonts

Fonts are installed from Fontsource, so they’re served from your own site. To switch to a different font, such as Inter:

  1. Install it:

    npm install @fontsource-variable/inter
  2. In src/styles/theme.css, replace the font import at the top:

    @import "@fontsource-variable/inter/wght.css";
  3. In src/config/identity.ts, set the font stacks. display is used for headings and sans for everything else:

    fonts: {
      sans: '"Inter Variable", ui-sans-serif, system-ui, sans-serif',
      display: '"Inter Variable", ui-sans-serif, system-ui, sans-serif',
      mono: 'ui-monospace, "SF Mono", Menlo, monospace',
    },
  4. In src/components/global/Seo.astro, point the font preload at the new file so text doesn’t flash on load:

    import fontWoff2 from "@fontsource-variable/inter/files/inter-latin-wght-normal.woff2?url";

    Rename the variable where it’s used further down in the file. The font’s Fontsource page lists the exact file names.

To use a second font for headings only, install both, import both, and give display the other font’s name.

Round or square the corners

Buttons, form fields, and anything using rounded-md share one token in theme.css:

--radius-md: 0.5rem;   /* default */
--radius-md: 0;        /* square */
--radius-md: 999px;    /* pill-shaped buttons */

Set name in src/config/identity.ts. It’s the name in the navbar, browser tabs, search results, and link previews.

The navbar shows the name as text. To use an image logo instead:

  1. Save your logo as an SVG in public/images/, for example public/images/logo.svg.

  2. Open your theme’s navbar in src/blocks/navbar/ and find the home link near the top. It contains {siteConfig.name}.

  3. Replace {siteConfig.name} with the image, keeping the text for screen readers:

    <img src="/images/logo.svg" alt={siteConfig.name} width="120" height="32" />

Set width and height to your logo’s proportions so the page doesn’t shift while it loads.

Edit the navigation

The menu lives under navigation in src/config/identity.ts:

navigation: {
  sticky: true,                 // stays at the top while scrolling
  dropdownTrigger: "hover",     // or "click"
  links: [
    { label: "Work", href: "/#work" },
    { label: "Blog", href: "/blog/" },
    {
      label: "Company",         // a dropdown
      children: [
        { label: "About", href: "/about/" },
        { label: "Contact", href: "/contact/" },
      ],
    },
  ],
  cta: { label: "Book a call", href: "/contact/", size: "md" },
},

Add, remove, or reorder links in the list. A link with children becomes a dropdown. Change the button on the right with cta.

The footer reads from a few places:

What Where
Tagline, copyright line footer.tagline and footer.copyright in identity.ts
Link columns footer.groups in identity.ts. Each group’s label is the column heading
Terms, Privacy, and other small links footer.legal in identity.ts
Email address author.email in identity.ts
Social icons seo.sameAs in src/config/integrations.ts. Add your profile URLs and the matching icons appear

The privacy, terms, and accessibility pages are plain Markdown in src/pages/. Edit the text there.

Change the words on a page

Headings, intros, and button labels for the built-in pages are in src/config/pages.ts. Copy for the theme’s sections (the hero, services, FAQ, and so on) is in src/config/blocks.ts, one entry per section. Change the text there rather than in the page files, so updates to the theme don’t overwrite your edits. See Configuration for the full list.

Replace the favicon

Replace public/favicon.svg with your own icon. If it isn’t an SVG, save it in public/, then set favicon in identity.ts to its path, for example "/favicon.png".

The color of the browser bar on phones is seo.themeColor in src/config/integrations.ts. Set it to your background or brand color as a hex value.

Replace the social image

The social image is the picture that appears when someone shares your link. The build draws it fresh each time from scripts/generate-og.mjs, along with the home-screen icon (apple-touch-icon.png). That means replacing public/og.png by hand won’t last.

  • To keep the generated card, edit the title, subtitle, and colors in scripts/generate-og.mjs.
  • To use your own design, delete the "prebuild" line in package.json, then replace public/og.png (1200 × 630 pixels) and public/apple-touch-icon.png (180 × 180).

To point the whole site at a differently named file, set seo.ogImage in src/config/integrations.ts.

Check your changes

Before you publish, run:

npm run build

If it finishes, the site is ready to publish. It also warns about pages with missing or duplicate descriptions and images without alt text. Then deploy as usual.

If you’d rather describe the change than make it, the theme includes instructions that let an AI coding agent make these edits the same way. See Working with AI agents.