From 3177ee1fc1ab5e45cb4f9c155e8b1e6de5d2a43c Mon Sep 17 00:00:00 2001
From: Tilman Griesel
Date: Sun, 1 Dec 2024 12:38:39 +0100
Subject: [PATCH] feat: Implement VitePress
---
.github/workflows/docs-deploy.yml | 50 +
.gitignore | 12 +-
Makefile | 18 +-
README.md | 54 +-
docs/.vitepress/config.mts | 26 +
docs/.vitepress/theme/index.ts | 20 +
docs/.vitepress/theme/style.css | 602 +++++++++
docs/about/graphite.md | 30 +
.../graphite-theme-development-kit.md | 72 +
docs/features/graphite-theme-patcher.md | 190 +++
.../README.md => docs/guides/card-examples.md | 18 +-
docs/guides/getting-started.md | 59 +
docs/index.md | 44 +
docs/{ => public/assets/brand}/logo.png | Bin
docs/{ => public/assets/brand}/logo.svg | 0
.../graphite_theme_patcher_demo_accent.gif | Bin
.../graphite_theme_patcher_demo_advanced.gif | Bin
docs/public/assets/screenshot/dark.png | Bin 0 -> 2542787 bytes
docs/public/assets/screenshot/light.png | Bin 0 -> 1857264 bytes
docs/screenshots/dark.png | Bin 2210427 -> 0 bytes
docs/screenshots/light.png | Bin 1522326 -> 0 bytes
extras/theme-patcher/README.md | 219 ----
package.json | 16 +
yarn.lock | 1155 +++++++++++++++++
24 files changed, 2333 insertions(+), 252 deletions(-)
create mode 100644 .github/workflows/docs-deploy.yml
create mode 100644 docs/.vitepress/config.mts
create mode 100644 docs/.vitepress/theme/index.ts
create mode 100644 docs/.vitepress/theme/style.css
create mode 100644 docs/about/graphite.md
create mode 100644 docs/features/graphite-theme-development-kit.md
create mode 100644 docs/features/graphite-theme-patcher.md
rename examples/README.md => docs/guides/card-examples.md (90%)
create mode 100644 docs/guides/getting-started.md
create mode 100644 docs/index.md
rename docs/{ => public/assets/brand}/logo.png (100%)
rename docs/{ => public/assets/brand}/logo.svg (100%)
rename docs/{screenshots => public/assets/gif}/graphite_theme_patcher_demo_accent.gif (100%)
rename docs/{screenshots => public/assets/gif}/graphite_theme_patcher_demo_advanced.gif (100%)
create mode 100644 docs/public/assets/screenshot/dark.png
create mode 100644 docs/public/assets/screenshot/light.png
delete mode 100644 docs/screenshots/dark.png
delete mode 100644 docs/screenshots/light.png
delete mode 100644 extras/theme-patcher/README.md
create mode 100644 package.json
create mode 100644 yarn.lock
diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml
new file mode 100644
index 0000000..47984ff
--- /dev/null
+++ b/.github/workflows/docs-deploy.yml
@@ -0,0 +1,50 @@
+name: Deploy docs site to Pages
+on:
+ push:
+ branches: [main]
+ workflow_dispatch:
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+concurrency:
+ group: pages
+ cancel-in-progress: false
+jobs:
+ # Build job
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Setup Node
+ uses: actions/setup-node@v4
+ with:
+ node-version: 18
+ cache: yarn
+ - name: Setup Pages
+ uses: actions/configure-pages@v5
+ - name: Install dependencies
+ run: yarn install
+ - name: Build with VitePress
+ run: |
+ yarn docs:build
+ touch ./docs/.vitepress/dist/.nojekyll
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./docs/.vitepress/dist
+ # Deployment job
+ deploy:
+ environment:
+ name: docs
+ url: ${{ steps.deployment.outputs.page_url }}
+ needs: build
+ runs-on: ubuntu-latest
+ name: Deploy
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/.gitignore b/.gitignore
index dd5c568..f850cd0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,12 @@
.DS_Store
-/.vscode
+.vscode
+cache
+*.log
+*.tgz
+.DS_Store
+.idea
+.temp
+.vite_opt_cache
+.vscode
+node_modules
+TODOs.md
\ No newline at end of file
diff --git a/Makefile b/Makefile
index c676de1..75368a2 100644
--- a/Makefile
+++ b/Makefile
@@ -20,11 +20,17 @@ format:
pre-commit run --all-files
@echo "YAML formatting complete."
+docs-dev:
+ @echo "Starting vitepress..."
+ yarn add -D vitepress
+ yarn docs:dev
+
help:
@echo "Available targets:"
- @echo " all - Run theme assembly (default)"
- @echo " theme - Run the theme assembler"
- @echo " clean - Remove generated files"
- @echo " dev - Run rebuild dev script"
- @echo " format - Format YAML files in src and theme directories"
- @echo " help - Show this help message"
+ @echo " all - Run theme assembly (default)"
+ @echo " theme - Run the theme assembler"
+ @echo " clean - Remove generated files"
+ @echo " dev - Run rebuild dev script"
+ @echo " docs-dev - Run local vitepress"
+ @echo " format - Format YAML files in src and theme directories"
+ @echo " help - Show this help message"
diff --git a/README.md b/README.md
index 12114dc..6fd87c6 100644
--- a/README.md
+++ b/README.md
@@ -6,43 +6,65 @@
-
-
-
**Graphite** is a modern theme that offers a soothing dark mode alongside a bright, clean light mode. It uses native device fonts and maintains a unified design language across all Home Assistant interfaces, from the admin panel to code editors.
+
+
+
## Installation
-Easily install Graphite via [HACS](https://hacs.xyz/docs/use/), the Home Assistant Community Store.
+
+### Step 1: Install HACS
+If you haven't already, [install HACS](https://hacs.xyz/docs/use/) by following the official guide.
+
+### Step 2: Add the Graphite Theme Repository
[![Open Graphite in your Home Assistant instance](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=TilmanGriesel&repository=graphite)
-### Manual Guide
-
-1. Copy the `themes` folder into your home-assistant config folder
-1. Set the theme folder in you `configuration.yaml`
+#### Alternatively
+1. Open the HACS interface in Home Assistant.
+2. Search for **Graphite Theme** or use the direct link below:
+3. Click **Install** to add the theme to your setup.
+
+### Step 3: Configure your theme directory
+
+Ensure your `configuration.yaml` is set up to include custom themes:
```yaml
frontend:
themes: !include_dir_merge_named themes
```
-3. Restart Home Assistant
-4. Select the `Graphite` theme in your profile
+### Step 4: Restart Home Assistant
+Restart your Home Assistant instance to apply changes.
-## Examples
+### Step 5: Select the Graphite Theme
-If you're curious about the cards from my screenshot, you can [check out my examples](https://github.com/TilmanGriesel/graphite/blob/main/examples/README.md).
+1. Go to your **User Profile** in Home Assistant.
+2. Under **Themes**, select `Graphite` (Light or Dark) from the dropdown menu.
+
+
+## Manual Installation
+For manual installation, you can follow these steps:
-## Custom primary color & more
+1. Download and copy the `themes` folder into your Home Assistant configuration directory.
+2. Add the following to your `configuration.yaml`:
+ ```yaml
+ frontend:
+ themes: !include_dir_merge_named themes
+ ```
+3. Restart Home Assistant.
+4. Choose the `Graphite` theme from your profile.
+## Personalize Graphite
Customize the Graphite theme's primary color and more without needing to fork the project by using the [Graphite Theme Patcher](https://github.com/TilmanGriesel/graphite/blob/main/extras/theme-patcher/README.md). This tool is designed for advanced users with technical expertise and experience in script and config modification. For detailed setup instructions, refer to the patcher's README.
-## Modifying the theme
+## Theme Development Kit
+I've created token abstraction and a script to help maintain Graphite's consistency across theme variants and simplify updates. This setup can also serve as a great starting point for building your own themes in no time. [Theme Development Kit](https://github.com/TilmanGriesel/graphite/blob/main/extras/theme-patcher/README.md)
-I've created a small token abstraction and a script to help maintain Graphite's consistency across theme variants and simplify updates. You'll find the source components in the src folder. After making any changes, use the theme_assembler Python 3 script in the tools directory to regenerate the theme files. Avoid directly modifying the files in the themes directory. This setup can also serve as a great starting point for building your own themes in no time.
+## Examples
+If you're curious about the cards from my screenshot, you can [check out my examples](https://github.com/TilmanGriesel/graphite/blob/main/examples/README.md).
## Personal note
-
Hi there, I'm Tilman, nice to meet you! I'm a product designer and software engineer with a love for blending technology, art, design, and open-source projects. I live in a cozy 16th-century home that I'm gradually turning into a smarter, more connected space.
I started designing this theme in 2022 to make our smart home more intuitive and visually harmonious for my partner Sophia and me. The goal was to create an experience that's both user-friendly and aesthetically pleasing, without needing extra complexity or plugins.
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
new file mode 100644
index 0000000..5e74838
--- /dev/null
+++ b/docs/.vitepress/config.mts
@@ -0,0 +1,26 @@
+import { defineConfig } from "vitepress";
+
+// https://vitepress.dev/reference/site-config
+export default defineConfig({
+ title: "Graphite Theme",
+ titleTemplate: ":title",
+ description: "Calm and clean theme for Home Assistant.",
+ themeConfig: {
+ // https://vitepress.dev/reference/default-theme-config
+ nav: [
+ { text: "Home", link: "/" },
+ { text: "Get Started", link: "/guides/getting-started" },
+ { text: "Theme Patcher", link: "/features/graphite-theme-patcher" },
+ { text: "Development Kit", link: "/features/graphite-theme-development-kit" },
+ { text: "Card Examples", link: "/guides/card-examples" },
+ { text: "About", link: "/about/graphite" },
+ ],
+ socialLinks: [
+ { icon: "github", link: "https://github.com/TilmanGriesel/graphite" },
+ ],
+ footer: {
+ message: 'Released under the MIT License.',
+ copyright: 'Copyright Β© 2024 Tilman Griesel'
+ }
+ },
+});
diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts
new file mode 100644
index 0000000..f8939cf
--- /dev/null
+++ b/docs/.vitepress/theme/index.ts
@@ -0,0 +1,20 @@
+import { h } from "vue";
+import type { Theme } from "vitepress";
+import DefaultTheme from "vitepress/theme";
+import "./style.css";
+
+export default {
+ extends: DefaultTheme,
+ Layout: () => {
+ return h(DefaultTheme.Layout, null, {
+ // https://vitepress.dev/guide/extending-default-theme#layout-slots
+ });
+ },
+ enhanceApp({ app, router, siteData }) {
+ // ...
+ },
+ appearance: {
+ initialValue: 'auto'
+ },
+ aside: false,
+} satisfies Theme;
\ No newline at end of file
diff --git a/docs/.vitepress/theme/style.css b/docs/.vitepress/theme/style.css
new file mode 100644
index 0000000..9c5b36f
--- /dev/null
+++ b/docs/.vitepress/theme/style.css
@@ -0,0 +1,602 @@
+@import url("https://fonts.googleapis.com/css2?family=Palanquin+Dark:wght@400;500;600;700&display=swap");
+
+/**
+ * Colors: Solid
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-c-white: #ffffff;
+ --vp-c-black: #000000;
+
+ --vp-c-neutral: var(--vp-c-black);
+ --vp-c-neutral-inverse: var(--vp-c-white);
+}
+
+.dark {
+ --vp-c-neutral: var(--vp-c-white);
+ --vp-c-neutral-inverse: var(--vp-c-black);
+}
+
+/**
+ * Colors: Palette
+ *
+ * The primitive colors used for accent colors. These colors are referenced
+ * by functional colors such as "Text", "Background", or "Brand".
+ *
+ * Each colors have exact same color scale system with 3 levels of solid
+ * colors with different brightness, and 1 soft color.
+ *
+ * - `XXX-1`: The most solid color used mainly for colored text. It must
+ * satisfy the contrast ratio against when used on top of `XXX-soft`.
+ *
+ * - `XXX-2`: The color used mainly for hover state of the button.
+ *
+ * - `XXX-3`: The color for solid background, such as bg color of the button.
+ * It must satisfy the contrast ratio with pure white (#ffffff) text on
+ * top of it.
+ *
+ * - `XXX-soft`: The color used for subtle background such as custom container
+ * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors
+ * on top of it.
+ *
+ * The soft color must be semi transparent alpha channel. This is crucial
+ * because it allows adding multiple "soft" colors on top of each other
+ * to create a accent, such as when having inline code block inside
+ * custom containers.
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-c-gray-1: #e8e9ec;
+ --vp-c-gray-2: #e3e3e4;
+ --vp-c-gray-3: #DADBDF;
+ --vp-c-gray-soft: #dfdfe2;
+
+ --vp-c-indigo-1: #3451b2;
+ --vp-c-indigo-2: #3a5ccc;
+ --vp-c-indigo-3: #5672cd;
+ --vp-c-indigo-soft: rgba(100, 108, 255, 0.14);
+
+ --vp-c-purple-1: #6f42c1;
+ --vp-c-purple-2: #7e4cc9;
+ --vp-c-purple-3: #8e5cd9;
+ --vp-c-purple-soft: rgba(159, 122, 234, 0.14);
+
+ --vp-c-green-1: #18794e;
+ --vp-c-green-2: #299764;
+ --vp-c-green-3: #30a46c;
+ --vp-c-green-soft: rgba(16, 185, 129, 0.14);
+
+ --vp-c-yellow-1: #915930;
+ --vp-c-yellow-2: #946300;
+ --vp-c-yellow-3: #9f6a00;
+ --vp-c-yellow-soft: rgba(234, 179, 8, 0.14);
+
+ --vp-c-red-1: #b8272c;
+ --vp-c-red-2: #d5393e;
+ --vp-c-red-3: #e0575b;
+ --vp-c-red-soft: rgba(244, 63, 94, 0.14);
+
+ --vp-c-sponsor: #db2777;
+
+ --vp-c-graphite-accent-1: #f36d00;
+ --vp-c-graphite-accent-2: #f88e14;
+ --vp-c-graphite-accent-3: #ff9d00;
+ --vp-c-graphite-accent-soft: #af700b;
+}
+
+.dark {
+ --vp-c-graphite-accent-1: #faab2c;
+ --vp-c-graphite-accent-2: #c57a00;
+ --vp-c-graphite-accent-3: #e59109;
+ --vp-c-graphite-accent-soft: #af700b;
+
+ --vp-c-gray-1: #515c67;
+ --vp-c-gray-2: #414853;
+ --vp-c-gray-3: #32363f;
+ --vp-c-gray-soft: rgba(101, 117, 133, 0.16);
+
+ --vp-c-indigo-1: #a8b1ff;
+ --vp-c-indigo-2: #5c73e7;
+ --vp-c-indigo-3: #3e63dd;
+ --vp-c-indigo-soft: rgba(100, 108, 255, 0.16);
+
+ --vp-c-purple-1: #c8abfa;
+ --vp-c-purple-2: #a879e6;
+ --vp-c-purple-3: #8e5cd9;
+ --vp-c-purple-soft: rgba(159, 122, 234, 0.16);
+
+ --vp-c-green-1: #3dd68c;
+ --vp-c-green-2: #30a46c;
+ --vp-c-green-3: #298459;
+ --vp-c-green-soft: rgba(16, 185, 129, 0.16);
+
+ --vp-c-yellow-1: #f9b44e;
+ --vp-c-yellow-2: #da8b17;
+ --vp-c-yellow-3: #a46a0a;
+ --vp-c-yellow-soft: rgba(234, 179, 8, 0.16);
+
+ --vp-c-red-1: #f66f81;
+ --vp-c-red-2: #f14158;
+ --vp-c-red-3: #b62a3c;
+ --vp-c-red-soft: rgba(244, 63, 94, 0.16);
+}
+
+/**
+ * Colors: Background
+ *
+ * - `bg`: The bg color used for main screen.
+ *
+ * - `bg-alt`: The alternative bg color used in places such as "sidebar",
+ * or "code block".
+ *
+ * - `bg-elv`: The elevated bg color. This is used at parts where it "floats",
+ * such as "dialog".
+ *
+ * - `bg-soft`: The bg color to slightly distinguish some components from
+ * the page. Used for things like "carbon ads" or "table".
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-c-bg: #fff;
+ --vp-c-bg-alt: #f6f6f7;
+ --vp-c-bg-elv: #ffffff;
+ --vp-c-bg-soft: #eff0f3;
+}
+
+.dark {
+ --vp-c-bg: #121316;
+ --vp-c-bg-alt: #25252B;
+ --vp-c-bg-elv: #31313b;
+ --vp-c-bg-soft: #34343a;
+}
+
+/**
+ * Colors: Borders
+ *
+ * - `divider`: This is used for separators. This is used to divide sections
+ * within the same components, such as having separator on "h2" heading.
+ *
+ * - `border`: This is designed for borders on interactive components.
+ * For example this should be used for a button outline.
+ *
+ * - `gutter`: This is used to divide components in the page. For example
+ * the header and the lest of the page.
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-c-border: #c2c2c4;
+ --vp-c-divider: #e2e2e3;
+ --vp-c-gutter: #e2e2e3;
+}
+
+.dark {
+ --vp-c-border: #3c3f44;
+ --vp-c-divider: #2e2e32;
+ --vp-c-gutter: #000000;
+}
+
+/**
+ * Colors: Text
+ *
+ * - `text-1`: Used for primary text.
+ *
+ * - `text-2`: Used for muted texts, such as "inactive menu" or "info texts".
+ *
+ * - `text-3`: Used for subtle texts, such as "placeholders" or "caret icon".
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-c-text-1: rgba(60, 60, 60);
+ --vp-c-text-2: rgba(60, 60, 60, 0.78);
+ --vp-c-text-3: rgba(60, 60, 60, 0.56);
+}
+
+.dark {
+ --vp-c-text-1: rgba(240, 240, 240, 0.86);
+ --vp-c-text-2: rgba(240, 240, 240, 0.6);
+ --vp-c-text-3: rgba(240, 240, 240, 0.38);
+}
+
+/**
+ * Colors: Function
+ *
+ * - `default`: The color used purely for subtle indication without any
+ * special meanings attached to it such as bg color for menu hover state.
+ *
+ * - `brand`: Used for primary brand colors, such as link text, button with
+ * brand theme, etc.
+ *
+ * - `tip`: Used to indicate useful information. The default theme uses the
+ * brand color for this by default.
+ *
+ * - `warning`: Used to indicate warning to the users. Used in custom
+ * container, badges, etc.
+ *
+ * - `danger`: Used to show error, or dangerous message to the users. Used
+ * in custom container, badges, etc.
+ *
+ * To understand the scaling system, refer to "Colors: Palette" section.
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-c-default-1: var(--vp-c-gray-1);
+ --vp-c-default-2: var(--vp-c-gray-2);
+ --vp-c-default-3: var(--vp-c-gray-3);
+ --vp-c-default-soft: var(--vp-c-gray-soft);
+
+ --vp-c-brand-1: var(--vp-c-graphite-accent-1);
+ --vp-c-brand-2: var(--vp-c-graphite-accent-2);
+ --vp-c-brand-3: var(--vp-c-graphite-accent-3);
+ --vp-c-brand-soft: var(--vp-c-graphite-accent-soft);
+
+ --vp-c-brand: var(--vp-c-brand-1);
+
+ --vp-c-tip-1: var(--vp-c-brand-1);
+ --vp-c-tip-2: var(--vp-c-brand-2);
+ --vp-c-tip-3: var(--vp-c-brand-3);
+ --vp-c-tip-soft: var(--vp-c-brand-soft);
+
+ --vp-c-note-1: var(--vp-c-brand-1);
+ --vp-c-note-2: var(--vp-c-brand-2);
+ --vp-c-note-3: var(--vp-c-brand-3);
+ --vp-c-note-soft: var(--vp-c-brand-soft);
+
+ --vp-c-success-1: var(--vp-c-green-1);
+ --vp-c-success-2: var(--vp-c-green-2);
+ --vp-c-success-3: var(--vp-c-green-3);
+ --vp-c-success-soft: var(--vp-c-green-soft);
+
+ --vp-c-important-1: var(--vp-c-purple-1);
+ --vp-c-important-2: var(--vp-c-purple-2);
+ --vp-c-important-3: var(--vp-c-purple-3);
+ --vp-c-important-soft: var(--vp-c-purple-soft);
+
+ --vp-c-warning-1: var(--vp-c-yellow-1);
+ --vp-c-warning-2: var(--vp-c-yellow-2);
+ --vp-c-warning-3: var(--vp-c-yellow-3);
+ --vp-c-warning-soft: var(--vp-c-yellow-soft);
+
+ --vp-c-danger-1: var(--vp-c-red-1);
+ --vp-c-danger-2: var(--vp-c-red-2);
+ --vp-c-danger-3: var(--vp-c-red-3);
+ --vp-c-danger-soft: var(--vp-c-red-soft);
+
+ --vp-c-caution-1: var(--vp-c-red-1);
+ --vp-c-caution-2: var(--vp-c-red-2);
+ --vp-c-caution-3: var(--vp-c-red-3);
+ --vp-c-caution-soft: var(--vp-c-red-soft);
+}
+
+/**
+ * Typography
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-font-family-base: "Inter", ui-sans-serif, system-ui, sans-serif,
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
+ "Noto Color Emoji";
+ --vp-font-family-mono: ui-monospace, "Menlo", "Monaco", "Consolas",
+ "Liberation Mono", "Courier New", monospace;
+ --vp-font-family-brand: "Palanquin Dark";
+
+ font-optical-sizing: auto;
+}
+
+:root:where(:lang(zh)) {
+ --vp-font-family-base: "Punctuation SC", "Inter", ui-sans-serif, system-ui,
+ "PingFang SC", "Noto Sans CJK SC", "Noto Sans SC", "Heiti SC",
+ "Microsoft YaHei", "DengXian", sans-serif, "Apple Color Emoji",
+ "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+}
+
+h1.name {
+ font-family: var(--vp-font-family-brand);
+}
+
+.VPNav .title {
+ font-family: var(--vp-font-family-brand);
+}
+
+@media (min-width: 960px) {
+ .main .tagline {
+ font-size: 18px;
+ }
+}
+
+.home .title {
+ visibility: hidden;
+}
+
+/**
+ * Shadows
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06);
+ --vp-shadow-2: 0 3px 12px rgba(0, 0, 0, 0.07), 0 1px 4px rgba(0, 0, 0, 0.07);
+ --vp-shadow-3: 0 12px 32px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.08);
+ --vp-shadow-4: 0 14px 44px rgba(0, 0, 0, 0.12),
+ 0 3px 9px rgba(0, 0, 0, 0.12);
+ --vp-shadow-5: 0 18px 56px rgba(0, 0, 0, 0.16),
+ 0 4px 12px rgba(0, 0, 0, 0.16);
+}
+
+/**
+ * Z-indexes
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-z-index-footer: 10;
+ --vp-z-index-local-nav: 20;
+ --vp-z-index-nav: 30;
+ --vp-z-index-layout-top: 40;
+ --vp-z-index-backdrop: 50;
+ --vp-z-index-sidebar: 60;
+}
+
+@media (min-width: 960px) {
+ :root {
+ --vp-z-index-sidebar: 25;
+ }
+}
+
+/**
+ * Layouts
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-layout-max-width: 1440px;
+}
+
+/**
+ * Component: Header Anchor
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-header-anchor-symbol: "#";
+}
+
+/**
+ * Component: Code
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-code-line-height: 1.7;
+ --vp-code-font-size: 0.875em;
+ --vp-code-color: var(--vp-c-brand-1);
+ --vp-code-link-color: var(--vp-c-brand-1);
+ --vp-code-link-hover-color: var(--vp-c-brand-2);
+ --vp-code-bg: var(--vp-c-default-soft);
+
+ --vp-code-block-color: var(--vp-c-text-2);
+ --vp-code-block-bg: var(--vp-c-bg-alt);
+ --vp-code-block-divider-color: var(--vp-c-gutter);
+
+ --vp-code-lang-color: var(--vp-c-text-3);
+
+ --vp-code-line-highlight-color: var(--vp-c-default-soft);
+ --vp-code-line-number-color: var(--vp-c-text-3);
+
+ --vp-code-line-diff-add-color: var(--vp-c-success-soft);
+ --vp-code-line-diff-add-symbol-color: var(--vp-c-success-1);
+
+ --vp-code-line-diff-remove-color: var(--vp-c-danger-soft);
+ --vp-code-line-diff-remove-symbol-color: var(--vp-c-danger-1);
+
+ --vp-code-line-warning-color: var(--vp-c-warning-soft);
+ --vp-code-line-error-color: var(--vp-c-danger-soft);
+
+ --vp-code-copy-code-border-color: var(--vp-c-divider);
+ --vp-code-copy-code-bg: var(--vp-c-bg-soft);
+ --vp-code-copy-code-hover-border-color: var(--vp-c-divider);
+ --vp-code-copy-code-hover-bg: var(--vp-c-bg);
+ --vp-code-copy-code-active-text: var(--vp-c-text-2);
+ --vp-code-copy-copied-text-content: "Copied";
+
+ --vp-code-tab-divider: var(--vp-code-block-divider-color);
+ --vp-code-tab-text-color: var(--vp-c-text-2);
+ --vp-code-tab-bg: var(--vp-code-block-bg);
+ --vp-code-tab-hover-text-color: var(--vp-c-text-1);
+ --vp-code-tab-active-text-color: var(--vp-c-text-1);
+ --vp-code-tab-active-bar-color: var(--vp-c-brand-1);
+}
+
+/**
+ * Component: Button
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-button-brand-border: transparent;
+ --vp-button-brand-text: var(--vp-c-white);
+ --vp-button-brand-bg: var(--vp-c-brand-3);
+ --vp-button-brand-hover-border: transparent;
+ --vp-button-brand-hover-text: var(--vp-c-white);
+ --vp-button-brand-hover-bg: var(--vp-c-brand-2);
+ --vp-button-brand-active-border: transparent;
+ --vp-button-brand-active-text: var(--vp-c-white);
+ --vp-button-brand-active-bg: var(--vp-c-brand-1);
+
+ --vp-button-alt-border: transparent;
+ --vp-button-alt-text: var(--vp-c-text-1);
+ --vp-button-alt-bg: var(--vp-c-default-3);
+ --vp-button-alt-hover-border: transparent;
+ --vp-button-alt-hover-text: var(--vp-c-text-1);
+ --vp-button-alt-hover-bg: var(--vp-c-default-2);
+ --vp-button-alt-active-border: transparent;
+ --vp-button-alt-active-text: var(--vp-c-text-1);
+ --vp-button-alt-active-bg: var(--vp-c-default-1);
+
+ --vp-button-sponsor-border: var(--vp-c-text-2);
+ --vp-button-sponsor-text: var(--vp-c-text-2);
+ --vp-button-sponsor-bg: transparent;
+ --vp-button-sponsor-hover-border: var(--vp-c-sponsor);
+ --vp-button-sponsor-hover-text: var(--vp-c-sponsor);
+ --vp-button-sponsor-hover-bg: transparent;
+ --vp-button-sponsor-active-border: var(--vp-c-sponsor);
+ --vp-button-sponsor-active-text: var(--vp-c-sponsor);
+ --vp-button-sponsor-active-bg: transparent;
+}
+
+/**
+ * Component: Custom Block
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-custom-block-font-size: 14px;
+ --vp-custom-block-code-font-size: 13px;
+
+ --vp-custom-block-info-border: transparent;
+ --vp-custom-block-info-text: var(--vp-c-text-1);
+ --vp-custom-block-info-bg: var(--vp-c-default-soft);
+ --vp-custom-block-info-code-bg: var(--vp-c-default-soft);
+
+ --vp-custom-block-note-border: transparent;
+ --vp-custom-block-note-text: var(--vp-c-text-1);
+ --vp-custom-block-note-bg: var(--vp-c-default-soft);
+ --vp-custom-block-note-code-bg: var(--vp-c-default-soft);
+
+ --vp-custom-block-tip-border: transparent;
+ --vp-custom-block-tip-text: var(--vp-c-text-1);
+ --vp-custom-block-tip-bg: var(--vp-c-tip-soft);
+ --vp-custom-block-tip-code-bg: var(--vp-c-tip-soft);
+
+ --vp-custom-block-important-border: transparent;
+ --vp-custom-block-important-text: var(--vp-c-text-1);
+ --vp-custom-block-important-bg: var(--vp-c-important-soft);
+ --vp-custom-block-important-code-bg: var(--vp-c-important-soft);
+
+ --vp-custom-block-warning-border: transparent;
+ --vp-custom-block-warning-text: var(--vp-c-text-1);
+ --vp-custom-block-warning-bg: var(--vp-c-warning-soft);
+ --vp-custom-block-warning-code-bg: var(--vp-c-warning-soft);
+
+ --vp-custom-block-danger-border: transparent;
+ --vp-custom-block-danger-text: var(--vp-c-text-1);
+ --vp-custom-block-danger-bg: var(--vp-c-danger-soft);
+ --vp-custom-block-danger-code-bg: var(--vp-c-danger-soft);
+
+ --vp-custom-block-caution-border: transparent;
+ --vp-custom-block-caution-text: var(--vp-c-text-1);
+ --vp-custom-block-caution-bg: var(--vp-c-caution-soft);
+ --vp-custom-block-caution-code-bg: var(--vp-c-caution-soft);
+
+ --vp-custom-block-details-border: var(--vp-custom-block-info-border);
+ --vp-custom-block-details-text: var(--vp-custom-block-info-text);
+ --vp-custom-block-details-bg: var(--vp-custom-block-info-bg);
+ --vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg);
+}
+
+/**
+ * Component: Input
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-input-border-color: var(--vp-c-border);
+ --vp-input-bg-color: var(--vp-c-bg-alt);
+
+ --vp-input-switch-bg-color: var(--vp-c-default-soft);
+}
+
+/**
+ * Component: Nav
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-nav-height: 64px;
+ --vp-nav-bg-color: var(--vp-c-bg);
+ --vp-nav-screen-bg-color: var(--vp-c-bg);
+ --vp-nav-logo-height: 24px;
+}
+
+.hide-nav {
+ --vp-nav-height: 0px;
+}
+
+.hide-nav .VPSidebar {
+ --vp-nav-height: 22px;
+}
+
+/**
+ * Component: Local Nav
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-local-nav-bg-color: var(--vp-c-bg);
+}
+
+/**
+ * Component: Sidebar
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-sidebar-width: 272px;
+ --vp-sidebar-bg-color: var(--vp-c-bg-alt);
+}
+
+/**
+ * Colors Backdrop
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-backdrop-bg-color: rgba(0, 0, 0, 0.6);
+}
+
+/**
+ * Component: Home
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-home-hero-name-color: var(--vp-c-text-1);
+ --vp-home-hero-name-background: transparent;
+
+ --vp-home-hero-image-background-image: none;
+ --vp-home-hero-image-filter: none;
+}
+
+/**
+ * Component: Badge
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-badge-info-border: transparent;
+ --vp-badge-info-text: var(--vp-c-text-2);
+ --vp-badge-info-bg: var(--vp-c-default-soft);
+
+ --vp-badge-tip-border: transparent;
+ --vp-badge-tip-text: var(--vp-c-tip-1);
+ --vp-badge-tip-bg: var(--vp-c-tip-soft);
+
+ --vp-badge-warning-border: transparent;
+ --vp-badge-warning-text: var(--vp-c-warning-1);
+ --vp-badge-warning-bg: var(--vp-c-warning-soft);
+
+ --vp-badge-danger-border: transparent;
+ --vp-badge-danger-text: var(--vp-c-danger-1);
+ --vp-badge-danger-bg: var(--vp-c-danger-soft);
+}
+
+/**
+ * Component: Carbon Ads
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-carbon-ads-text-color: var(--vp-c-text-1);
+ --vp-carbon-ads-poweredby-color: var(--vp-c-text-2);
+ --vp-carbon-ads-bg-color: var(--vp-c-bg-soft);
+ --vp-carbon-ads-hover-text-color: var(--vp-c-brand-1);
+ --vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1);
+}
+
+/**
+ * Component: Local Search
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-local-search-bg: var(--vp-c-bg);
+ --vp-local-search-result-bg: var(--vp-c-bg);
+ --vp-local-search-result-border: var(--vp-c-divider);
+ --vp-local-search-result-selected-bg: var(--vp-c-bg);
+ --vp-local-search-result-selected-border: var(--vp-c-brand-1);
+ --vp-local-search-highlight-bg: var(--vp-c-brand-1);
+ --vp-local-search-highlight-text: var(--vp-c-neutral-inverse);
+}
diff --git a/docs/about/graphite.md b/docs/about/graphite.md
new file mode 100644
index 0000000..882434e
--- /dev/null
+++ b/docs/about/graphite.md
@@ -0,0 +1,30 @@
+# About
+
+Hi there, I'm Tilman, it's great to meet you! π
+
+I'm a product designer and software engineer with a passion for blending technology, art, and design into thoughtful, open-source projects. I live in a cozy 16th-century home, which I'm gradually transforming into a smarter, more connected space.
+
+## About Graphite
+
+I began designing the Graphite theme in 2022 to make our Home Assistant setup more intuitive and visually harmonious for my partner Sophia and me. My aim was to create a user experience that's both friendly and beautiful, free of unnecessary complexity and compatible without requiring extra plugins.
+
+Graphite was after the first public release crafted with two audiences in mind:
+
+- **Everyday Users**: A clean, out-of-the-box theme that simplifies Home Assistant's interface.
+- **Tinkerers**: A flexible foundation for creating custom themes, leveraging build tools and token abstraction to extend or tweak the design effortlessly.
+
+Graphite isn't about flashy features or quantity; it's about quality. It's a theme that grows with you, whether you're just starting out or looking to personalize every pixel of your smart home interface.
+
+## Key Features
+
+- **Minimalist Aesthetic**: A focus on clean design with harmonious colors and device native typography.
+- **User-Friendly**: Designed to enhance usability for both new and experienced Home Assistant users.
+- **Customization Ready**: Easily extend the theme using the provided tools, or tweak it with the theme patcher.
+- **No Dependencies**: No plugins required, Graphite is designed to integrate seamlessly into your setup.
+
+## Why Graphite?
+
+Graphite was born out of a personal need to improve the way we interact with our smart home. I wanted something intuitive, visually appealing, and built to last. It's been a labor of love, evolving through feedback and constant iteration.
+
+If this theme improves your Home Assistant experience, leaving a βοΈ on GitHub would mean a lot and help others discover it too!
+
diff --git a/docs/features/graphite-theme-development-kit.md b/docs/features/graphite-theme-development-kit.md
new file mode 100644
index 0000000..8bc7d52
--- /dev/null
+++ b/docs/features/graphite-theme-development-kit.md
@@ -0,0 +1,72 @@
+# Graphite Theme Development Kit
+
+This guide provides an overview of the tools and processes designed to help you create and maintain consistent theme variants with ease.
+
+## Overview
+
+The development kit includes:
+- **Token Abstraction**: Simplifies theme consistency across variants.
+- **Theme Assembler Script**: Automates the regeneration of theme files after changes.
+- **Source Directory**: Contains all source components (`src/` folder).
+- **Tools Directory**: Houses utility scripts (`tools/` folder).
+
+### Quick Tips
+- Avoid editing files directly in the `themes/` directory.
+- Use the provided `theme_assembler.py` script to apply changes from the `src/` folder.
+- This setup is also an excellent foundation for developing custom themes rapidly.
+
+## Setup and Usage
+
+1. **Install Requirements**: Ensure you have Python 3 and `pre-commit` installed.
+2. **Modify Source Components**: Make updates in the `src/` directory.
+3. **Regenerate Themes**: Run the theme assembler script:
+ ```bash
+ make theme
+ ```
+4. **Clean Theme Directory**: Remove generated files before rebuilding:
+ ```bash
+ make clean
+ ```
+5. **Format YAML Files**: Ensure consistent formatting:
+ ```bash
+ make format
+ ```
+6. **Develop Documentation**: Start a local Vitepress instance for documentation development:
+ ```bash
+ make docs-dev
+ ```
+
+## Makefile Targets
+
+The included `Makefile` simplifies common tasks:
+
+| Target | Description |
+|------------|---------------------------------------------------|
+| `all` | Format YAML files and assemble themes (default). |
+| `theme` | Run the theme assembler script. |
+| `clean` | Remove all generated files in the `themes/` folder. |
+| `dev` | Execute the `rebuild_dev.sh` script. |
+| `docs-dev` | Launch a local Vitepress server. |
+| `format` | Format all YAML files in `src/` and `themes/`. |
+| `help` | Display available Makefile targets. |
+
+## File Structure
+
+- **`src/`**: Source components for your themes.
+- **`tools/`**: Scripts, including `theme_assembler.py`, to automate tasks.
+- **`themes/`**: Generated theme files (do not edit directly).
+- **`docs/`**: Vitepress documentation and statics assets.
+- **`.github/`**: GitHub workflows and more.
+
+## Getting Started
+
+1. Clone the repository.
+2. Make your changes in the `src/` folder.
+3. Use the Makefile commands to assemble, format, and test your themes.
+
+---
+
+### Contribute
+
+This kit is designed to evolve! Feel free to contribute by sharing feedback, submitting issues, or creating pull requests.
+
diff --git a/docs/features/graphite-theme-patcher.md b/docs/features/graphite-theme-patcher.md
new file mode 100644
index 0000000..e70911e
--- /dev/null
+++ b/docs/features/graphite-theme-patcher.md
@@ -0,0 +1,190 @@
+# Graphite Theme Patcher
+
+Effortlessly customize Graphite's primary color and more **without forking the project** using the **Graphite Theme Patcher**. Designed for advanced users, this tool simplifies theme adjustments with minimal hassle.
+
+![graphite_theme_patcher_demo_accent](/assets/gif/graphite_theme_patcher_demo_accent.gif)
+
+## Overview
+
+The Graphite Theme Patcher allows you to:
+- Adjust the primary accent color.
+- Replace specific theme tokens for deeper customization.
+
+This tool is ideal for tinkerers and power users familiar with script and configuration editing.
+
+::: info
+Changes made with this patcher are **temporary**. Updates to the Graphite theme will overwrite customizations unless automated workflows are in place.
+:::
+
+
+## Installation
+
+### **Step 1: Download the Patcher**
+
+Save the `graphite-theme-patcher.py` script to your `/config/scripts` directory. If the directory doesn't exist, create it.
+
+**Quick Command:**
+
+```bash
+wget -O /config/scripts https://raw.githubusercontent.com/TilmanGriesel/graphite/refs/heads/main/extras/theme-patcher/graphite-theme-patcher.py
+```
+
+---
+
+### **Step 2: Add a Shell Command**
+
+1. Open your Home Assistant `configuration.yaml` file.
+2. Add the following entry under `shell_command`:
+
+ ```yaml
+ shell_command:
+ patch_graphite_theme_primary_color: "python3 /config/scripts/graphite-theme-patcher.py {{ rgb_value }}"
+ ```
+
+3. Save and restart Home Assistant.
+
+
+---
+
+### **Step 3: Create a Home Assistant Script**
+
+Use the Home Assistant UI or add this YAML to a new script for adjusting the theme's primary color:
+
+```yaml
+alias: Update & Patch Graphite Theme
+icon: mdi:palette-swatch
+description: Customize the primary color of the Graphite theme.
+fields:
+ user_primary_color:
+ selector:
+ color_rgb: {}
+ default:
+ - 229
+ - 145
+ - 9
+ name: Primary Color
+ required: true
+sequence:
+ - action: shell_command.patch_graphite_theme_primary_color
+ data:
+ rgb_value: "{{ user_primary_color | join(',') }}"
+ - action: frontend.reload_themes
+ data: {}
+```
+
+## Usage
+
+1. Open the script in Home Assistant.
+2. Choose your desired color using the color picker or input RGB values.
+3. Run the script to:
+ 1. Apply your chosen color.
+ 2. Reload the Graphite theme for immediate updates.
+
+::: info
+**Review the script's functionality to ensure safe usage**. While safeguards are in place, it's good practice to understand any changes being applied.
+:::
+
+## Advanced Customization
+
+The basic installation outlined earlier will likely meet your needs, so you can stop here if you're satisfied. However, if you're ready to explore the patcher's true potential, consider this your gateway to experimentation and powerful customization. The documentation isn't exhaustive, but it equips you with enough knowledge to dive deep, experimenting with RGB and size tokens to unleash their full power. From here on, you're stepping into experimental, uncharted territory.
+
+### Advanced Shell Command Example
+
+Add a new shell command to your `configuration.yaml`:
+
+```yaml
+shell_command:
+ patch_theme: "python3 /config/scripts/graphite-theme-patcher.py --theme {{ theme }} --token {{ token }} --type {{ type }} {{ token_value }}"
+```
+
+Save and restart Home Assistant.
+
+---
+
+### Advanced Script Example
+
+```yaml
+alias: Update & Patch Graphite Theme (Advanced)
+icon: mdi:dev-to
+description: Advanced customization of Graphite theme tokens.
+fields:
+ user_primary_color:
+ selector:
+ color_rgb: {}
+ name: Primary Color
+ required: true
+ user_radius_large:
+ selector:
+ number:
+ min: 0
+ max: 99
+ step: 3
+ name: "Large Radius"
+ required: true
+sequence:
+ - action: shell_command.patch_theme
+ data:
+ theme: graphite
+ token: token-rgb-primary
+ type: rgb
+ token_value: "{{ user_primary_color | join(',') }}"
+ - action: shell_command.patch_theme
+ data:
+ theme: graphite
+ token: token-size-radius-large
+ type: radius
+ token_value: "{{ user_radius_large }}"
+ - action: frontend.reload_themes
+ data: {}
+```
+
+## Command-Line Usage
+
+Run the patcher directly for quick edits:
+
+```bash
+python3 graphite-theme-patcher.py "255,158,0"
+```
+
+### Options
+
+```bash
+usage: graphite-theme-patcher.py [-h] [--version] [--token TOKEN] [--type {rgb,size,opacity,radius,generic}] [--theme THEME]
+ [--path PATH]
+ [value]
+
+positional arguments:
+ value Value to set or 'None' to skip
+
+options:
+ -h, --help show this help message and exit
+ --version Show version information and exit
+ --token TOKEN Token to update (default: token-rgb-primary)
+ --type {rgb,size,opacity,radius,generic}
+ Type of token (default: rgb)
+ --theme THEME Theme name (default: graphite)
+ --path PATH Base path for themes directory (default: /config/themes)
+```
+
+---
+
+- **Basic Example**: Update the primary color:
+ ```bash
+ python3 graphite-theme-patcher.py "0,230,226"
+ ```
+- **Advanced Example**: Modify specific tokens:
+ ```bash
+ python3 graphite-theme-patcher.py "255,158,0" --token "token-color-feedback-info"
+ ```
+
+## Requirements
+
+- Access to `/config/themes/graphite`.
+- Write permissions for YAML files.
+- Valid input values (e.g., RGB values between 0β255).
+
+## Error Handling
+
+- **Invalid Inputs**: Triggers validation errors.
+- **Missing Tokens**: Logs errors but continues execution.
+- **Failed Updates**: Logged in `logs/graphite_theme_patcher.log`.
diff --git a/examples/README.md b/docs/guides/card-examples.md
similarity index 90%
rename from examples/README.md
rename to docs/guides/card-examples.md
index 8eb0b8e..76d3436 100644
--- a/examples/README.md
+++ b/docs/guides/card-examples.md
@@ -1,9 +1,11 @@
-## Home Dashboard Card Examples
-I've been getting a lot of questions about my configurations and card style, so I thought I'd share them here. If you have any questions, don't hesitate to open an issue. Just a heads-up: you might need to tweak the configurations a bit to fit your setup.
+# Home Dashboard Card Examples
+I've been getting questions about my configurations and card style, so I thought I'd share them here. If you have any questions, don't hesitate to open an issue. Just a heads-up: you might need to tweak the configurations a bit to fit your setup.
----
+:::info
+This article is somewhat outdated, as it references an earlier version of Graphite and a previous set of dashboard cards.
+:::
-### Clock Card
+## Clock Card
Itβs a digital-clock and card-mod (you can get both in the HACS) with the following configuration.
Custom Cards:
@@ -37,9 +39,7 @@ card_mod:
}
```
----
-
-### Temperature Card
+## Temperature Card
Itβs a mini-graph-card and card-mod (you can get both in the HACS) with the following configuration. You also need a binary night sensor which is a time of day or TOD sensor.
@@ -87,9 +87,7 @@ card_mod:
}
```
----
-
-### Pollenflug Germany (ePIN)
+## Pollenflug Germany (ePIN)
This card utilizes data from the Elektronisches Polleninformationsnetzwerk (ePIN) REST API: https://epin.lgl.bayern.de/pollenflug-aktuell.
To retrieve data from ePIN, you first need to set up a REST sensor in your `/homeassistant/configuration.yaml` file. Adjust the configuration as needed:
diff --git a/docs/guides/getting-started.md b/docs/guides/getting-started.md
new file mode 100644
index 0000000..9aa210b
--- /dev/null
+++ b/docs/guides/getting-started.md
@@ -0,0 +1,59 @@
+# Graphite Theme Quickstart
+
+Graphite is a sleek and modern Home Assistant theme with both a soothing dark mode and a clean, bright light mode. It's easy to install and customize via HACS, the Home Assistant Community Store.
+
+![graphite_theme_patcher_demo_accent](/assets/screenshot/dark.png)
+![graphite_theme_patcher_demo_accent](/assets/screenshot/light.png)
+
+## Installation via HACS
+
+Follow these steps to install the Graphite theme using HACS:
+
+### Step 1: Install HACS
+
+If you haven't already, [install HACS](https://hacs.xyz/docs/use/) by following the official guide.
+
+### Step 2: Add the Graphite Theme Repository
+
+[![Open Graphite in your Home Assistant instance](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=TilmanGriesel&repository=graphite)
+
+#### Alternatively
+1. Open the HACS interface in Home Assistant.
+2. Search for **Graphite Theme** or use the direct link below:
+3. Click **Install** to add the theme to your setup.
+
+### Step 3: Configure Your Theme Directory
+
+Ensure your `configuration.yaml` is set up to include custom themes:
+
+```yaml
+frontend:
+ themes: !include_dir_merge_named themes
+```
+
+### Step 4: Restart Home Assistant
+
+Restart your Home Assistant instance to apply changes.
+
+### Step 5: Select the Graphite Theme
+
+1. Go to your **User Profile** in Home Assistant.
+2. Under **Themes**, select `Graphite` (Light or Dark) from the dropdown menu.
+
+
+## Manual Installation
+
+For manual installation, you can follow these steps:
+
+1. Download and copy the `themes` folder into your Home Assistant configuration directory.
+2. Add the following to your `configuration.yaml`:
+ ```yaml
+ frontend:
+ themes: !include_dir_merge_named themes
+ ```
+3. Restart Home Assistant.
+4. Choose the `Graphite` theme from your profile.
+
+---
+
+Enjoy the Graphite theme? π Consider [leaving a star](https://github.com/TilmanGriesel/graphite/stargazers) on GitHub to support its development!
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..c35506b
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,44 @@
+---
+
+# https://vitepress.dev/reference/default-theme-home-page
+layout: home
+
+hero:
+ name: "Graphite Home Assistant Theme"
+ tagline: "Calm and clean theme for Home Assistant"
+ image:
+ src: /assets/brand/logo.png
+ alt: graphite-home-assistant-theme-logo
+ actions:
+ - theme: brand
+ text: Quickstart
+ link: /guides/getting-started
+
+ - theme: alt
+ text: Theme Patcher
+ link: /features/graphite-theme-patcher
+
+ - theme: alt
+ text: GitHub
+ link: https://github.com/TilmanGriesel/graphite
+
+features:
+ - title: Simple Installation
+ icon: π
+ details: Get started effortlessly - no technical expertise needed! Perfect for users of all skill levels.
+ link: /guides/getting-started
+ linkText: Learn more
+
+ - title: Customize Your Style
+ icon: π¨
+ details: Personalize Graphite. Adjust the primary color and other theme elements using the Graphite Theme Patcher - no forking required.
+ link: /features/graphite-theme-patcher
+ linkText: Learn more
+
+ - title: Advanced Developer Tools
+ icon: π οΈ
+ details: Streamline theme creation with a powerful token abstraction and tools designed to keep variants consistent and updates simple.
+ link: /features/graphite-theme-development-kit
+ linkText: Learn more
+
+---
diff --git a/docs/logo.png b/docs/public/assets/brand/logo.png
similarity index 100%
rename from docs/logo.png
rename to docs/public/assets/brand/logo.png
diff --git a/docs/logo.svg b/docs/public/assets/brand/logo.svg
similarity index 100%
rename from docs/logo.svg
rename to docs/public/assets/brand/logo.svg
diff --git a/docs/screenshots/graphite_theme_patcher_demo_accent.gif b/docs/public/assets/gif/graphite_theme_patcher_demo_accent.gif
similarity index 100%
rename from docs/screenshots/graphite_theme_patcher_demo_accent.gif
rename to docs/public/assets/gif/graphite_theme_patcher_demo_accent.gif
diff --git a/docs/screenshots/graphite_theme_patcher_demo_advanced.gif b/docs/public/assets/gif/graphite_theme_patcher_demo_advanced.gif
similarity index 100%
rename from docs/screenshots/graphite_theme_patcher_demo_advanced.gif
rename to docs/public/assets/gif/graphite_theme_patcher_demo_advanced.gif
diff --git a/docs/public/assets/screenshot/dark.png b/docs/public/assets/screenshot/dark.png
new file mode 100644
index 0000000000000000000000000000000000000000..79e774bd50466d3ec624ce63ba847e8abb0a081c
GIT binary patch
literal 2542787
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 MpbU5Yv(H)luHd|NvZgxGU7yQ@#FvnlFS_WLI
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 Q#&
zF4IT0Upmjq*xPj%$wl+=Mwh#TWq`uRjP4+n6R9waZWU5{??E41u*OqjEq3T}s>Wrn
zjg_guQz9{P<&QHi@@hgZ2tk}i%MJq-T+>7OgGCROCNIxp-VQ1WT(}OIo7 VY^Ry
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 |