diff --git a/.github/workflows/update-pages.yml b/.github/workflows/update-pages.yml
new file mode 100644
index 0000000..979977b
--- /dev/null
+++ b/.github/workflows/update-pages.yml
@@ -0,0 +1,46 @@
+---
+name: Build GH-Pages
+permissions: {}
+
+on:
+ pull_request:
+ push:
+ branches:
+ - master
+ workflow_dispatch:
+
+concurrency:
+ group: "${{ github.workflow }}-${{ github.ref }}"
+ cancel-in-progress: true
+
+jobs:
+ prep:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ steps:
+ - name: Checkout
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: prep
+ path: gh-pages-template/
+ if-no-files-found: error
+ include-hidden-files: true
+ retention-days: 1
+
+ call-jekyll-build:
+ needs: prep
+ permissions:
+ contents: read
+ uses: LizardByte/LizardByte.github.io/.github/workflows/jekyll-build.yml@master
+ secrets:
+ GH_BOT_EMAIL: ${{ secrets.GH_BOT_EMAIL }}
+ GH_BOT_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
+ with:
+ clean_gh_pages: true
+ gh_bot_name: ${{ vars.GH_BOT_NAME }}
+ site_artifact: 'prep'
+ target_branch: 'gh-pages'
diff --git a/gh-pages-template/.readthedocs.yaml b/gh-pages-template/.readthedocs.yaml
new file mode 100644
index 0000000..681f205
--- /dev/null
+++ b/gh-pages-template/.readthedocs.yaml
@@ -0,0 +1,25 @@
+---
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+
+version: 2
+
+build:
+ os: ubuntu-24.04
+ tools:
+ ruby: "3.3"
+ apt_packages:
+ - 7zip
+ - jq
+ jobs:
+ install:
+ - |
+ mkdir -p "./tmp"
+ branch="master"
+ base_url="https://raw.githubusercontent.com/LizardByte/LizardByte.github.io"
+ url="${base_url}/refs/heads/${branch}/scripts/readthedocs_build.sh"
+ curl -sSL -o "./tmp/readthedocs_build.sh" "${url}"
+ chmod +x "./tmp/readthedocs_build.sh"
+ build:
+ html:
+ - "./tmp/readthedocs_build.sh"
diff --git a/gh-pages-template/_config.yml b/gh-pages-template/_config.yml
new file mode 100644
index 0000000..0869c47
--- /dev/null
+++ b/gh-pages-template/_config.yml
@@ -0,0 +1,4 @@
+---
+# See https://github.com/LizardByte/beautiful-jekyll-next/blob/master/_config.yml for documented options
+
+avatar: "/libvirtualhid/assets/img/navbar-avatar.png"
diff --git a/gh-pages-template/_data/features.yml b/gh-pages-template/_data/features.yml
new file mode 100644
index 0000000..d8ed6f4
--- /dev/null
+++ b/gh-pages-template/_data/features.yml
@@ -0,0 +1,40 @@
+---
+- title: "Platform-neutral C++ API"
+ icon_fa: "fas fa-code"
+ description: >
+ Build against portable runtime, profile, device, and report concepts while
+ backend-specific HID details stay behind the library implementation.
+
+- title: "Gamepad-first profiles"
+ icon_fa: "fas fa-gamepad"
+ description: >
+ Create virtual gamepads that model generic HID, Xbox, DualShock, DualSense,
+ and Nintendo Switch Pro-style controller layouts.
+
+- title: "Remote streaming ready"
+ icon_fa: "fas fa-tower-broadcast"
+ description: >
+ Designed for low-latency streaming hosts that need predictable lifecycle,
+ normalized input state, and output feedback callbacks.
+
+- title: "User-mode Windows support"
+ icon_img: "https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/icons/windows.svg"
+ icon_img_alt: "Windows"
+ icon_img_invert: true
+ description: >
+ Windows gamepads are exposed through a user-mode UMDF2 control driver backed
+ by Virtual HID Framework, without requiring a custom kernel-mode driver.
+
+- title: "Linux HID backends"
+ icon_img: "https://cdn.jsdelivr.net/npm/simple-icons@16/icons/linux.svg"
+ icon_img_alt: "Linux"
+ icon_img_invert: true
+ description: >
+ Linux gamepads use descriptor-driven uhid devices, with uinput available for
+ keyboard, mouse, touchscreen, trackpad, and pen tablet devices.
+
+- title: "CMake friendly"
+ icon_fa: "fas fa-screwdriver-wrench"
+ description: >
+ Consume libvirtualhid through installed packages, vendored source,
+ add_subdirectory, or FetchContent in CMake-based projects.
diff --git a/gh-pages-template/assets/img/banners/libvirtualhid.jpeg b/gh-pages-template/assets/img/banners/libvirtualhid.jpeg
new file mode 100644
index 0000000..47ec16d
Binary files /dev/null and b/gh-pages-template/assets/img/banners/libvirtualhid.jpeg differ
diff --git a/gh-pages-template/assets/img/navbar-avatar.png b/gh-pages-template/assets/img/navbar-avatar.png
new file mode 100644
index 0000000..139979d
Binary files /dev/null and b/gh-pages-template/assets/img/navbar-avatar.png differ
diff --git a/gh-pages-template/index.html b/gh-pages-template/index.html
new file mode 100644
index 0000000..aeaa0ef
--- /dev/null
+++ b/gh-pages-template/index.html
@@ -0,0 +1,108 @@
+---
+title: libvirtualhid
+subtitle: A LizardByte project
+layout: page
+full-width: true
+after-content:
+ - donate.html
+ - support.html
+cover-img:
+ - /libvirtualhid/assets/img/banners/libvirtualhid.jpeg
+---
+
+
+
+ libvirtualhid is a cross-platform C++ library for creating virtual input devices. It focuses on
+ gamepad support for remote streaming hosts, while keeping the public API portable and hiding
+ platform-specific virtual HID details behind backend implementations.
+ {{ feature.description }}Features
+
+ {% endif %}
+
{{ feature.title }}
+
+ Read the documentation to learn how to build, use, and integrate libvirtualhid. +
++ Browse the library source, public headers, and streaming-host-oriented examples. +
+