diff --git a/.github/workflows/deploy-gh-pages.yml b/.github/workflows/deploy-gh-pages.yml
index 11bd2a2..63eab85 100644
--- a/.github/workflows/deploy-gh-pages.yml
+++ b/.github/workflows/deploy-gh-pages.yml
@@ -33,7 +33,7 @@ jobs:
- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
with:
- source: ./docs
+ source: ./docs/site
destination: ./_site
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
diff --git a/.gitignore b/.gitignore
index 8dd4607..0003fb2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -395,4 +395,15 @@ FodyWeavers.xsd
*.msp
# JetBrains Rider
-*.sln.iml
\ No newline at end of file
+*.sln.iml
+# Jekyll / GitHub Pages local build
+_site/
+.jekyll-cache/
+.jekyll-metadata
+.sass-cache/
+vendor/
+.bundle/
+docs/site/Gemfile.lock
+
+# Claude Code scratch directory (local, not shared)
+.claude/
diff --git a/Hyperbee.Templating.slnx b/Hyperbee.Templating.slnx
index e28fea4..ea7b360 100644
--- a/Hyperbee.Templating.slnx
+++ b/Hyperbee.Templating.slnx
@@ -5,7 +5,7 @@
-
+
diff --git a/docs/site/Gemfile b/docs/site/Gemfile
new file mode 100644
index 0000000..6380d59
--- /dev/null
+++ b/docs/site/Gemfile
@@ -0,0 +1,13 @@
+source "https://rubygems.org"
+
+gem "jekyll", "~> 4.3"
+gem "just-the-docs"
+
+group :jekyll_plugins do
+ gem "jekyll-remote-theme"
+ gem "jekyll-include-cache"
+ gem "jekyll-seo-tag"
+ gem "jekyll-relative-links"
+end
+
+gem "webrick", "~> 1.8"
diff --git a/docs/_config.yml b/docs/site/_config.yml
similarity index 100%
rename from docs/_config.yml
rename to docs/site/_config.yml
diff --git a/docs/_includes/nav_footer_custom.html b/docs/site/_includes/nav_footer_custom.html
similarity index 100%
rename from docs/_includes/nav_footer_custom.html
rename to docs/site/_includes/nav_footer_custom.html
diff --git a/docs/docs.projitems b/docs/site/docs.projitems
similarity index 100%
rename from docs/docs.projitems
rename to docs/site/docs.projitems
diff --git a/docs/docs.shproj b/docs/site/docs.shproj
similarity index 100%
rename from docs/docs.shproj
rename to docs/site/docs.shproj
diff --git a/docs/index.md b/docs/site/index.md
similarity index 100%
rename from docs/index.md
rename to docs/site/index.md
diff --git a/docs/site/local-jekyll.md b/docs/site/local-jekyll.md
new file mode 100644
index 0000000..ade9f4b
--- /dev/null
+++ b/docs/site/local-jekyll.md
@@ -0,0 +1,427 @@
+# Running Jekyll Docs Locally (Docker)
+
+Reusable recipe for previewing `just-the-docs` / GitHub Pages sites locally
+using a throwaway `ruby:3.3` container. Works for any repo -- BlazorX, Hyperbee,
+anything else that follows the same docs convention.
+
+No Ruby install required. Docker Desktop is the only dependency.
+
+---
+
+## First-time setup (teammate onboarding)
+
+Skip this section if you already have Docker and a bash shell working.
+
+### 1. Install Docker Desktop
+
+**Windows / macOS**: download from https://www.docker.com/products/docker-desktop/
+and run the installer. Defaults are fine. On Windows it prompts to enable
+WSL 2 -- accept.
+
+**Linux**: install Docker Engine per your distro's instructions. You do
+not need Docker Desktop specifically; any `docker` CLI that can pull
+public images works.
+
+**Licensing note**: Docker Desktop is free for personal use, education,
+non-commercial open-source work, and companies with fewer than 250
+employees AND less than $10M in annual revenue. Larger companies need
+paid subscriptions. Check the current terms before using it in
+a commercial setting.
+
+### 2. Start Docker and verify
+
+Launch Docker Desktop (Windows/macOS) and wait for the whale icon in
+the system tray to settle. Then in a terminal:
+
+```bash
+docker --version
+docker run --rm hello-world
+```
+
+The first command prints the Docker version. The second pulls and runs
+a tiny test image -- if it prints "Hello from Docker!", you're set.
+
+### 3. Pick a shell
+
+The `docker run` command below works from any shell, but the
+`MSYS_NO_PATHCONV=1` prefix is a Git Bash specific workaround for a
+path-translation bug on Windows. Your options:
+
+- **Git Bash** (Windows) -- use the commands as written. Get it bundled
+ with Git for Windows at https://git-scm.com/
+- **WSL 2** (Windows) -- drop the `MSYS_NO_PATHCONV=1` prefix; WSL
+ doesn't need it. Paths also change from `C:/...` to `/mnt/c/...`.
+- **PowerShell** (Windows) -- drop the prefix; use backticks instead
+ of backslashes for line continuation.
+- **macOS / Linux terminal** -- drop the prefix; paths are already
+ POSIX.
+
+### 4. Pre-pull the image (optional but recommended)
+
+The first `docker run` in the Quick-start section pulls `ruby:3.3`
+(~900 MB). You can do this explicitly up front so the first actual
+use starts fast:
+
+```bash
+docker pull ruby:3.3
+```
+
+After this, every container we spin up reuses the cached image.
+
+---
+
+## Prerequisites (for a running environment)
+
+1. **Docker running** -- verified via `docker --version` and `docker info`.
+2. A project with a `docs/` folder (or `docs/site/`, or wherever you keep
+ Jekyll sources) containing:
+ - `_config.yml`
+ - `Gemfile`
+ - Your markdown content.
+3. Git Bash, WSL, or another bash-capable shell (the `MSYS_NO_PATHCONV`
+ trick below is specifically for Git Bash on Windows).
+
+---
+
+## Quick-start command
+
+From the project root, pick a port and run:
+
+```bash
+MSYS_NO_PATHCONV=1 docker run --rm --name my-jekyll \
+ -v "C:/path/to/project/docs/site:/srv/jekyll" \
+ -w /srv/jekyll -p 4000:4000 \
+ ruby:3.3 \
+ sh -c "bundle install --quiet && bundle exec jekyll serve --host 0.0.0.0 --force_polling"
+```
+
+Then open `http://localhost:4000//` in your browser, where
+`` is whatever `baseurl` is set to in `_config.yml`
+(for example, `/blazorx/`).
+
+**What each flag does**:
+- `MSYS_NO_PATHCONV=1` -- stops Git Bash from rewriting the Windows path
+ into a POSIX-looking path that Docker then fails to mount.
+- `--rm` -- container is deleted when it stops. No cleanup needed.
+- `--name my-jekyll` -- optional, lets you `docker stop my-jekyll` later.
+- `-v :/srv/jekyll` -- bind-mounts your docs folder into the
+ container's working directory.
+- `-w /srv/jekyll` -- makes that the starting directory.
+- `-p 4000:4000` -- publishes port 4000 on your host. Change the left side
+ if 4000 is taken.
+- `ruby:3.3` -- the Debian/glibc Ruby 3.3 image. Avoids the Alpine/musl
+ sass-embedded broken-pipe bug.
+- `sh -c "bundle install --quiet && bundle exec jekyll serve ..."` --
+ installs gems, then runs Jekyll in watch mode.
+- `--host 0.0.0.0` -- needed so the host machine can reach the server
+ through the port mapping.
+- `--force_polling` -- needed on Windows bind mounts for file-change
+ detection to work reliably.
+
+First run downloads `ruby:3.3` (~900 MB). Subsequent runs start in seconds
+because the image is cached locally.
+
+---
+
+## What each repo needs
+
+### `docs//_config.yml`
+
+Minimum viable starting point:
+
+```yaml
+title: My Project
+description: One-line project description
+remote_theme: pmarsceill/just-the-docs
+baseurl: "/myproject/"
+url: "https://example.github.io"
+
+aux_links:
+ "GitHub Repository":
+ - "//github.com/my-org/my-project"
+
+search_enabled: true
+color_scheme: dark
+
+markdown: kramdown
+highlighter: rouge
+permalink: pretty
+
+plugins:
+ - jekyll-remote-theme
+ - jekyll-include-cache
+ - jekyll-seo-tag
+ - jekyll-relative-links
+
+relative_links:
+ enabled: true
+ collections: true
+
+# Optional: Mermaid diagram support (just-the-docs >= 0.5)
+mermaid:
+ version: "10.9.0"
+
+defaults:
+ - scope:
+ path: ""
+ values:
+ layout: "default"
+ # Disable Liquid rendering inside content pages so code fences
+ # containing {{ or }} don't trip the template engine. Adjust the
+ # paths to match your directory layout.
+ - scope:
+ path: "getting-started"
+ values:
+ render_with_liquid: false
+ - scope:
+ path: "guides"
+ values:
+ render_with_liquid: false
+ - scope:
+ path: "reference"
+ values:
+ render_with_liquid: false
+ - scope:
+ path: "index.md"
+ values:
+ render_with_liquid: false
+```
+
+### `docs//Gemfile`
+
+```ruby
+source "https://rubygems.org"
+
+gem "jekyll", "~> 4.3"
+gem "just-the-docs"
+
+group :jekyll_plugins do
+ gem "jekyll-remote-theme"
+ gem "jekyll-include-cache"
+ gem "jekyll-seo-tag"
+ gem "jekyll-relative-links"
+end
+
+gem "webrick", "~> 1.8"
+```
+
+### `.gitignore` entries
+
+Add to the repo's root `.gitignore`:
+
+```
+# Jekyll / GitHub Pages local build
+_site/
+.jekyll-cache/
+.jekyll-metadata
+.sass-cache/
+vendor/
+.bundle/
+docs/site/Gemfile.lock
+```
+
+Adjust `docs/site/Gemfile.lock` to match your docs path.
+
+### GitHub Pages workflow (optional, for publishing)
+
+`.github/workflows/deploy-gh-pages.yml`:
+
+```yaml
+name: Deploy GitHub Pages
+
+on:
+ push:
+ branches: ["main"]
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/configure-pages@v5
+ - uses: actions/jekyll-build-pages@v1
+ with:
+ source: ./docs/site
+ destination: ./_site
+ - uses: actions/upload-pages-artifact@v3
+
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - id: deployment
+ uses: actions/deploy-pages@v4
+```
+
+Set `source:` to wherever your docs live (for example `./docs` or `./docs/site`).
+
+---
+
+## Running multiple projects in parallel
+
+Each project gets its own container name and its own host port. The
+`ruby:3.3` image is shared across all of them.
+
+```bash
+# BlazorX on port 4000
+MSYS_NO_PATHCONV=1 docker run --rm --name bzx-jekyll \
+ -v "C:/Development/playground/BlazorX/docs/site:/srv/jekyll" \
+ -w /srv/jekyll -p 4000:4000 ruby:3.3 \
+ sh -c "bundle install --quiet && bundle exec jekyll serve --host 0.0.0.0 --force_polling"
+
+# Hyperbee.Json on port 4001
+MSYS_NO_PATHCONV=1 docker run --rm --name hbjson-jekyll \
+ -v "C:/Development/hyperbee.json/docs:/srv/jekyll" \
+ -w /srv/jekyll -p 4001:4000 ruby:3.3 \
+ sh -c "bundle install --quiet && bundle exec jekyll serve --host 0.0.0.0 --force_polling"
+```
+
+Browse them at `http://localhost:4000//` and
+`http://localhost:4001//` simultaneously.
+
+---
+
+## Reusable helper script
+
+Drop this at a well-known location (for example `C:/Development/tools/jekyll-serve.sh`):
+
+```bash
+#!/usr/bin/env bash
+# Start a Jekyll dev container for any project.
+# Usage: jekyll-serve.sh [docs-dir] [host-port]
+set -eu
+
+DOCS_DIR="${1:-$(pwd)/docs/site}"
+PORT="${2:-4000}"
+
+# Absolute path for Docker bind mount
+DOCS_ABS="$(cd "$DOCS_DIR" && pwd)"
+
+# Pick a reasonable container name from the parent folder
+NAME="jekyll-$(basename "$(dirname "$DOCS_ABS")")-$PORT"
+
+echo "Serving $DOCS_ABS on http://localhost:$PORT/"
+echo "Container: $NAME"
+echo "Stop with: docker stop $NAME"
+
+MSYS_NO_PATHCONV=1 docker run --rm --name "$NAME" \
+ -v "${DOCS_ABS}:/srv/jekyll" \
+ -w /srv/jekyll -p "${PORT}:4000" \
+ ruby:3.3 \
+ sh -c "bundle install --quiet && bundle exec jekyll serve --host 0.0.0.0 --force_polling"
+```
+
+Then from any repo:
+
+```bash
+# Uses ./docs/site, port 4000
+~/dev/tools/jekyll-serve.sh
+
+# Custom path
+~/dev/tools/jekyll-serve.sh ./docs
+
+# Custom path and port
+~/dev/tools/jekyll-serve.sh ./docs 4001
+```
+
+---
+
+## Speeding up repeat starts (optional)
+
+On each cold start the container runs `bundle install` and fetches about
+40 gems. That's ~20 seconds. Cache the bundle directory to reuse across
+runs by adding a volume for `/usr/local/bundle`:
+
+```bash
+MSYS_NO_PATHCONV=1 docker run --rm --name my-jekyll \
+ -v "C:/path/to/docs:/srv/jekyll" \
+ -v "jekyll-bundle-cache:/usr/local/bundle" \
+ -w /srv/jekyll -p 4000:4000 ruby:3.3 \
+ sh -c "bundle install --quiet && bundle exec jekyll serve --host 0.0.0.0 --force_polling"
+```
+
+`jekyll-bundle-cache` is a named Docker volume. It persists across
+containers and projects. Remove with `docker volume rm jekyll-bundle-cache`.
+
+---
+
+## Troubleshooting
+
+### `docker: command not found`
+
+Docker is not installed or not on `PATH`. See the First-time setup
+section above. On Windows, restart your terminal after installing
+Docker Desktop so `PATH` picks up the new entries.
+
+### `Cannot connect to the Docker daemon`
+
+Docker is installed but not running. On Windows/macOS, launch
+Docker Desktop and wait for the whale icon to stop animating. On
+Linux, `sudo systemctl start docker` (or `service docker start`).
+
+### "Could not locate Gemfile"
+
+The bind mount did not land where the container expected. On Git Bash you
+need both the `MSYS_NO_PATHCONV=1` prefix and a Windows-style absolute
+path like `C:/path/...` (forward slashes).
+
+### Port already in use
+
+Another process or container has the host port. Check with
+`docker ps --filter "publish=4000"` or just pick a different port on the
+left side of `-p host:container`.
+
+### Mermaid diagrams don't render
+
+Your `_config.yml` needs a `mermaid:` block with a `version:` key, and
+your markdown must use ``` ```mermaid ``` fenced blocks. The theme
+JavaScript replaces the code block with rendered SVG on page load --
+nothing needs to run server-side.
+
+### SCSS errors ("expected }")
+
+You probably set `render_with_liquid: false` too broadly. Scope it to
+content directories only (see the `defaults` block in `_config.yml`
+above). The theme's SCSS files genuinely need Liquid for
+`{% include %}` directives.
+
+### Links ending in `.md` return 404
+
+Install `jekyll-relative-links` (see `Gemfile` and `_config.yml`
+templates above). Without it, Jekyll does not rewrite `[text](foo.md)`
+links to the final rendered URL.
+
+### File changes not picked up
+
+Windows bind mounts need `--force_polling` on the `jekyll serve` command.
+Without it, Jekyll uses inotify/fsevent which do not fire across the
+Docker VM boundary.
+
+### `_config.yml` edits seem to be ignored
+
+Jekyll does not auto-reload `_config.yml` even with `--force_polling`.
+Stop and restart the container to pick up changes.
+
+---
+
+## Stopping the container
+
+```bash
+docker stop my-jekyll
+```
+
+`--rm` in the run command means the container is removed automatically
+on stop. No manual cleanup.
diff --git a/docs/syntax/configuration.md b/docs/site/syntax/configuration.md
similarity index 100%
rename from docs/syntax/configuration.md
rename to docs/site/syntax/configuration.md
diff --git a/docs/syntax/examples.md b/docs/site/syntax/examples.md
similarity index 100%
rename from docs/syntax/examples.md
rename to docs/site/syntax/examples.md
diff --git a/docs/syntax/methods.md b/docs/site/syntax/methods.md
similarity index 100%
rename from docs/syntax/methods.md
rename to docs/site/syntax/methods.md
diff --git a/docs/syntax/overview.md b/docs/site/syntax/overview.md
similarity index 100%
rename from docs/syntax/overview.md
rename to docs/site/syntax/overview.md
diff --git a/docs/syntax/syntax.md b/docs/site/syntax/syntax.md
similarity index 100%
rename from docs/syntax/syntax.md
rename to docs/site/syntax/syntax.md
diff --git a/docs/syntax/tokens.md b/docs/site/syntax/tokens.md
similarity index 100%
rename from docs/syntax/tokens.md
rename to docs/site/syntax/tokens.md