# Colors & Fonts

## Colors & Fonts

**Files:** `src/styles/theme.css`, `src/config/fonts.json` · **Skill level:** Beginner

A rebrand in Taskly is a few values, not a find-and-replace. Components use color **tokens** (`bg-primary`, `text-dark`, `bg-lime`), and content files pick colors by **name** (`color: "lime"`), so changing a value in `theme.css` updates every page.

### The Pastel Palette
The colors live in the `:root` block at the bottom of `src/styles/theme.css`:

| Variable                 | Default   | Used for                                                     |
| ------------------------ | --------- | ------------------------------------------------------------ |
| `--theme-primary`        | `#9886fe` | Lilac: links, focus rings, the featured plan, the logo tile  |
| `--theme-primary-soft`   | `#efebff` | Light tint of primary behind icons and badges                |
| `--theme-sun`            | `#ffd86f` | Sun: the `fill` button (dark text), sun tags and cards       |
| `--theme-accent`         | `#ffd86f` | Sun again, as the accent role; keep it equal to `--theme-sun` |
| `--theme-dark`           | `#120a0b` | Ink: headings, dark buttons, the dark footers                |
| `--theme-text-default`   | `#454140` | Body text                                                    |
| `--theme-light`          | `#f8f4f1` | Cream (`cream`): cards, the hero background, the `newsletter` footer |
| `--theme-body`           | `#ffffff` | Page background                                              |
| `--theme-gray`, `--theme-gray-line` | `#f2f2f4`, `#dedde3` | Neutral panels and their lines          |
| `--theme-border-light`   | `#ece6e1` | Borders                                                      |
| `--theme-danger`         | `#e5484d` | Error messages                                               |

And the **pastels** that cards, tags, avatars, and the product mockups use. Content files pick them by name; the name maps to a variable, a text color, and a soft tint in `src/lib/pastel.ts`:

| Name     | Variable          | Default   | Text on it | Soft tint           |
| -------- | ----------------- | --------- | ---------- | ------------------- |
| `sun`    | `--theme-sun`     | `#ffd86f` | ink        | `--theme-sun-soft` (`#fff6dc`) |
| `lime`   | `--theme-lime`    | `#c9ff85` | ink        | `--theme-lime-soft` (`#f1ffde`) |
| `sky`    | `--theme-sky`     | `#7ce1ff` | ink        | `--theme-sky-soft` (`#e3f8ff`) |
| `lilac`  | `--theme-primary` | `#9886fe` | white      | `--theme-primary-soft` |
| `orchid` | `--theme-orchid`  | `#d886fe` | white      | `--theme-primary-soft` |
| `mint`   | `--theme-mint`    | `#2bd886` | white      | `--theme-lime-soft` |
| `lemon`  | `--theme-lemon`   | `#feef79` | ink        | `--theme-sun-soft`  |

`white` and `cream` are names too. There is also a paler `--theme-lilac` (`#ccbdf4`, the `bg-lilac` class) that a few components use directly, for example the newsletter card of the `tiles` footer; the content name `lilac` uses `--theme-primary`.

### Pick A Color In Content
Content files never contain color codes. Wherever a file has a `color` field (tags, cards, icon tiles, avatars, calendar marks, plan names), it takes one of these names:

```yaml
tag: { label: "Pricing", color: "lime" } # sun | lime | sky | lilac | orchid | mint | lemon | white | cream
```

Text is white on `lilac`, `orchid`, and `mint` and ink on the others (`pastelText` in `src/lib/pastel.ts`; icons on tiles follow `pastelIcon` in the same file). If you change a pastel a lot, for example make `--theme-lime` dark, change its entry there too so the text stays readable.

### Change The Brand Colors
Taskly has two brand roles: **primary** (lilac) and the **main button** (sun).

```css
:root {
  --theme-primary: #2563eb;      /* links, focus rings, featured plan, logo tile */
  --theme-primary-soft: #eff6ff; /* a very light tint of the same color */
  --theme-sun: #ffd86f;          /* the "fill" button, with dark text */
  --theme-accent: #ffd86f;       /* keep equal to --theme-sun */
}
```

The `fill` button is dark text on `--theme-sun`, so `--theme-sun` must stay light; changing it also changes every `sun` tag and card. White text sits on `primary` (the featured plan with `highlight: true`, the built-in logo tile, `lilac` tags), so check the contrast of your primary with a free checker such as WebAIM's.

To retint the whole palette, change the pastel values too. The names stay the same, so no content file changes.

<Aside type="note" title="One color mode">
  Taskly ships one light palette (`color-scheme: light`) and has no dark mode
  or theme toggle. The `default` and `wordmark` footers, the dark logo band,
  and the dark review cards are dark by design, using `--theme-dark`.
</Aside>

### Shapes, Breakpoints, And Type Scale
The `@theme inline` block at the top of `theme.css` holds the rest of the design tokens:

- **Radii:** `--radius-card` (20px, section cards) and `--radius-panel` (12px, cards inside cards and mockup panels). Buttons and inputs use `rounded-xl`; tags and avatars are round.
- **Breakpoints:** `sm` 540px, `md` 768px, `lg` 1024px, `xl` 1280px.
- **Type scale:** `--text-h1` to `--text-h6` for desktop (60px down to 18px) and `--text-h1-sm` to `--text-h6-sm` for phones, plus heading line heights and letter spacing (`--leading-h1`, `--tracking-h1`…).
- **Easing:** `--ease-out-soft` (menus, header) and `--ease-spring` (the FAQ plus and the pricing switch).

### Fonts
Fonts are listed in `src/config/fonts.json` and load from Google Fonts at build time (self-hosted, no request to Google from your visitors):

| Font                  | `cssVariable`     | Used for                                                     |
| --------------------- | ----------------- | ------------------------------------------------------------ |
| Figtree               | `--font-primary`  | Body text, buttons, forms                                    |
| Bricolage Grotesque   | `--font-heading`  | Headings, the logo text, big numbers                         |
| DM Mono               | `--font-note`     | Annotations and small uppercase labels                       |
| Instrument Serif (italic) | `--font-display` | The highlighted `*word*` pill in hero and page titles     |
| JetBrains Mono        | `--font-code`     | Code blocks                                                  |

To change a font, replace its `name` with any Google Fonts family and keep its `cssVariable`:

```json
{
  "name": "Inter",
  "variants": [
    { "style": "normal", "weight": "400" },
    { "style": "normal", "weight": "600" }
  ],
  "preload": true,
  "display": "swap",
  "cssVariable": "--font-primary",
  "provider": "google",
  "subsets": ["latin"],
  "fallback": "sans-serif"
}
```

List every weight the theme uses (body: 400 to 700; headings: 500 to 700), or the browser fakes the missing ones. `preload: true` is worth it only for the body and heading fonts. The generated Open Graph cards use the `--font-primary` font.

### The Highlighted Word
Wrap a word or two of a hero or page header title in single asterisks and it is set in Instrument Serif italic inside an outlined pill:

```yaml
title: "Run your *team* from one board"
```

Keep it to one short phrase per title, and check the result at phone width: long phrases wrap.

### Do It With AI
```text
Follow the "Rebrand colors / typography" skill in SKILLS.md. Brand color: [HEX]. Fonts: body
[FONT], headings [FONT]. Edit src/styles/theme.css (:root values) and src/config/fonts.json, and
src/lib/pastel.ts only if a pastel changes from light to dark. Keep --theme-sun light (the "fill"
button is dark text on it) and --theme-accent equal to it, check that white text reads on
--theme-primary, and keep the variable names and cssVariable values. List the values you chose.
```