Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 41 additions & 35 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,57 +11,63 @@ pnpm build && pnpm smoke
## Themes

A theme is a directory under `packages/jaamd/src/themes/<slug>/` plus one entry in
`packages/jaamd/src/themes/index.ts`. Themes are welcome as pull requests.

### 1. Write `index.css`

A `:root` block of `--jaamd-*` declarations. A theme with both a light and a dark
palette adds a second block on `html.dark` and repeats the seeds there; otherwise
one mode borrows the other's background. These **seeds are required**:

| Token | What it is |
|---|---|
| `--jaamd-bg` | Page background the palette assumes |
| `--jaamd-color-fg` | Body text |
| `--jaamd-color-fg-bright` | Headings, strong, table headers |
| `--jaamd-color-primary` | Links and accents |
| `--jaamd-alert-*-color` | The five alert hues: note, tip, important, warning, caution |
`packages/jaamd/src/themes/index.js`. Themes are welcome as pull requests.

The CSS is generated. You write a palette; `pnpm build:themes` writes `index.css`
and, for a single-palette theme, `dark.css`. Never edit those by hand.

### 1. Write `palette.js`

Fourteen colours per palette. A `dual` theme fills both `light` and `dark`, the
others leave one `null`.

```js
export default {
light: null,
dark: {
recessed: "#21222c", // below the background: code-tab header
base: "#282a36", // the background itself
surface: "#44475a", // raised: inline code, table rows, spoilers
overlay: "#6272a4", // borders and rules
text: "#f8f8f2",
bright: "#ffffff", // headings, strong

primary: "#bd93f9",
primaryLight: "#ff79c6",
accent: "#8be9fd", // emphasis

alert: { note: "#8be9fd", tip: "#50fa7b", important: "#bd93f9",
warning: "#f1fa8c", caution: "#ff5555" },
},
};
```

Everything else (surfaces, borders, the table-of-contents card, alert backgrounds)
is derived from those by `src/styles/variables.css`: a nine-colour theme is
complete. Omit `--jaamd-bg` and the derived tokens mix against the *default*
background instead of yours.
Most palettes document these levels already: Catppuccin has `mantle/base/surface0/
overlay0/text`, Gruvbox the `bg0_h/bg0/bg1/bg2`, Rosé Pine `base/surface/muted`,
Tokyo Night `bg_dark/bg/bg_highlight/comment`.

Beyond the seeds, override any concrete token an editor scheme defines by hand
rather than by formula: `--jaamd-code-bg`, `--jaamd-pre-bg` and friends. See an
existing theme for the full list.
Where a palette wants a token off the recipe, add it under `overrides`:

Do not restate the font tokens: they are the defaults already.
```js
overrides: { "blockquote-fg": "#6272a4" },
```

### 2. Declare it

Add an entry to `src/themes/index.ts` with the directory name as `slug` and a
Add an entry to `src/themes/index.js` with the directory name as `slug` and a
readable `name`, plus:

| `mode` | The palette is | `shiki` |
|---|---|---|
| `"light"` / `"dark"` | one palette, applying in both modes | one theme name |
| `"dual"` | two palettes, `:root` and `html.dark` | `{ light, dark }` |

### 3. Generate the dark variant
### 3. Generate and check

```bash
pnpm build:themes
```

`dark.css` is `index.css` under `html.dark`: the variant for using a single-palette
theme only in dark mode. It is generated and committed; never edit it by hand. A
`dual` theme covers dark mode itself and gets no `dark.css`.

### 4. Check it

```bash
pnpm test:themes
```

It names the missing seed, an unknown Shiki theme, or a stale `dark.css`.
The test names the missing level, an unknown Shiki theme, a token no other theme
lacks, or CSS that no longer matches its palette.
4 changes: 3 additions & 1 deletion packages/jaamd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,9 @@ import { themes } from "@lancher-dev/jaamd/themes";
// [{ slug: "dracula", name: "Dracula", mode: "dark", shiki: "dracula" }, …]
```

To customise one, copy a directory from `src/themes/`. To add one, see
Each preset is generated from a `palette.js` of fourteen colours, so every theme
declares the same token set. The `.css` files are build output: to customise a
preset, copy its directory and edit the palette. To add one, see
[CONTRIBUTING.md](../../CONTRIBUTING.md#themes).

### Dual-theme Shiki
Expand Down
3 changes: 1 addition & 2 deletions packages/jaamd/src/styles/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
/* ── Blockquote ─────────────────────────────────────────── */

--jaamd-blockquote-bg: var(--jaamd-surface-1);
--jaamd-blockquote-border: color-mix(in oklab, var(--jaamd-color-fg) 81%, var(--jaamd-bg));
--jaamd-blockquote-border: var(--jaamd-border-strong);
--jaamd-blockquote-fg: var(--jaamd-color-primary-light);


Expand Down Expand Up @@ -184,7 +184,6 @@ html.dark {
--jaamd-border-strong: color-mix(in oklab, var(--jaamd-color-fg) 36%, var(--jaamd-bg));

--jaamd-table-border: var(--jaamd-border);
--jaamd-blockquote-border: var(--jaamd-border-strong);
--jaamd-copy-btn-hover-border: var(--jaamd-border-strong);

--jaamd-alert-note-color: #58a6ff;
Expand Down
140 changes: 115 additions & 25 deletions packages/jaamd/src/themes/catppuccin/index.css
Original file line number Diff line number Diff line change
@@ -1,31 +1,121 @@
/* JAAMD theme: Catppuccin. Latte in light, Mocha in dark. */
/* JAAMD theme: Catppuccin. Pairs with Shiki theme "catppuccin-latte" and "catppuccin-mocha". */

:root {
--jaamd-bg: #eff1f5;
--jaamd-color-fg: #4c4f69;
--jaamd-color-fg-bright: #4c4f69;
--jaamd-color-primary: #1e66f5;
--jaamd-color-success: #40a02b;
--jaamd-alert-note-color: #1e66f5;
--jaamd-alert-tip-color: #40a02b;
--jaamd-alert-important-color: #1e66f5;
--jaamd-alert-warning-color: #df8e1d;
--jaamd-alert-caution-color: #d20f39;

--jaamd-em-fg: #8839ef;
--jaamd-bg: #eff1f5;
--jaamd-color-fg: #4c4f69;
--jaamd-color-fg-bright: #4c4f69;
--jaamd-color-primary: #1e66f5;
--jaamd-color-primary-light: #7287fd;
--jaamd-color-success: #40a02b;

--jaamd-heading-border-color: rgba(30, 102, 245, 0.3);

--jaamd-code-bg: #ccd0da;
--jaamd-code-border: #9ca0b0;
--jaamd-code-fg: #4c4f69;

--jaamd-pre-bg: #eff1f5;
--jaamd-pre-border: #ccd0da;
--jaamd-pre-fg: #4c4f69;

--jaamd-copy-btn-bg: #ccd0da;
--jaamd-copy-btn-border: #9ca0b0;
--jaamd-copy-btn-fg: #4c4f69;
--jaamd-copy-btn-hover-bg: #9ca0b0;
--jaamd-copy-btn-hover-border:#1e66f5;
--jaamd-copy-btn-hover-fg: #4c4f69;

--jaamd-blockquote-bg: #eff1f5;
--jaamd-blockquote-border: #9ca0b0;
--jaamd-blockquote-fg: #7287fd;

--jaamd-em-fg: #8839ef;
--jaamd-hr-color: rgba(30, 102, 245, 0.3);

--jaamd-table-border: #ccd0da;
--jaamd-table-header-bg: #eff1f5;
--jaamd-table-hover-bg: #ccd0da;

--jaamd-tabs-border: #ccd0da;
--jaamd-tabs-header-bg: #e6e9ef;
--jaamd-tabs-btn-hover-bg: #ccd0da;
--jaamd-tabs-btn-active-bg: #eff1f5;

--jaamd-details-bg: #eff1f5;
--jaamd-details-border: #ccd0da;

--jaamd-spoiler-hidden-color: #4c4f69;
--jaamd-spoiler-revealed-bg: #ccd0da;
--jaamd-spoiler-revealed-fg: #4c4f69;

--jaamd-alert-note-color: #1e66f5;
--jaamd-alert-note-bg: rgba(30, 102, 245, 0.1);
--jaamd-alert-tip-color: #40a02b;
--jaamd-alert-tip-bg: rgba(64, 160, 43, 0.1);
--jaamd-alert-important-color:#8839ef;
--jaamd-alert-important-bg: rgba(136, 57, 239, 0.1);
--jaamd-alert-warning-color: #df8e1d;
--jaamd-alert-warning-bg: rgba(223, 142, 29, 0.1);
--jaamd-alert-caution-color: #d20f39;
--jaamd-alert-caution-bg: rgba(210, 15, 57, 0.1);
}

html.dark {
--jaamd-bg: #1e1e2e;
--jaamd-color-fg: #cdd6f4;
--jaamd-color-fg-bright: #cdd6f4;
--jaamd-color-primary: #89b4fa;
--jaamd-color-success: #a6e3a1;
--jaamd-alert-note-color: #89b4fa;
--jaamd-alert-tip-color: #a6e3a1;
--jaamd-alert-important-color: #89b4fa;
--jaamd-alert-warning-color: #f9e2af;
--jaamd-alert-caution-color: #f38ba8;

--jaamd-em-fg: #cba6f7;
--jaamd-bg: #1e1e2e;
--jaamd-color-fg: #cdd6f4;
--jaamd-color-fg-bright: #cdd6f4;
--jaamd-color-primary: #89b4fa;
--jaamd-color-primary-light: #b4befe;
--jaamd-color-success: #a6e3a1;

--jaamd-heading-border-color: rgba(137, 180, 250, 0.3);

--jaamd-code-bg: #313244;
--jaamd-code-border: #6c7086;
--jaamd-code-fg: #cdd6f4;

--jaamd-pre-bg: #1e1e2e;
--jaamd-pre-border: #313244;
--jaamd-pre-fg: #cdd6f4;

--jaamd-copy-btn-bg: #313244;
--jaamd-copy-btn-border: #6c7086;
--jaamd-copy-btn-fg: #cdd6f4;
--jaamd-copy-btn-hover-bg: #6c7086;
--jaamd-copy-btn-hover-border:#89b4fa;
--jaamd-copy-btn-hover-fg: #cdd6f4;

--jaamd-blockquote-bg: #1e1e2e;
--jaamd-blockquote-border: #6c7086;
--jaamd-blockquote-fg: #b4befe;

--jaamd-em-fg: #cba6f7;
--jaamd-hr-color: rgba(137, 180, 250, 0.3);

--jaamd-table-border: #313244;
--jaamd-table-header-bg: #1e1e2e;
--jaamd-table-hover-bg: #313244;

--jaamd-tabs-border: #313244;
--jaamd-tabs-header-bg: #181825;
--jaamd-tabs-btn-hover-bg: #313244;
--jaamd-tabs-btn-active-bg: #1e1e2e;

--jaamd-details-bg: #1e1e2e;
--jaamd-details-border: #313244;

--jaamd-spoiler-hidden-color: #cdd6f4;
--jaamd-spoiler-revealed-bg: #313244;
--jaamd-spoiler-revealed-fg: #cdd6f4;

--jaamd-alert-note-color: #89b4fa;
--jaamd-alert-note-bg: rgba(137, 180, 250, 0.1);
--jaamd-alert-tip-color: #a6e3a1;
--jaamd-alert-tip-bg: rgba(166, 227, 161, 0.1);
--jaamd-alert-important-color:#cba6f7;
--jaamd-alert-important-bg: rgba(203, 166, 247, 0.1);
--jaamd-alert-warning-color: #f9e2af;
--jaamd-alert-warning-bg: rgba(249, 226, 175, 0.1);
--jaamd-alert-caution-color: #f38ba8;
--jaamd-alert-caution-bg: rgba(243, 139, 168, 0.1);
}
45 changes: 45 additions & 0 deletions packages/jaamd/src/themes/catppuccin/palette.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export default {
// Latte
light: {
recessed: "#e6e9ef",
base: "#eff1f5",
surface: "#ccd0da",
overlay: "#9ca0b0",
text: "#4c4f69",
bright: "#4c4f69",

primary: "#1e66f5",
primaryLight: "#7287fd",
accent: "#8839ef",

alert: {
note: "#1e66f5",
tip: "#40a02b",
important: "#8839ef",
warning: "#df8e1d",
caution: "#d20f39",
},
},

// Mocha
dark: {
recessed: "#181825",
base: "#1e1e2e",
surface: "#313244",
overlay: "#6c7086",
text: "#cdd6f4",
bright: "#cdd6f4",

primary: "#89b4fa",
primaryLight: "#b4befe",
accent: "#cba6f7",

alert: {
note: "#89b4fa",
tip: "#a6e3a1",
important: "#cba6f7",
warning: "#f9e2af",
caution: "#f38ba8",
},
},
};
Loading
Loading