diff --git a/.github/workflows/release-themes.yml b/.github/workflows/release-themes.yml index e01f75f..35f655a 100644 --- a/.github/workflows/release-themes.yml +++ b/.github/workflows/release-themes.yml @@ -116,6 +116,13 @@ jobs: - name: Package Home Assistant run: cp themes/warm-burnout.yaml warm-burnout-home-assistant.yaml + - name: Package Obsidian + run: | + cd obsidian + zip -j ../warm-burnout-obsidian.zip \ + theme.css \ + manifest.json + - name: Package JetBrains run: | cd jetbrains @@ -137,6 +144,7 @@ jobs: warm-burnout-tmux.zip warm-burnout-eza.zip warm-burnout-home-assistant.yaml + warm-burnout-obsidian.zip jetbrains/warm-burnout-theme.jar - name: Publish to JetBrains Marketplace @@ -149,3 +157,36 @@ jobs: https://plugins.jetbrains.com/api/updates/upload env: JETBRAINS_TOKEN: ${{ secrets.JETBRAINS_TOKEN }} + + sync-obsidian-mirror: + needs: [validate] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Sync to mirror repo + env: + MIRROR_DEPLOY_KEY: ${{ secrets.OBSIDIAN_MIRROR_DEPLOY_KEY }} + run: | + mkdir -p ~/.ssh + echo "$MIRROR_DEPLOY_KEY" > ~/.ssh/deploy_key + chmod 600 ~/.ssh/deploy_key + export GIT_SSH_COMMAND="ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no" + + git clone git@github.com:felipefdl/warm-burnout-obsidian.git mirror + cp obsidian/theme.css mirror/ + cp obsidian/manifest.json mirror/ + cp obsidian/README.md mirror/ + cp LICENSE mirror/ + + cd mirror + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add -A + if git diff --cached --quiet; then + echo "No changes to sync" + else + git commit -m "Sync from warm-burnout ${GITHUB_REF_NAME}" + git tag "${GITHUB_REF_NAME}" + git push origin main --tags + fi diff --git a/AGENTS.md b/AGENTS.md index fc12677..37d27c1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -39,6 +39,7 @@ warm-burnout/ windows_terminal.rs # Windows Terminal theme validation tests tmux.rs # tmux theme validation tests zsh.rs # Zsh theme validation tests + obsidian.rs # Obsidian theme validation tests .github/workflows/ validate.yml # CI: run theme validation on push/PR release-vscode.yml # VS Code extension release workflow @@ -133,6 +134,11 @@ warm-burnout/ light.yml # Light variant README.md # eza install instructions AGENTS.md # eza-specific agent rules + obsidian/ # Obsidian community theme + theme.css # Dark + light variants (CSS custom properties) + manifest.json # Community theme manifest + README.md # Obsidian install instructions + AGENTS.md # Obsidian-specific agent rules screenshots/ # Theme preview screenshots AGENTS.md # Screenshot-specific agent rules generate.mjs # Playwright script to render HTML -> PNG diff --git a/README.md b/README.md index e4a07c8..be9b90c 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ Inspired by materials that age well. Unlike your eyes. | Zsh | Available | [`zsh/`](zsh/) | | Home Assistant | Available | [`home-assistant/`](home-assistant/) | | eza | Available | [`eza/`](eza/) | +| Obsidian | Available | [`obsidian/`](obsidian/) | Each platform lives in its own directory with its own README, build process, and release workflow. diff --git a/obsidian/AGENTS.md b/obsidian/AGENTS.md new file mode 100644 index 0000000..feace28 --- /dev/null +++ b/obsidian/AGENTS.md @@ -0,0 +1,54 @@ +# Obsidian -- Agent Instructions + +## Platform Reference + +See the root [`AGENTS.md`](../AGENTS.md) for the canonical palette, design principles, and brand rules. Do not duplicate palette tables here. + +## Obsidian Theme Format + +- Obsidian community themes consist of `theme.css` and `manifest.json` at the repo/directory root. +- Both dark and light variants live in a single `theme.css`, switched via `.theme-dark` / `.theme-light` body class selectors. +- `manifest.json` contains name, version, minAppVersion, author, and optional authorUrl. + +## CSS Architecture + +The theme uses a four-layer CSS custom property system: + +1. **Palette layer** (`--wb-*`): Canonical hex values inside `.theme-dark` / `.theme-light`. Only place raw hex appears. Test harness reads from these. +2. **Base mapping**: Maps `--wb-*` into Obsidian's `--color-base-*` ramp (13 steps) and `--color-*` extended colors. +3. **Code syntax**: `--code-*` variables mapped to `--wb-*` for both CodeMirror 6 and Prism.js. Additional `.token.*` rules for reading view. +4. **Warmth tweaks**: Warm shadows, scrollbar tints, softer radii. No layout changes. + +## Color Variable Extraction + +The test harness uses `obsidian_color(src, variant, key)` to extract `--wb-{key}: #hex;` from inside the `.theme-{variant}` block. When adding new palette colors, add them as `--wb-*` declarations in both variant blocks. + +## Surface Ramp + +The `--color-base-*` scale uses 13 steps (00, 05, 10, 20, 25, 30, 35, 40, 50, 60, 70, 100). All intermediates carry a warm undertone. In dark mode, 00 = deepest surface, 100 = primary text. In light mode, 00 = lightest surface, 100 = primary text. + +## Heading Colors + +H1 through H6 are mapped to palette materials by visual weight: amber, burnt orange, aged brass, terra cotta, steel patina, warm stone. Set via `--h1-color` through `--h6-color` in each variant block. + +## Distribution + +The theme is distributed via a mirror repo (`felipefdl/warm-burnout-obsidian`) that CI syncs on tag push. The Obsidian community directory pulls from that mirror. Source of truth is always this monorepo. + +## File Structure + +``` +obsidian/ + theme.css # Single CSS file, both dark + light variants + manifest.json # Obsidian theme manifest + README.md # Install instructions + AGENTS.md # This file +``` + +## Rules + +1. Every hex value in `--wb-*` declarations must come from the canonical palette. No approximations. +2. Surface ramp intermediates must carry warm undertone (R > G > B in hex channels). +3. Do not add blues outside of the steel patina type accent. +4. Keep both `.theme-dark` and `.theme-light` blocks in sync: same `--wb-*` variable set, different values. +5. Test changes with `cargo test --test obsidian`. diff --git a/obsidian/README.md b/obsidian/README.md new file mode 100644 index 0000000..f994c40 --- /dev/null +++ b/obsidian/README.md @@ -0,0 +1,38 @@ +# Warm Burnout for Obsidian + +Your second brain was running on factory-default colors. Cold blues, harsh whites, zero consideration for 2am rabbit holes through your note graph. Fixed. + +Full community theme for Obsidian with dark and light variants. Warm palette, contrast-audited, zero blues in the chrome. Headings follow a natural energy gradient from amber down to warm stone. + +## Install + +### Community Themes (recommended) + +1. Open Settings > Appearance > Themes +2. Click "Manage" and search for **Warm Burnout** +3. Install and activate + +### Manual + +1. Download `theme.css` and `manifest.json` from the [latest release](https://github.com/felipefdl/warm-burnout/releases) +2. Create a folder called `Warm Burnout` inside your vault's `.obsidian/themes/` directory +3. Place both files in that folder +4. Open Settings > Appearance > Themes and select **Warm Burnout** + +## What This Themes + +- **Surface hierarchy**: 13-step warm ramp from deep brown-black to warm cream. No neutral grays anywhere. +- **Headings**: H1 through H6 mapped to palette materials (amber, burnt orange, aged brass, terra cotta, steel patina, warm stone). Visual weight decreases naturally. +- **Code blocks**: Full syntax palette in both editing and reading views. Functions = amber, keywords = burnt orange, strings = dried sage, types = steel patina. +- **Accent**: Copper rust on all interactive elements, links, and active states. +- **Warm tweaks**: Tinted shadows, warm scrollbar tracks, soft selection highlights. No layout changes. + +## Palette + +Both variants derive from the canonical Warm Burnout palette defined in the root [`AGENTS.md`](../AGENTS.md). + +Dark background: `#1a1510`. Light background: `#F5EDE0`. Accent: `#b8522e` (copper rust). + +## Requirements + +Obsidian 1.0.0 or later. diff --git a/obsidian/manifest.json b/obsidian/manifest.json new file mode 100644 index 0000000..7ddf984 --- /dev/null +++ b/obsidian/manifest.json @@ -0,0 +1,7 @@ +{ + "name": "Warm Burnout", + "version": "1.4.2", + "minAppVersion": "1.0.0", + "author": "Felipe Lima", + "authorUrl": "https://warmburnout.com" +} diff --git a/obsidian/theme.css b/obsidian/theme.css new file mode 100644 index 0000000..e3313fb --- /dev/null +++ b/obsidian/theme.css @@ -0,0 +1,432 @@ +/* ========================================================================== + Warm Burnout for Obsidian + Warm, contrast-audited color theme. Dark + Light. + https://warmburnout.com + ========================================================================== */ + +/* -- Dark variant --------------------------------------------------------- */ +.theme-dark { + /* Palette (canonical hex values, test harness reads from these) */ + --wb-bg: #1a1510; + --wb-fg: #bfbdb6; + --wb-accent: #b8522e; + --wb-cursor: #f5c56e; + --wb-amber: #ffb454; + --wb-burnt-orange: #ff8f40; + --wb-operator: #f29668; + --wb-terra-cotta: #dc9e92; + --wb-dried-sage: #b4bc78; + --wb-verdigris: #96b898; + --wb-dusty-mauve: #d4a8b8; + --wb-coral: #ec9878; + --wb-warm-stone: #b4a89c; + --wb-aged-brass: #deb074; + --wb-steel-patina: #90aec0; + --wb-gold: #e6c08a; + --wb-error: #f49090; + + /* Surface ramp (warm undertone throughout, no neutral grays) */ + --color-base-00: #14120f; + --color-base-05: #1a1510; + --color-base-10: #1f1d17; + --color-base-20: #2a2520; + --color-base-25: #302a22; + --color-base-30: #3a342c; + --color-base-35: #443d34; + --color-base-40: #5a5348; + --color-base-50: #6e665c; + --color-base-60: #8a8278; + --color-base-70: #9e968c; + --color-base-100: #bfbdb6; + + /* Extended colors */ + --color-red: var(--wb-error); + --color-red-rgb: 244, 144, 144; + --color-orange: var(--wb-burnt-orange); + --color-orange-rgb: 255, 143, 64; + --color-yellow: var(--wb-amber); + --color-yellow-rgb: 255, 180, 84; + --color-green: var(--wb-dried-sage); + --color-green-rgb: 180, 188, 120; + --color-cyan: var(--wb-verdigris); + --color-cyan-rgb: 150, 184, 152; + --color-blue: var(--wb-steel-patina); + --color-blue-rgb: 144, 174, 192; + --color-purple: var(--wb-dusty-mauve); + --color-purple-rgb: 212, 168, 184; + --color-pink: var(--wb-coral); + --color-pink-rgb: 236, 152, 120; + + /* Headings */ + --h1-color: var(--wb-amber); + --h2-color: var(--wb-burnt-orange); + --h3-color: var(--wb-aged-brass); + --h4-color: var(--wb-terra-cotta); + --h5-color: var(--wb-steel-patina); + --h6-color: var(--wb-warm-stone); + + /* Selection and highlights */ + --text-selection: rgba(245, 197, 110, 0.2); + --text-highlight-bg: rgba(245, 197, 110, 0.15); + + /* Ribbon (left icon strip) */ + --ribbon-background: #14120f; + --ribbon-background-collapsed: #14120f; + + /* Sidebar */ + --background-secondary: #16130f; + --background-secondary-alt: #1a1510; + + /* Navigation items */ + --nav-item-color: var(--color-base-60); + --nav-item-color-hover: var(--wb-fg); + --nav-item-color-active: var(--wb-fg); + --nav-item-color-selected: var(--wb-fg); + --nav-item-background-hover: rgba(184, 82, 46, 0.08); + --nav-item-background-active: rgba(184, 82, 46, 0.12); + --nav-item-background-selected: rgba(184, 82, 46, 0.15); + + /* Tabs */ + --tab-background-active: #1a1510; + --tab-text-color: var(--color-base-50); + --tab-text-color-focused: var(--wb-fg); + --tab-text-color-focused-active: var(--wb-fg); + --tab-text-color-focused-active-current: var(--wb-fg); + --tab-outline-color: transparent; + --tab-stacked-header-height: 36px; + --tab-container-background: #14120f; + --tab-divider-color: transparent; + --tab-curve: 6px; + + /* Titlebar */ + --titlebar-background: #14120f; + --titlebar-background-focused: #14120f; + --titlebar-text-color: var(--color-base-60); + + /* Status bar */ + --status-bar-background: #14120f; + --status-bar-text-color: var(--color-base-50); + --status-bar-border-color: transparent; + + /* Dividers and borders */ + --divider-color: rgba(191, 189, 182, 0.06); + --tab-outline-color: transparent; + --prompt-border-color: var(--color-base-25); + --background-modifier-border: var(--color-base-20); + --background-modifier-border-hover: var(--color-base-30); + --background-modifier-border-focus: var(--wb-accent); + + /* Interactive states */ + --interactive-normal: var(--color-base-10); + --interactive-hover: var(--color-base-20); + --interactive-accent: var(--wb-accent); + --interactive-accent-hover: #c4603a; + --background-modifier-hover: rgba(184, 82, 46, 0.08); + + /* Icons */ + --icon-color: var(--color-base-50); + --icon-color-hover: var(--wb-fg); + --icon-color-active: var(--wb-accent); + --icon-color-focused: var(--color-base-60); + --icon-opacity: 0.85; + --icon-opacity-hover: 1; + --icon-opacity-active: 1; + + /* Checkbox accent */ + --checkbox-color: var(--wb-accent); + --checkbox-color-hover: #c4603a; + --checkbox-border-color: var(--color-base-35); + + /* Tag pills */ + --tag-color: var(--wb-accent); + --tag-color-hover: #c4603a; + --tag-background: rgba(184, 82, 46, 0.1); + --tag-background-hover: rgba(184, 82, 46, 0.18); +} + +/* -- Light variant -------------------------------------------------------- */ +.theme-light { + /* Palette (canonical hex values, test harness reads from these) */ + --wb-bg: #f5ede0; + --wb-fg: #3a3630; + --wb-accent: #b8522e; + --wb-cursor: #8a6600; + --wb-amber: #855700; + --wb-burnt-orange: #924800; + --wb-operator: #8f4418; + --wb-terra-cotta: #8e4632; + --wb-dried-sage: #4d5c1a; + --wb-verdigris: #286a48; + --wb-dusty-mauve: #7e4060; + --wb-coral: #883850; + --wb-warm-stone: #544c40; + --wb-aged-brass: #74501c; + --wb-steel-patina: #285464; + --wb-gold: #7a5a1c; + --wb-error: #b03434; + + /* Surface ramp (warm undertone throughout, no neutral grays) */ + --color-base-00: #f5ede0; + --color-base-05: #ede5d8; + --color-base-10: #e5ddd0; + --color-base-20: #d5cbbd; + --color-base-25: #c8bfb0; + --color-base-30: #b8ae9e; + --color-base-35: #a89e8e; + --color-base-40: #968c7c; + --color-base-50: #7e7568; + --color-base-60: #665e52; + --color-base-70: #524a40; + --color-base-100: #3a3630; + + /* Extended colors */ + --color-red: var(--wb-error); + --color-red-rgb: 176, 52, 52; + --color-orange: var(--wb-burnt-orange); + --color-orange-rgb: 146, 72, 0; + --color-yellow: var(--wb-amber); + --color-yellow-rgb: 133, 87, 0; + --color-green: var(--wb-dried-sage); + --color-green-rgb: 77, 92, 26; + --color-cyan: var(--wb-verdigris); + --color-cyan-rgb: 40, 106, 72; + --color-blue: var(--wb-steel-patina); + --color-blue-rgb: 40, 84, 100; + --color-purple: var(--wb-dusty-mauve); + --color-purple-rgb: 126, 64, 96; + --color-pink: var(--wb-coral); + --color-pink-rgb: 136, 56, 80; + + /* Headings */ + --h1-color: var(--wb-amber); + --h2-color: var(--wb-burnt-orange); + --h3-color: var(--wb-aged-brass); + --h4-color: var(--wb-terra-cotta); + --h5-color: var(--wb-steel-patina); + --h6-color: var(--wb-warm-stone); + + /* Selection and highlights */ + --text-selection: rgba(138, 102, 0, 0.15); + --text-highlight-bg: rgba(138, 102, 0, 0.12); + + /* Ribbon (left icon strip) */ + --ribbon-background: #ebe3d6; + --ribbon-background-collapsed: #ebe3d6; + + /* Sidebar */ + --background-secondary: #efe7da; + --background-secondary-alt: #f5ede0; + + /* Navigation items */ + --nav-item-color: var(--color-base-60); + --nav-item-color-hover: var(--wb-fg); + --nav-item-color-active: var(--wb-fg); + --nav-item-color-selected: var(--wb-fg); + --nav-item-background-hover: rgba(184, 82, 46, 0.06); + --nav-item-background-active: rgba(184, 82, 46, 0.1); + --nav-item-background-selected: rgba(184, 82, 46, 0.12); + + /* Tabs */ + --tab-background-active: #f5ede0; + --tab-text-color: var(--color-base-50); + --tab-text-color-focused: var(--wb-fg); + --tab-text-color-focused-active: var(--wb-fg); + --tab-text-color-focused-active-current: var(--wb-fg); + --tab-outline-color: transparent; + --tab-stacked-header-height: 36px; + --tab-container-background: #ebe3d6; + --tab-divider-color: transparent; + --tab-curve: 6px; + + /* Titlebar */ + --titlebar-background: #ebe3d6; + --titlebar-background-focused: #ebe3d6; + --titlebar-text-color: var(--color-base-60); + + /* Status bar */ + --status-bar-background: #ebe3d6; + --status-bar-text-color: var(--color-base-50); + --status-bar-border-color: transparent; + + /* Dividers and borders */ + --divider-color: rgba(58, 54, 48, 0.08); + --tab-outline-color: transparent; + --prompt-border-color: var(--color-base-25); + --background-modifier-border: var(--color-base-20); + --background-modifier-border-hover: var(--color-base-30); + --background-modifier-border-focus: var(--wb-accent); + + /* Interactive states */ + --interactive-normal: var(--color-base-10); + --interactive-hover: var(--color-base-20); + --interactive-accent: var(--wb-accent); + --interactive-accent-hover: #a04828; + --background-modifier-hover: rgba(184, 82, 46, 0.06); + + /* Icons */ + --icon-color: var(--color-base-50); + --icon-color-hover: var(--wb-fg); + --icon-color-active: var(--wb-accent); + --icon-color-focused: var(--color-base-60); + --icon-opacity: 0.85; + --icon-opacity-hover: 1; + --icon-opacity-active: 1; + + /* Checkbox accent */ + --checkbox-color: var(--wb-accent); + --checkbox-color-hover: #a04828; + --checkbox-border-color: var(--color-base-35); + + /* Tag pills */ + --tag-color: var(--wb-accent); + --tag-color-hover: #a04828; + --tag-background: rgba(184, 82, 46, 0.08); + --tag-background-hover: rgba(184, 82, 46, 0.14); +} + +/* -- Shared (resolves per-variant via cascade) ---------------------------- */ +body { + /* Accent: copper rust HSL decomposition of #b8522e */ + --accent-h: 16; + --accent-s: 60%; + --accent-l: 45%; + + /* Code syntax highlighting (CodeMirror 6 + Prism.js shared tokens) */ + --code-background: var(--color-base-00); + --code-normal: var(--wb-fg); + --code-function: var(--wb-amber); + --code-keyword: var(--wb-burnt-orange); + --code-string: var(--wb-dried-sage); + --code-comment: var(--wb-warm-stone); + --code-tag: var(--wb-terra-cotta); + --code-value: var(--wb-dusty-mauve); + --code-property: var(--wb-aged-brass); + --code-important: var(--wb-verdigris); + --code-operator: var(--wb-operator); + --code-punctuation: var(--color-base-60); + + /* Warm shadows */ + --background-modifier-box-shadow: rgba(26, 21, 16, 0.3); + --input-shadow: 0 1px 2px rgba(26, 21, 16, 0.15); + --shadow-s: 0px 1px 2px rgba(26, 21, 16, 0.12), 0px 3px 6px rgba(26, 21, 16, 0.08); + --shadow-l: 0px 2px 4px rgba(26, 21, 16, 0.12), 0px 8px 24px rgba(26, 21, 16, 0.16); + + /* Warm scrollbars */ + --scrollbar-bg: var(--color-base-10); + --scrollbar-thumb-bg: var(--color-base-35); + --scrollbar-active-thumb-bg: var(--color-base-40); + + /* Softer radii */ + --radius-s: 4px; + --radius-m: 6px; + --radius-l: 10px; +} + +/* -- UI chrome refinements ------------------------------------------------ */ + +/* Ribbon icons: warm tint on hover, accent on active */ +.workspace-ribbon .sidebar-toggle-button, +.workspace-ribbon .clickable-icon { + border-radius: var(--radius-m); + transition: background 0.15s, color 0.15s; +} + +/* Tab bar: active tab stands out with bottom accent border */ +.workspace-tab-header.is-active { + border-bottom: 2px solid var(--wb-accent); +} + +.workspace-tab-header:not(.is-active) { + opacity: 0.7; +} + +.workspace-tab-header:not(.is-active):hover { + opacity: 1; +} + +/* Nav items: smoother hover, rounded selection */ +.nav-file-title, +.nav-folder-title { + border-radius: var(--radius-s); + transition: background 0.12s, color 0.12s; +} + +/* Status bar: subtle top border */ +.status-bar { + border-top: 1px solid var(--divider-color); +} + +/* Sidebar section headers */ +.nav-header { + text-transform: uppercase; + font-size: 0.65em; + letter-spacing: 0.08em; + color: var(--color-base-50); +} + +/* Vault name in sidebar */ +.nav-buttons-container + .tree-item .nav-folder-title-content { + font-weight: 600; +} + +/* -- Prism.js token overrides (reading view) ------------------------------ */ +.markdown-reading-view .token.keyword { + color: var(--wb-burnt-orange); + font-weight: bold; +} + +.markdown-reading-view .token.function { + color: var(--wb-amber); +} + +.markdown-reading-view .token.string, +.markdown-reading-view .token.char, +.markdown-reading-view .token.attr-value { + color: var(--wb-dried-sage); +} + +.markdown-reading-view .token.number, +.markdown-reading-view .token.boolean, +.markdown-reading-view .token.constant { + color: var(--wb-dusty-mauve); +} + +.markdown-reading-view .token.comment { + color: var(--wb-warm-stone); + font-style: italic; +} + +.markdown-reading-view .token.operator { + color: var(--wb-operator); +} + +.markdown-reading-view .token.punctuation { + color: var(--color-base-60); +} + +.markdown-reading-view .token.property { + color: var(--wb-aged-brass); + font-style: italic; +} + +.markdown-reading-view .token.class-name { + color: var(--wb-steel-patina); + font-style: italic; +} + +.markdown-reading-view .token.tag { + color: var(--wb-terra-cotta); + font-weight: bold; +} + +.markdown-reading-view .token.regex { + color: var(--wb-verdigris); +} + +.markdown-reading-view .token.symbol { + color: var(--wb-terra-cotta); +} + +.markdown-reading-view .token.selector { + color: var(--wb-coral); +} diff --git a/site/index.html b/site/index.html index 1e0f000..1c2b2e4 100644 --- a/site/index.html +++ b/site/index.html @@ -5,14 +5,14 @@
15 platforms. The burnout is spreading.
+16 platforms. The burnout is spreading.
Obsidian
+Notes
+ Available + +