Skip to content

Internal Docs Site

The project docs (from docs/ and .context/) are published as a static site using Zensical (successor to MkDocs Material), deployed to Cloudflare Pages at cslewis-docs.fueled.engineering, gated behind Cloudflare Access for @fueled.com SSO.

Quick start (local)

# Preview locally (hot-reload)
./scripts/docs-build.sh serve

# One-off build → site/
./scripts/docs-build.sh build

Requires uv (install). Zensical runs via uvx — no global install needed.

How it works

  1. scripts/docs-build.sh merges docs/ and .context/ into docs/_build/
  2. Zensical reads mkdocs.yml (which points at docs/_build/) and produces site/
  3. GH Action (.github/workflows/docs.yml) deploys site/ to Cloudflare Pages on every push to main
  4. Cloudflare Access gates the site with Google Workspace SSO (@fueled.com)

Both docs/_build/ and site/ are gitignored.

Adding pages

  1. Add your .md file under docs/ (or .context/ for internal-only content)
  2. Add a nav entry in mkdocs.yml under the appropriate section
  3. Push to main — auto-deploys

Setup for a new Fueled project

Copy these files into any repo:

File Purpose
mkdocs.yml Site config — edit site_name, nav
scripts/docs-build.sh Build script — merges source dirs
.github/workflows/docs.yml CI deploy to Cloudflare Pages

1. Cloudflare Pages project

CLOUDFLARE_ACCOUNT_ID=97e8452a103b40bfa5d44e08ceca38bb \
  wrangler pages project create <project-name> --production-branch main

Or create via Cloudflare dashboard → Pages → Create project → Direct upload.

2. GitHub secrets

Add to repo Settings → Secrets and variables → Actions:

Secret Value
CLOUDFLARE_API_TOKEN API token with Cloudflare Pages: Edit on Fueled account
CLOUDFLARE_ACCOUNT_ID 97e8452a103b40bfa5d44e08ceca38bb

Update --project-name in .github/workflows/docs.yml to match step 1.

3. Custom domain

  1. In Cloudflare Pages → your project → Custom domains → Add (e.g. <name>-docs.fueled.engineering)
  2. In Cloudflare DNS → fueled.engineering zone → Add CNAME: <name>-docs<project-name>.pages.dev (proxied)

4. Cloudflare Access (auth gate)

Cloudflare Zero Trust → Access → Applications → Add:

  • Type: Self-hosted
  • Application domain: <name>-docs.fueled.engineering
  • Policy: Allow → Emails ending in @fueled.com

This gates the entire site behind Google Workspace SSO. Add specific email addresses for client stakeholders.

Zensical config reference

Zensical reads standard mkdocs.yml. Key settings:

site_name: "Project Name"      # Tab title
docs_dir: docs/_build           # Source after merge script
site_dir: site                  # Output

theme:
  name: material                # Zensical is Material-compatible
  palette:                      # Light/dark mode toggle
    - scheme: default
      toggle: { icon: material/brightness-7 }
    - scheme: slate
      toggle: { icon: material/brightness-4 }
  features:
    - navigation.instant          # SPA-style page loads
    - navigation.instant.prefetch # Prefetch on hover
    - navigation.instant.progress # Loading progress bar
    - navigation.tabs             # Top-level sections as tabs
    - navigation.tabs.sticky      # Tabs stay visible on scroll
    - navigation.sections         # Collapsible nav groups
    - navigation.expand           # Auto-expand sidebar sections
    - navigation.path             # Breadcrumbs
    - navigation.top              # Back-to-top button
    - navigation.indexes          # Section index pages
    - search.suggest              # Autocomplete in search
    - search.highlight            # Search term highlighting
    - search.share                # Shareable search links
    - content.code.copy           # Copy button on code blocks
    - content.code.annotate       # Code annotations
    - content.tabs.link           # Synced content tabs
    - header.autohide             # Auto-hide header on scroll

plugins:
  - search                      # Built-in full-text search

markdown_extensions:
  - abbr                        # Glossary tooltips (via snippets)
  - admonition                  # Note/warning/tip boxes
  - attr_list                   # Grids, buttons
  - md_in_html                  # Markdown inside HTML blocks
  - pymdownx.superfences        # Mermaid diagrams, fenced code
  - pymdownx.highlight          # Code highlighting with line numbers
  - pymdownx.tabbed             # Content tabs
  - pymdownx.details            # Collapsible admonitions
  - pymdownx.tasklist           # Checkbox lists
  - pymdownx.snippets           # Reusable content includes
  - pymdownx.emoji              # Material icons in markdown
  - pymdownx.keys               # Keyboard key rendering
  - pymdownx.mark               # Highlighted text
  - pymdownx.smartsymbols       # Smart quotes, arrows, fractions

Full compatibility list: https://zensical.org/compatibility/features/

Glossary tooltips

Domain terms from docs/glossary.md automatically render as hover tooltips across all pages. The build script parses the glossary table and generates _build/_includes/abbreviations.md during assembly — no manual sync needed.

To add a tooltip: just add a row to docs/glossary.md. Next build picks it up.

Section index pages

Sections with navigation.indexes enabled use an index.md as the section landing page. These live at:

  • docs/reference/index.md — Reference section landing
  • docs/design/index.md — Design section landing
  • docs/guides/index.md — Guides section landing

Use Material's grid cards for visual navigation on these pages.

Agent instructions

When updating docs or .context/, remember: - Run ./scripts/docs-build.sh build to verify no build errors - Add new pages to nav: in mkdocs.yml - docs/_build/ is ephemeral — never edit files there directly - HTML files in docs/ (like design/data-model-plan.html) pass through as-is