Skip to content

Commit 4417414

Browse files
committed
add tweaks and refractor
1 parent 999f224 commit 4417414

31 files changed

Lines changed: 365 additions & 55 deletions

.github/pull_request_template.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
## Summary
22

3-
<!-- Briefly describe new themes or changes. -->
3+
<!-- Briefly describe new themes, tweaks, or other changes. -->
44

5-
## Theme PR checklist
5+
## Theme PR checklist (`themes/`)
66

7-
- [ ] `{name}.sable.css` and `{name}.preview.sable.css` share the same basename.
8-
- [ ] Preview file contains **only** the seven preview tokens (see **Creating a new theme** in [README](README.md)), plus `@sable-theme` metadata.
9-
- [ ] `fullThemeUrl` in metadata points at the correct raw URL of the full theme file once merged.
7+
- [ ] Files live under **`themes/`** (not the repo root).
8+
- [ ] `themes/{name}.sable.css` and `themes/{name}.preview.sable.css` share the same basename.
9+
- [ ] Preview file contains **only** the seven preview tokens (see **Themes** in [README](README.md)), plus `@sable-theme` metadata.
10+
- [ ] `fullThemeUrl` in metadata points at **`…/main/themes/{name}.sable.css`** once merged.
11+
12+
## Tweak PR checklist (`tweaks/`)
13+
14+
- [ ] Single file under **`tweaks/`**: `tweaks/{name}.sable.css` (no `.preview` file).
15+
- [ ] Metadata block uses **`@sable-tweak`** with at least **`name`** and **`description`** (see [README](README.md)).

.github/workflows/catalog.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ on:
44
push:
55
branches: [main]
66
paths:
7-
- '**.css'
7+
- 'themes/**'
8+
- 'tweaks/**'
89
- 'catalog.json'
910
- 'scripts/build-catalog.mjs'
1011
- '.github/workflows/catalog.yml'

README.md

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,49 @@
11
# Sable themes
22

3-
Official theme packages for [Sable](https://github.com/SableClient/Sable). Each theme ships as:
3+
Official theme packages for [Sable](https://github.com/SableClient/Sable). This repo is split into two top-level folders:
44

5-
| File | Purpose |
6-
|------|--------|
7-
| **`{name}.sable.css`** | Full theme: all tokens, imported at runtime when the user applies the theme. |
8-
| **`{name}.preview.sable.css`** | **Preview only**: a tiny subset of tokens so the catalog and chat can show a safe swatch without loading full CSS. |
5+
| Folder | Contents |
6+
|--------|----------|
7+
| themes/ | Full themes: each basename has `{name}.sable.css` + `{name}.preview.sable.css`. |
8+
| tweaks/ | Optional overlays: one `{name}.sable.css` per tweak (no preview file). |
99

10-
`catalog.json` in this repo lists theme pairs for the client (regenerated by CI).
10+
`catalog.json` at the repo root lists **theme pairs** and **tweaks** for the client (regenerated by CI).
1111

1212
---
1313

14-
## Creating a new theme
14+
## Tweaks (`tweaks/*.sable.css`)
1515

16-
### 1. Full theme file: `{basename}.sable.css`
16+
Tweaks are **single-file** CSS overlays: they stack on top of whichever full theme is active. There is no `.preview.sable.css`. The app loads the full file once, parses metadata from it, caches the CSS, and shows a text description in the catalog instead of a color swatch.
17+
18+
Add one file per tweak under `tweaks/` (e.g. `tweaks/my-tweak.sable.css`).
19+
20+
### Metadata: `@sable-tweak`
21+
22+
The first block comment containing `@sable-tweak` is parsed:
23+
24+
```
25+
/*
26+
@sable-tweak
27+
id: my-tweak
28+
name: Human Readable Name
29+
description: One line explaining what changes (shown in the catalog).
30+
author: Your Name
31+
tags: comma, separated, keywords
32+
*/
33+
```
34+
35+
CI will regenerate the catalog.json. Do not modify it.
36+
37+
---
38+
39+
## Themes (`themes/`)
40+
41+
### 1. Full theme file: `themes/{basename}.sable.css`
1742

1843
- Define the full set of `--sable-*` / `--tc-*` custom properties your design needs.
1944
- You may use any valid CSS. Sable injects the file as a stylesheet when the theme is applied.
2045

21-
### 2. Preview file: `{basename}.preview.sable.css`
46+
### 2. Preview file: `themes/{basename}.preview.sable.css`
2247

2348
The in-app **preview card** (settings catalog, favorites, chat embeds) does **not** load this file as a full stylesheet. Sable **parses** it and only applies a limited set of custom properties to a small UI sample (“Sample text”, Primary, Surface chips).
2449

@@ -38,7 +63,7 @@ Use a `.sable-theme-preview { ... }` block so the file stays readable; only thos
3863

3964
### 3. Metadata block
4065

41-
Put this **first** in the preview file (and typically mirror the same block in the full `.sable.css` for consistency). The first block comment that contains `@sable-theme` is parsed (you can add a license comment **above** it, or put `@sable-theme` in the first block).
66+
Put this **first** in the preview file (and mirror the same block in the full `.sable.css`). The first block comment that contains `@sable-theme` is parsed.
4267

4368
```
4469
/*
@@ -49,17 +74,14 @@ author: Your Name
4974
kind: light
5075
contrast: low
5176
tags: comma, separated, keywords
52-
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/my-theme.sable.css
77+
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/themes/my-theme.sable.css
5378
*/
5479
```
5580

5681
- **`kind`**: `light` or `dark`.
5782
- **`contrast`**: `low` or `high`.
58-
- **`fullThemeUrl`**: URL to the full `.sable.css` (used when linking from preview to install).
59-
60-
Adjust `fullThemeUrl` to the upstream raw URL once the files are on GitHub, although you'll need to point to your fork or import the raw file for your testing.
83+
- **`fullThemeUrl`**: Raw URL to the full file under `themes/` (used when linking from preview to install).
6184

62-
### 4. Naming and catalog
85+
Adjust `fullThemeUrl` to match this repo layout: `…/main/themes/{basename}.sable.css` once the files are on `main`.
6386

64-
- Basename must match between files: `my-theme.preview.sable.css` pairs with `my-theme.sable.css`.
65-
- After you add or rename files on `main`, CI will regenerate `catalog.json`. Do not modify it.
87+
CI will regenerate the catalog.json. Do not modify it.

scripts/build-catalog.mjs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,72 @@ const REPO_ROOT = path.join(__dirname, '..');
88

99
const PREVIEW_SUFFIX = '.preview.sable.css';
1010
const FULL_SUFFIX = '.sable.css';
11+
const THEMES_DIR = 'themes';
12+
const TWEAKS_DIR = 'tweaks';
1113

1214
const repo =
1315
process.env.GITHUB_REPOSITORY?.trim() ||
1416
process.env.CATALOG_REPOSITORY?.trim() ||
1517
'SableClient/themes';
1618
const ref = process.env.GITHUB_REF_NAME?.trim() || process.env.CATALOG_REF?.trim() || 'main';
1719

18-
function rawFileUrl(fileName) {
19-
return `https://raw.githubusercontent.com/${repo}/${ref}/${fileName}`;
20+
function rawFileUrl(relativePath) {
21+
return `https://raw.githubusercontent.com/${repo}/${ref}/${relativePath}`;
2022
}
2123

2224
function buildCatalog() {
23-
const files = fs.readdirSync(REPO_ROOT);
25+
const themesPath = path.join(REPO_ROOT, THEMES_DIR);
26+
if (!fs.existsSync(themesPath) || !fs.statSync(themesPath).isDirectory()) {
27+
console.warn(`missing ${THEMES_DIR}/ directory`);
28+
}
29+
const files = fs.existsSync(themesPath) ? fs.readdirSync(themesPath) : [];
2430
const previewFiles = files.filter((f) => f.endsWith(PREVIEW_SUFFIX));
2531

2632
const themes = [];
2733
for (const previewName of previewFiles) {
2834
const basename = previewName.slice(0, -PREVIEW_SUFFIX.length);
2935
const fullName = `${basename}${FULL_SUFFIX}`;
3036
if (!files.includes(fullName)) {
31-
console.warn(`skip ${previewName}: missing ${fullName}`);
37+
console.warn(`skip ${THEMES_DIR}/${previewName}: missing ${fullName}`);
3238
continue;
3339
}
40+
const prevRel = `${THEMES_DIR}/${previewName}`;
41+
const fullRel = `${THEMES_DIR}/${fullName}`;
3442
themes.push({
3543
basename,
36-
previewUrl: rawFileUrl(previewName),
37-
fullUrl: rawFileUrl(fullName),
44+
previewUrl: rawFileUrl(prevRel),
45+
fullUrl: rawFileUrl(fullRel),
3846
});
3947
}
4048

4149
themes.sort((a, b) => a.basename.localeCompare(b.basename));
4250

51+
const tweaks = [];
52+
const tweaksPath = path.join(REPO_ROOT, TWEAKS_DIR);
53+
if (fs.existsSync(tweaksPath) && fs.statSync(tweaksPath).isDirectory()) {
54+
for (const name of fs.readdirSync(tweaksPath)) {
55+
if (!name.endsWith(FULL_SUFFIX)) continue;
56+
const basename = name.slice(0, -FULL_SUFFIX.length);
57+
tweaks.push({
58+
basename,
59+
fullUrl: rawFileUrl(`${TWEAKS_DIR}/${name}`),
60+
});
61+
}
62+
tweaks.sort((a, b) => a.basename.localeCompare(b.basename));
63+
}
64+
4365
return {
4466
version: 1,
4567
repository: repo,
4668
ref,
4769
themes,
70+
tweaks,
4871
};
4972
}
5073

5174
const catalog = buildCatalog();
5275
const outPath = path.join(REPO_ROOT, 'catalog.json');
5376
fs.writeFileSync(outPath, `${JSON.stringify(catalog, null, 2)}\n`, 'utf8');
54-
console.log(`Wrote ${outPath} (${catalog.themes.length} theme pairs)`);
77+
console.log(
78+
`Wrote ${outPath} (${catalog.themes.length} theme pairs, ${catalog.tweaks.length} tweaks)`
79+
);
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ author: kr0nst
66
kind: dark
77
contrast: low
88
tags: dark
9-
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/accord.sable.css
9+
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/themes/accord.sable.css
1010
*/
1111

1212
.sable-theme-preview {
@@ -18,3 +18,4 @@ fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/accord.s
1818
--sable-primary-main: #5865f2;
1919
--sable-primary-on-main: #fff;
2020
}
21+
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ author: kr0nst
66
kind: dark
77
contrast: low
88
tags: dark
9-
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/accord.sable.css
9+
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/themes/accord.sable.css
1010
*/
1111

1212
body.sable-remote-theme {
@@ -99,3 +99,4 @@ body.sable-remote-theme {
9999
--mx-uc-7: hsl(40, 100%, 75%);
100100
--mx-uc-8: hsl(0, 100%, 75%);
101101
}
102+
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ author: Elec3137
66
kind: dark
77
contrast: high
88
tags: dark, oled
9-
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/black.sable.css
9+
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/themes/black.sable.css
1010
*/
1111

1212
.sable-theme-preview {
@@ -18,3 +18,4 @@ fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/black.sa
1818
--sable-primary-main: #bdb6ec;
1919
--sable-primary-on-main: #1b1a21;
2020
}
21+

black.sable.css renamed to themes/black.sable.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ author: Elec3137
66
kind: dark
77
contrast: high
88
tags: dark, oled
9-
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/black.sable.css
9+
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/themes/black.sable.css
1010
*/
1111

1212
body.sable-remote-theme {
@@ -88,3 +88,4 @@ body.sable-remote-theme {
8888
--sable-shadow: rgba(0, 0, 0, 0.4);
8989
--sable-overlay: rgba(15, 14, 18, 0.85);
9090
}
91+
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ author: Sable
66
kind: dark
77
contrast: low
88
tags: dark, warm
9-
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/butter.sable.css
9+
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/themes/butter.sable.css
1010
*/
1111

1212
.sable-theme-preview {
@@ -18,3 +18,4 @@ fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/butter.s
1818
--sable-primary-main: #e3ba91;
1919
--sable-primary-on-main: #1a1916;
2020
}
21+
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ author: Sable
66
kind: dark
77
contrast: low
88
tags: dark, warm
9-
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/butter.sable.css
9+
fullThemeUrl: https://raw.githubusercontent.com/SableClient/themes/main/themes/butter.sable.css
1010
*/
1111

1212
body.sable-remote-theme {
@@ -88,3 +88,4 @@ body.sable-remote-theme {
8888
--sable-shadow: rgba(0, 0, 0, 0.6);
8989
--sable-overlay: rgba(15, 14, 12, 0.9);
9090
}
91+

0 commit comments

Comments
 (0)