What is GlowDoc?

GlowDoc is a modern, lightweight documentation template that presents a beautiful thoughtful space for your work. It's built with pure HTML, CSS, and minimal JavaScript to ensure fast loading times and easy customization.

Key Features

  • Modern Design - Clean, professional appearance with attention to typography and spacing
  • Dark Mode - Built-in dark mode support with smooth transitions
  • Responsive - Works perfectly on desktop, tablet, and mobile devices
  • Fast - Minimal dependencies and optimized for performance
  • Accessible - Built with accessibility best practices
  • Customizable - Easy to modify colors, fonts, and layout

Perfect For

GlowDoc is ideal for:

  • Project documentation
  • API documentation
  • User guides and tutorials
  • Knowledge bases
  • Technical blogs

Philosophy

We believe documentation should be beautiful, fast, and accessible. GlowDoc follows these principles by providing a clean, distraction-free reading experience that focuses on your content.

Quick Start

Get up and running with GlowDoc in minutes. This comprehensive guide will walk you through installation, setup, and creating your first professional documentation site.

Prerequisites

Before you begin, ensure you have the following installed:

Required Software

Rust (Latest Stable)

# Install Rust using rustup (recommended)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Follow the on-screen instructions, then reload your shell
source ~/.cargo/env

# Verify installation
rustc --version
cargo --version

Git

# Check if Git is installed
git --version

# If not installed:
# macOS: Install Xcode Command Line Tools
xcode-select --install

# Windows: Download from https://git-scm.com/download/win
# Linux (Ubuntu/Debian): sudo apt-get install git

Python 3 (for local testing)

# Check Python installation
python3 --version

# Python is usually pre-installed on macOS/Linux
# Windows: Download from https://python.org

System Requirements

  • Operating System: macOS, Linux, or Windows
  • RAM: 512MB minimum, 1GB recommended
  • Disk Space: 100MB for Rust toolchain + project files
  • Network: Internet connection for dependencies (initial setup only)

Installation Options

Choose the installation method that best fits your workflow:

Option 1: Download Release (Quickest)

  1. Download the latest release:

    # Download and extract (replace URL with actual release)
    curl -L https://github.com/username/glowdoc/archive/refs/heads/main.zip -o glowdoc.zip
    unzip glowdoc.zip
    cd glowdoc-main
    
  2. Build immediately:

    cargo run --release
    
  1. Clone the repository:

    git clone https://github.com/username/glowdoc.git
    cd glowdoc
    
  2. Build the documentation:

    cargo run --release
    

Option 3: Start Fresh Project

  1. Create new project directory:

    mkdir my-docs
    cd my-docs
    
  2. Copy GlowDoc source files:

    # Copy src/ and docs/ directories from GlowDoc
    # Copy Cargo.toml
    
  3. Initialize your documentation:

    cargo run init-config
    

Project Structure Overview

Understanding GlowDoc's structure helps you work effectively:

glowdoc/
├── Cargo.toml              # Rust project configuration
├── src/                    # Rust source code
│   ├── main.rs            # Main application logic
│   └── config_builder.rs   # Configuration builder
├── docs/                   # Your documentation source
│   ├── config.yaml        # Navigation configuration
│   ├── entry.md           # Homepage content (optional)
│   ├── introduction/      # Documentation sections
│   │   ├── quick-start.md
│   │   └── what-is-glowdoc.md
│   ├── getting-started/
│   │   ├── installation.md
│   │   ├── configuration.md
│   │   └── first-steps.md
│   └── [more-sections]/
├── index.html              # Generated documentation site
├── README.md              # Project information
└── .gitignore             # Git ignore rules

Key Directories

  • docs/: Your markdown documentation files
  • src/: GlowDoc's Rust source code (modify for customization)
  • index.html: Generated single-file documentation site

5-Minute Setup

Follow these steps to have a working documentation site in 5 minutes:

Step 1: Build Your First Site (1 minute)

# After installation, build immediately
cargo run --release

# You should see output like:
# "Building documentation..."
# "Generated index.html successfully"

Step 2: Preview Your Site (30 seconds)

# Start local server
python3 -m http.server 8000

# Open in browser
# Visit: http://localhost:8000

Alternative server options:

# Node.js users
npx serve .

# PHP users
php -S localhost:8000

# Python 2 users
python -m SimpleHTTPServer 8000

Step 3: Verify Everything Works (30 seconds)

Check these features in your browser:

  • Homepage loads correctly
  • Navigation sidebar works
  • Theme toggle (light/dark) functions
  • Search functionality operates
  • Mobile responsive design
  • All documentation pages display

Step 4: Customize Your Content (3 minutes)

  1. Update site information:

    # Edit docs/config.yaml
    vim docs/config.yaml  # or your preferred editor
    
    title: My Project Documentation
    description: Comprehensive guide for My Project
    theme: vibrant  # or 'default' or 'purple'
    
  2. Add your homepage content:

    # Edit docs/entry.md
    vim docs/entry.md
    
    # My Project Documentation
    
    Welcome to the comprehensive documentation for My Project.
    
    ## Getting Started
    
    Follow our guides to get up and running quickly.
    
  3. Add your first documentation page:

    # Create a new page
    echo "# My First Page\n\nThis is my first documentation page." > docs/introduction/my-first-page.md
    
  4. Rebuild and see changes:

    cargo run --release
    # Refresh your browser
    

Configuration Walkthrough

Let GlowDoc detect and configure your documentation structure automatically:

# Interactive configuration wizard
cargo run init-config

Example session:

GlowDoc Configuration Builder
============================

Scanning docs/ directory...
Found 3 sections: introduction, getting-started, advanced

Site title [GlowDoc]: My Project Docs
Description [modern docs for the modern world]: Complete guide for My Project
Theme [vibrant]: default

Detected sections:
1. introduction (2 files)
2. getting-started (3 files)  
3. advanced (2 files)

Would you like to reorder sections? [y/N]: y
Enter new order (comma-separated): introduction,getting-started,advanced

Configuration saved to docs/config.yaml
Backup created: docs/config.yaml.backup

Manual Configuration

For precise control, edit docs/config.yaml directly:

title: My Project Documentation
description: Everything you need to know about My Project
theme: vibrant

navigation:
  - title: Introduction
    id: introduction
    items:
      - title: Overview
        id: overview
        file: introduction/overview.md
      - title: Quick Start
        id: quick-start
        file: introduction/quick-start.md
  
  - title: User Guide
    id: user-guide
    items:
      - title: Installation
        id: installation
        file: guide/installation.md
      - title: Configuration
        id: configuration
        file: guide/configuration.md

Command-Line Configuration

For automated workflows, use CLI arguments:

# Complete automated setup
cargo run init-config \
  --title "My Project Docs" \
  --description "Comprehensive project documentation" \
  --section-order introduction,guide,api,advanced \
  --rename-section guide="User Guide" \
  --rename-section api="API Reference" \
  --page-order guide=installation.md,configuration.md,usage.md \
  --exclude-section drafts

Content Creation Guide

Writing Effective Documentation

Markdown Basics

GlowDoc supports GitHub-flavored markdown with extensions:

# Page Title (H1 - use only once per page)

## Section Heading (H2)

### Subsection (H3)

**Bold text** and *italic text*

- Bullet points
- Another item

1. Numbered lists
2. Sequential items

`inline code` and:

```javascript
// Code blocks with syntax highlighting
function example() {
  return "Hello, World!";
}

Blockquotes for important information

Links to other pages External links

TablesAreSupported
Cell 1Cell 2Cell 3

#### Page Structure Best Practices

```markdown
# Clear, Descriptive Page Title

Brief introduction paragraph explaining what this page covers.

## Main Concepts

Explain the core concepts first.

### Detailed Subsection

Break down complex topics into digestible sections.

## Examples

Provide practical examples:

```bash
# Command examples
cargo run --release

Next Steps

Guide readers to related pages or next actions.


### Organizing Your Content

#### Recommended Structure

docs/ ├── config.yaml ├── entry.md # Homepage content ├── introduction/ # High-level overview │ ├── overview.md # What is your project? │ ├── quick-start.md # This page │ └── concepts.md # Core concepts ├── guides/ # Step-by-step instructions │ ├── installation.md │ ├── configuration.md │ ├── first-project.md │ └── troubleshooting.md ├── reference/ # Detailed technical info │ ├── api.md │ ├── cli.md │ └── configuration-reference.md └── advanced/ # Advanced topics ├── customization.md ├── plugins.md └── deployment.md


#### Content Guidelines

1. **Start with user goals**: What does the reader want to accomplish?
2. **Use progressive disclosure**: Basic info first, details later
3. **Include examples**: Show, don't just tell
4. **Test your instructions**: Verify steps work as documented
5. **Update regularly**: Keep content current with your project

### Adding New Pages

1. **Create the markdown file:**
   ```bash
   # Create in appropriate section
   touch docs/guides/new-feature.md
  1. Add content with H1 title:

    # New Feature Guide
    
    This guide explains how to use the new feature.
    
  2. Update configuration:

    # Auto-detect and add to navigation
    cargo run init-config
    
    # Or manually edit docs/config.yaml
    
  3. Rebuild documentation:

    cargo run --release
    

Theme Customization

Built-in Themes

GlowDoc includes three professionally designed themes:

# In docs/config.yaml
theme: default  # Clean, professional
theme: purple   # Purple accents
theme: vibrant  # Colorful, energetic

Quick Theme Preview

# Try different themes quickly
sed -i 's/theme: .*/theme: purple/' docs/config.yaml && cargo run --release
sed -i 's/theme: .*/theme: vibrant/' docs/config.yaml && cargo run --release
sed -i 's/theme: .*/theme: default/' docs/config.yaml && cargo run --release

Dark Mode

All themes include automatic dark mode:

  • System preference detection: Respects user's OS setting
  • Manual toggle: Click the theme button in header
  • Persistent choice: Remembers user preference

Development Workflow

Efficient Development Loop

# 1. Edit your markdown files
vim docs/guides/new-page.md

# 2. Rebuild (takes ~1-3 seconds)
cargo run --release

# 3. Refresh browser (server keeps running)
# No need to restart python server

File Watching (Optional)

For automatic rebuilds on file changes:

# Install cargo-watch
cargo install cargo-watch

# Watch for changes and rebuild
cargo watch -x "run --release"

Version Control Integration

# Initialize git repository
git init

# Add files (excluding generated content)
git add .
git commit -m "Initial documentation setup"

# .gitignore should include:
echo "target/" >> .gitignore
echo "index.html" >> .gitignore  # Generated file

Testing Your Documentation

Pre-Deployment Checklist

# 1. Build successfully
cargo run --release

# 2. Check file size (should be reasonable)
ls -lh index.html

# 3. Validate HTML (optional)
# Install html-validate: npm install -g html-validate
html-validate index.html

# 4. Test locally
python3 -m http.server 8000

Manual Testing

Visit http://localhost:8000 and verify:

  • Navigation: All links work correctly
  • Search: Finds content in titles and text
  • Themes: Light/dark mode toggle works
  • Mobile: Sidebar collapses, navigation works
  • Content: All pages display properly
  • Links: Internal and external links function
  • Performance: Pages load quickly

Accessibility Testing

# Install axe-core CLI (optional)
npm install -g @axe-core/cli

# Test accessibility
axe http://localhost:8000

Common Issues and Solutions

Build Problems

"cargo: command not found"

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env

"No such file or directory: docs/config.yaml"

# Generate configuration
cargo run init-config

Build errors after editing config.yaml

# Validate YAML syntax
python3 -c "import yaml; yaml.safe_load(open('docs/config.yaml'))"

# Check file references exist
ls docs/introduction/quick-start.md

Server Issues

"Address already in use"

# Find and kill process using port 8000
lsof -ti:8000 | xargs kill

# Or use different port
python3 -m http.server 8080

Browser shows "No such file or directory"

# Ensure you're in the correct directory
ls index.html

# Rebuild if missing
cargo run --release

Content Problems

Page not appearing in navigation

# Ensure file is referenced in config.yaml
grep -r "filename.md" docs/config.yaml

# Or regenerate config
cargo run init-config

Search not finding content

# Rebuild to update search index
cargo run --release

# Check file has H1 heading
head -5 docs/section/page.md

Next Steps

Congratulations! You now have a working GlowDoc site. Here's what to explore next:

Immediate Actions

  1. Add Your Content

    • Replace sample content with your documentation
    • Update docs/entry.md with your project information
    • Add pages for your specific use cases
  2. Customize Appearance

    • Try different themes in config.yaml
    • Explore advanced styling options
    • Add your logo or branding
  3. Test Thoroughly

    • Verify all navigation works
    • Test search functionality
    • Check mobile responsiveness

Advanced Features

  1. Learn Configuration Management

    • Read the Configuration Guide
    • Understand navigation structure options
    • Explore CLI automation features
  2. Explore Customization

  3. Plan Deployment

  4. Extend Functionality

Community and Support

  • Documentation: Continue with First Steps
  • Examples: Browse sample configurations and setups
  • Issues: Report problems or request features
  • Contributions: Help improve GlowDoc

Pro Tips

  1. Keep It Simple: Start with basic setup, add complexity gradually
  2. Test Early: Preview changes frequently during development
  3. Version Control: Commit documentation changes regularly
  4. User Focus: Write for your audience, not yourself
  5. Iterate: Improve documentation based on user feedback

You're now ready to create professional, beautiful documentation with GlowDoc. Happy documenting!

First Steps

Now that you have GlowDoc installed, let's build your first documentation site step by step.

1. Initialize Your Project

Start by setting up the basic structure for your documentation:

# Create a new project directory
mkdir my-docs
cd my-docs

# Download or clone GlowDoc
# Then copy the src/ and docs/ folders to your project

2. Generate Your Configuration

Use the interactive config builder to set up your site structure:

# Interactive mode - walks you through setup
cargo run init-config

This will:

  • Scan any existing markdown files in docs/
  • Extract page titles from H1 headers
  • Generate a docs/config.yaml file
  • Create a backup of any existing configuration

Example Interactive Session

GlowDoc Configuration Builder
============================

Site title [GlowDoc]: My Project Documentation
Description [modern docs for the modern world]: Comprehensive guide for My Project

Found 3 sections in docs/:
  1. introduction (2 files)
  2. getting-started (3 files)  
  3. api (1 file)

Would you like to reorder sections? [y/N]: y
Enter section order (comma-separated): introduction,getting-started,api

Configuration saved to docs/config.yaml

3. Create Your Content

Homepage Content

Create or edit docs/entry.md for your homepage:

# My Project Documentation

Welcome to the comprehensive documentation for My Project.

## Getting Started

Follow our step-by-step guides to get up and running quickly.

## Key Features

- Feature 1: Description
- Feature 2: Description
- Feature 3: Description

Add Documentation Pages

Create markdown files in organized folders:

docs/
├── entry.md
├── config.yaml
├── introduction/
│   ├── overview.md
│   └── installation.md
├── guides/
│   ├── quick-start.md
│   ├── configuration.md
│   └── advanced-usage.md
└── reference/
    └── api.md

Each markdown file should start with an H1 header:

# Page Title

Your content here...

## Section

More content...

4. Start Development Server

For the best development experience, use the built-in development server with hot reload:

# Start development server (recommended)
cargo run watch

This will:

  • Build your documentation site
  • Start HTTP server at http://localhost:8000
  • Watch for file changes in docs/
  • Automatically rebuild and refresh your browser when files change
  • Serve images and static assets from your docs folder

Alternative: One-time Build

If you prefer to build once and serve with a separate server:

# Build the complete site once
cargo run --release

# Serve with any static server
python3 -m http.server 8000

Visit http://localhost:8000 to see your documentation site.

5. Add Images and Assets

Place images and other static files in your docs/ directory:

docs/
├── images/
│   ├── logo.png
│   └── screenshots/
│       └── demo.jpg
├── assets/
│   └── diagram.svg
└── getting-started/
    └── tutorial.md

Reference them in your markdown:

![Logo](images/logo.png)
![Demo Screenshot](images/screenshots/demo.jpg)
![Architecture](assets/diagram.svg)

The development server (cargo run watch) automatically serves these assets. Supported formats include:

  • Images: PNG, JPG, GIF, SVG, WebP
  • Documents: PDF, TXT, MD
  • Media: MP3, MP4, WebM
  • Fonts: WOFF, TTF, OTF

6. Customize the Appearance

Update Site Information

Edit docs/config.yaml to customize your site:

title: My Project Documentation
description: Everything you need to know about My Project
theme: vibrant  # or 'default'

Adjust Navigation

Reorder sections and pages by editing the navigation structure:

navigation:
  - title: Introduction
    id: introduction
    items:
      - title: Overview
        id: overview
        file: introduction/overview.md
      - title: Installation
        id: installation
        file: introduction/installation.md

Rebuild After Changes

With Development Server (Recommended):

  • Changes are automatically detected and applied
  • Browser refreshes automatically
  • No manual rebuilding needed

With Manual Builds:

cargo run --release

7. Development Workflow

Use the development server for the fastest workflow:

# Start development server
cargo run watch

# Then edit files in docs/ - changes appear instantly!

Features:

  • Instant rebuilds when you save files
  • Automatic browser refresh
  • Static asset serving (images, fonts, etc.)
  • Error reporting in console
  • Debounced updates (prevents duplicate builds)

Manual Build Workflow

For production builds or when you prefer manual control:

# 1. Edit markdown files in docs/
# 2. Rebuild the site
cargo run --release

# 3. Refresh browser to see changes
# (No need to restart the server)

Adding New Pages

With Development Server:

  1. Create the markdown file in the appropriate docs/ subfolder
  2. Run the config generator to update navigation:
    cargo run init-config
    
  3. The site rebuilds automatically - no manual rebuild needed!

With Manual Builds:

  1. Create the markdown file in the appropriate docs/ subfolder
  2. Run the config generator to update navigation:
    cargo run init-config
    
  3. Rebuild the site:
    cargo run --release
    

Reorganizing Content

Use CLI options for batch updates:

# Reorder sections and rename them
cargo run init-config \
  --section-order intro,guide,reference \
  --rename-section intro="Getting Started" \
  --rename-section guide="User Guide"

Next Steps

Now that you have a working documentation site:

  1. Explore Customization: Learn about theming and styling options
  2. Add More Content: Expand your documentation with additional pages
  3. Deploy Your Site: Set up hosting for your documentation
  4. Advanced Features: Explore plugins and advanced configuration

Common Tasks

Adding a New Section

  1. Create a new folder in docs/: mkdir docs/new-section
  2. Add markdown files to the folder
  3. Run cargo run init-config to detect the new section
  4. Rebuild: cargo run --release

Reordering Pages

cargo run init-config --page-order section=page1.md,page2.md,page3.md

Excluding Draft Content

cargo run init-config --exclude-section drafts

Custom Page Titles

Override auto-detected titles in docs/config.yaml:

- title: Custom Navigation Title
  id: page-id
  file: section/actual-filename.md

Troubleshooting

Build errors: Check that all files referenced in config.yaml exist and paths are correct.

Missing navigation: Ensure your markdown files have H1 headers and are included in the config.

Styling issues: Verify the theme setting in config.yaml and rebuild the site.

Server not accessible: Check that the server is running and try http://localhost:8000 instead of 127.0.0.1.

Installation

GlowDoc is designed to be simple to set up. Choose the method that works best for your workflow.

Download Template

The easiest way to get started is to download the template directly:

# Download and extract
wget https://github.com/paradise-runner/glowdoc/archive/main.zip
unzip main.zip
cd glowdoc-main

Clone Repository

If you prefer to clone the repository:

# Clone the repository
git clone https://github.com/paradise-runner/glowdoc.git
cd glowdoc

# Remove git history (optional)
rm -rf .git
git init

Use as Template

Create a new repository using GlowDoc as a template on GitHub, then clone your new repository.

Configuration

GlowDoc provides flexible configuration options to customize your documentation site. All configuration is managed through the docs/config.yaml file.

config.yaml Overview

The configuration file controls your site's structure, navigation, and appearance:

title: GlowDoc
description: modern docs for the modern world
theme: vibrant
navigation:
  - title: Introduction
    id: introduction
    items:
      - title: What is GlowDoc?
        id: what-is-glowdoc
        file: introduction/what-is-glowdoc.md

Auto-Generate Configuration

The easiest way to create or update your configuration is using the built-in generator:

Interactive Mode

cargo run init-config

This launches an interactive wizard that:

  • Scans your docs/ folder structure
  • Detects existing markdown files
  • Extracts page titles from H1 headers
  • Guides you through customization options
  • Backs up your existing config before generating a new one

Command-Line Mode

For automated workflows, use CLI arguments:

cargo run init-config \
  --title "My Project" \
  --description "Comprehensive project documentation" \
  --section-order introduction,guide,api,advanced \
  --rename-section guide="User Guide" \
  --rename-page guide/setup.md="Installation Guide" \
  --page-order guide=setup.md,configuration.md,usage.md \
  --exclude-section drafts

Available CLI Options

  • --title "Site Title" - Set the site title
  • --description "Description" - Set the site description
  • --section-order folder1,folder2 - Reorder sections by folder names
  • --rename-section old=new - Rename section titles in navigation
  • --rename-page section/file.md="New Title" - Override page titles
  • --page-order section=file1.md,file2.md - Reorder pages within sections
  • --exclude-section folder - Exclude folders from navigation
  • --help - Show complete usage guide

Manual Configuration

Basic Settings

title: Your Project Name
description: Brief description for SEO and page meta
theme: vibrant  # or 'default'

Navigation follows a hierarchical structure with sections and items:

navigation:
  - title: Section Name
    id: unique-section-id
    items:
      - title: Page Title
        id: unique-page-id
        file: folder/filename.md

Key Rules:

  • Section id must be unique across all sections
  • Page id must be unique across all pages
  • file path is relative to the docs/ folder
  • Pages are displayed in the order they appear in the config

Themes

GlowDoc includes built-in themes:

  • default - Clean, professional appearance
  • vibrant - Bold colors with enhanced contrast

File Organization

docs/
├── config.yaml          # Navigation configuration
├── entry.md            # Homepage content (optional)
├── introduction/
│   ├── overview.md
│   └── quick-start.md
├── guides/
│   ├── installation.md
│   └── configuration.md
└── reference/
    ├── api.md
    └── cli.md

Markdown Files

Each markdown file should start with an H1 header:

# Page Title

Content goes here...

The H1 title is automatically extracted during config generation and used as the default page title.

Advanced Configuration

Custom Page Titles

Override the auto-detected title from the markdown H1:

- title: Custom Page Title  # Shows in navigation
  id: custom-page
  file: section/actual-filename.md  # H1 in file can be different

Section Ordering

Control the order sections appear in navigation:

cargo run init-config --section-order introduction,tutorial,reference,advanced

Page Ordering

Control the order pages appear within each section:

cargo run init-config --page-order tutorial=setup.md,basics.md,advanced.md

Development Workflow

  1. Edit Configuration: Modify docs/config.yaml or use cargo run init-config
  2. Update Content: Edit markdown files in the docs/ folder
  3. Rebuild Site: Run cargo run --release to regenerate index.html
  4. Preview Changes: Use python3 -m http.server 8000 to serve locally

Troubleshooting

Common Issues

Config validation errors: Ensure all id fields are unique and all referenced files exist.

Missing pages: Check that file paths in config.yaml are correct and relative to the docs/ folder.

Build failures: Verify YAML syntax in config.yaml using a YAML validator.

Backup and Recovery

The config generator automatically creates backups:

  • docs/config.yaml.backup - Created before generating new config
  • Manual backup: cp docs/config.yaml docs/config.yaml.manual-backup

Theming

GlowDoc features a sophisticated theming system built on CSS custom properties, supporting multiple color schemes and seamless dark mode switching.

Built-in Themes

GlowDoc includes three professionally designed themes:

Default Theme

Clean, neutral design perfect for professional documentation:

# In docs/config.yaml
theme: default

Purple Theme

Purple-accented design with elegant color tones:

theme: purple

Vibrant Theme

Colorful, energetic design with bold accents:

theme: vibrant

Color System Architecture

GlowDoc uses a semantic color system with HSL values for precise color control and smooth transitions.

Core Color Properties

All themes use the same CSS custom property structure:

:root {
  /* Background colors */
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  
  /* Component backgrounds */
  --card: 0 0% 100%;
  --card-foreground: 222.2 84% 4.9%;
  --popover: 0 0% 100%;
  --popover-foreground: 222.2 84% 4.9%;
  
  /* Semantic colors */
  --primary: 222.2 47.4% 11.2%;
  --primary-foreground: 210 40% 98%;
  --secondary: 210 40% 96%;
  --secondary-foreground: 222.2 84% 4.9%;
  --muted: 210 40% 96%;
  --muted-foreground: 215.4 16.3% 46.9%;
  
  /* Interactive elements */
  --accent: 210 40% 96%;
  --accent-foreground: 222.2 84% 4.9%;
  --destructive: 0 84.2% 60.2%;
  --destructive-foreground: 210 40% 98%;
  
  /* UI elements */
  --border: 214.3 31.8% 91.4%;
  --input: 214.3 31.8% 91.4%;
  --ring: 222.2 84% 4.9%;
  --radius: 0.5rem;
}

Dark Mode Support

Each theme automatically includes dark mode variants:

[data-theme="dark"] {
  --background: 222.2 84% 4.9%;
  --foreground: 210 40% 98%;
  /* ... other dark mode overrides */
}

Dark Mode Features:

  • Automatic system preference detection
  • Manual toggle with LocalStorage persistence
  • Smooth 0.3s transitions between themes
  • Optimized contrast ratios for readability

Typography System

Font Stack

GlowDoc uses a carefully selected system font stack for optimal performance and cross-platform consistency:

font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", 
             Roboto, "Helvetica Neue", Arial, sans-serif;

Typography Scale

Homepage Typography:

  • Main Heading (H1): 3rem (48px), weight 800, gradient text effect
  • Section Headings (H2): 1.75rem (28px), weight 600
  • Body Text: 1.125rem (18px) for enhanced readability

Content Typography:

  • Page Titles (H1): 2.5rem (40px), weight 700
  • Section Headings (H2): 1.75rem (28px), weight 600
  • Body Text: 1rem (16px) for optimal reading
  • Navigation: 0.875rem (14px), weight 500-600
  • Code: 0.875rem (14px) monospace

Special Typography Effects

Gradient Text (Homepage):

background: linear-gradient(135deg, 
  hsl(var(--primary)), 
  hsl(var(--accent))
);
-webkit-background-clip: text;
color: transparent;

Spacing System

GlowDoc uses a consistent spacing scale based on rem units:

/* Spacing scale */
--space-1: 0.25rem;  /* 4px */
--space-2: 0.5rem;   /* 8px */
--space-3: 0.75rem;  /* 12px */
--space-4: 1rem;     /* 16px */
--space-6: 1.5rem;   /* 24px */
--space-8: 2rem;     /* 32px */
--space-16: 4rem;    /* 64px */

Common Usage:

  • Small margins: 0.25rem (4px)
  • Button padding: 0.5rem (8px)
  • Standard spacing: 1rem (16px)
  • Section gaps: 1.5rem (24px)
  • Content padding: 2rem (32px)
  • Large sections: 4rem (64px)

Custom Theme Creation

1. Modify Existing Theme

To customize an existing theme, you'll need to modify the CSS generation in the Rust source:

Location: src/main.rs in the generate_css() function

2. Color Customization

Update the HSL values for any theme:

:root {
  /* Change primary brand color */
  --primary: 220 70% 50%;  /* Blue instead of dark gray */
  --primary-foreground: 0 0% 100%;
  
  /* Adjust accent color */
  --accent: 160 60% 45%;   /* Teal accent */
  --accent-foreground: 0 0% 100%;
}

3. Typography Customization

Custom Font Integration:

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
}

Custom Font Sizes:

/* Larger base font size */
.main-content {
  font-size: 1.125rem;
  line-height: 1.75;
}

/* Custom heading sizes */
h1 { font-size: 3rem; }
h2 { font-size: 2rem; }
h3 { font-size: 1.5rem; }

Advanced Theming

Custom CSS Properties

Add your own custom properties for consistent theming:

:root {
  /* Custom brand colors */
  --brand-blue: 220 90% 56%;
  --brand-green: 142 71% 45%;
  --brand-orange: 25 95% 53%;
  
  /* Custom spacing */
  --content-width: 900px;
  --sidebar-width: 320px;
  
  /* Custom shadows */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
}

Responsive Design Variables

:root {
  --mobile-breakpoint: 768px;
  --sidebar-width: 280px;
  --mobile-padding: 1rem;
  --desktop-padding: 2rem;
}

@media (max-width: 768px) {
  .main-content {
    padding: var(--mobile-padding);
  }
}

Animation Customization

:root {
  /* Transition speeds */
  --transition-fast: 0.15s;
  --transition-normal: 0.2s;
  --transition-slow: 0.3s;
  
  /* Easing functions */
  --ease-out: cubic-bezier(0.0, 0.0, 0.2, 1);
  --ease-in-out: cubic-bezier(0.4, 0.0, 0.2, 1);
}

/* Apply to interactive elements */
.nav-link {
  transition: all var(--transition-normal) var(--ease-out);
}

Theme Implementation Details

Theme Switching Mechanism

GlowDoc implements theme switching through:

  1. Data attribute: data-theme="light|dark" on the <html> element
  2. JavaScript toggle: Smooth transitions between light/dark modes
  3. LocalStorage: Persistent user preference storage
  4. System detection: Automatic theme based on user's OS preference

Color Accessibility

All themes maintain WCAG AA contrast ratios:

  • Normal text: 4.5:1 contrast ratio
  • Large text: 3:1 contrast ratio
  • Interactive elements: Enhanced focus states

Performance Considerations

  • CSS custom properties enable instant theme switching
  • No additional HTTP requests for theme assets
  • Optimized for both light and dark viewing conditions
  • Smooth transitions without layout shifts

Troubleshooting

Theme not applying: Ensure the theme name in config.yaml matches exactly: default, purple, or vibrant.

Dark mode not working: Check that JavaScript is enabled and the browser supports CSS custom properties.

Custom colors not showing: Verify HSL values are properly formatted: 220 70% 50% (without hsl() wrapper).

Typography issues: Ensure font declarations come after the base stylesheet in the build process.

Components

GlowDoc is built with a comprehensive component system that provides consistent, accessible, and responsive UI elements throughout your documentation site.

Layout Components

Header Component

The main header provides navigation and theme switching functionality:

Structure:

<header class="header-content">
  <div class="container">
    <div class="logo">Site Title</div>
    <button class="theme-toggle" aria-label="Toggle theme">
      <!-- Theme toggle icon -->
    </button>
  </div>
</header>

Features:

  • Sticky positioning with backdrop blur effect
  • 80px fixed height
  • Responsive container with max-width of 1200px
  • Integrated theme toggle button

The collapsible sidebar houses the main navigation and search functionality:

Structure:

<aside class="sidebar">
  <div class="search-container">
    <input type="text" class="search-input" placeholder="Search...">
    <div class="search-results"></div>
  </div>
  
  <nav class="navigation">
    <div class="nav-section">
      <button class="nav-section-title">Section Name</button>
      <div class="nav-section-content">
        <a href="#page" class="nav-link">Page Title</a>
      </div>
    </div>
  </nav>
</aside>

Features:

  • Fixed 280px width on desktop
  • Collapsible sections with smooth animations
  • Integrated search with live results
  • Mobile-responsive with overlay behavior

Main Content Area

The primary content container with optimal reading layout:

Structure:

<main class="main-content">
  <div class="content-section" id="page-id">
    <h1>Page Title</h1>
    <p>Content goes here...</p>
  </div>
</main>

Features:

  • Flexible layout that grows to fill available space
  • 800px max-width for optimal reading
  • Responsive padding (2rem desktop, 1rem mobile)
  • Centered content with proper spacing

Individual navigation items with active state support:

CSS Classes:

.nav-link {
  /* Base navigation link styles */
  display: block;
  padding: 0.5rem 1rem;
  color: hsl(var(--muted-foreground));
  text-decoration: none;
  border-radius: 0.375rem;
  transition: all 0.2s ease;
}

.nav-link:hover {
  background-color: hsl(var(--accent));
  color: hsl(var(--accent-foreground));
}

.nav-link.active {
  background-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  font-weight: 600;
}

Usage:

  • Automatically marked as .active based on current page
  • Left border accent on hover and active states
  • Smooth color transitions
  • Accessible keyboard navigation

Section Headers

Collapsible section headers in the navigation:

Structure:

<button class="nav-section-title" data-section="section-id">
  <span>Section Name</span>
  <svg class="chevron-icon"><!-- Chevron icon --></svg>
</button>

Features:

  • Click to expand/collapse section content
  • Animated chevron icon rotation
  • Maintains expanded state in LocalStorage
  • Proper ARIA attributes for accessibility

Interactive Components

Theme Toggle

The dark/light mode switcher with system preference detection:

Structure:

<button class="theme-toggle" aria-label="Toggle theme">
  <svg class="sun-icon"><!-- Sun icon --></svg>
  <svg class="moon-icon"><!-- Moon icon --></svg>
</button>

Features:

  • Automatic system preference detection on first visit
  • Smooth icon transitions between light/dark states
  • LocalStorage persistence for user preference
  • 0.3s transition for theme switching

Search Component

Live search functionality with instant results:

Structure:

<div class="search-container">
  <div class="search-input-wrapper">
    <svg class="search-icon"><!-- Search icon --></svg>
    <input type="text" class="search-input" placeholder="Search documentation...">
  </div>
  <div class="search-results">
    <div class="search-result" data-target="page-id">
      <div class="search-result-title">Page Title</div>
      <div class="search-result-excerpt">Matching content...</div>
    </div>
  </div>
</div>

Features:

  • Real-time search as you type (300ms debounce)
  • Searches through all page titles and content
  • Highlighted search terms in results
  • Keyboard navigation support (arrow keys, Enter)
  • Click or Enter to navigate to results

Mobile Menu

Responsive navigation for mobile devices:

Structure:

<button class="mobile-menu-toggle">
  <span class="hamburger-line"></span>
  <span class="hamburger-line"></span>
  <span class="hamburger-line"></span>
</button>

Features:

  • Animated hamburger menu icon
  • Transforms sidebar into full-screen overlay
  • Smooth slide-in animation from left
  • Closes on backdrop click or page navigation

Content Components

Code Blocks

Syntax-highlighted code blocks with proper formatting:

Markdown Usage:

```javascript
function greetUser(name) {
  console.log(`Hello, ${name}!`);
}
```

Generated HTML:

<pre><code class="language-javascript">
function greetUser(name) {
  console.log(`Hello, ${name}!`);
}
</code></pre>

Features:

  • Automatic syntax highlighting via CSS
  • Consistent background and padding
  • Horizontal scrolling for long lines
  • Copy-friendly formatting

Content Sections

Organized content areas for each documentation page:

Structure:

<div class="content-section" id="unique-page-id">
  <h1>Page Title</h1>
  <p>Introduction paragraph...</p>
  
  <h2>Section Heading</h2>
  <p>Section content...</p>
</div>

Features:

  • Hidden by default (only active page shown)
  • Smooth fade-in transitions when activated
  • Proper heading hierarchy (H1 for page title, H2+ for sections)
  • Semantic HTML structure for accessibility

Search Result Highlighting

Dynamic highlighting of search terms in content:

Generated Markup:

<p>This is some <mark class="search-highlight">highlighted</mark> text.</p>

CSS Styling:

.search-highlight {
  background-color: hsl(var(--primary) / 0.2);
  color: hsl(var(--primary-foreground));
  padding: 0.125rem 0.25rem;
  border-radius: 0.25rem;
}

Responsive Behavior

Breakpoint System

GlowDoc uses a mobile-first approach with a single breakpoint:

/* Mobile styles (default) */
.sidebar {
  position: fixed;
  left: -100%;
  transition: left 0.3s ease;
}

/* Desktop styles */
@media (min-width: 768px) {
  .sidebar {
    position: fixed;
    left: 0;
  }
}

Mobile Adaptations

Sidebar Behavior:

  • Becomes full-screen overlay on mobile
  • Slide-in animation from left edge
  • Backdrop blur and dark overlay
  • Closes on outside click or page navigation

Content Layout:

  • Single-column layout on mobile
  • Reduced padding (1rem vs 2rem)
  • Optimized touch targets (44px minimum)
  • Larger font sizes for better readability

Navigation:

  • Collapsible sections remain functional
  • Touch-optimized interactive areas
  • Simplified hover states for touch devices

Accessibility Features

Keyboard Navigation

Navigation Support:

  • Tab order follows logical content flow
  • Arrow keys navigate search results
  • Enter key activates links and buttons
  • Escape key closes mobile menu and search

Focus Management:

  • Visible focus indicators on all interactive elements
  • Focus trapped within mobile menu when open
  • Focus restored when closing overlays

Screen Reader Support

ARIA Labels:

<button aria-label="Toggle theme" class="theme-toggle">
<input aria-label="Search documentation" class="search-input">
<nav aria-label="Main navigation" class="navigation">

Semantic Structure:

  • Proper heading hierarchy (H1 → H2 → H3)
  • Landmark roles for main sections
  • Descriptive link text
  • Form labels associated with inputs

Color and Contrast

WCAG AA Compliance:

  • 4.5:1 contrast ratio for normal text
  • 3:1 contrast ratio for large text
  • Enhanced focus states with both color and outline
  • Color is not the only means of conveying information

Performance Optimizations

CSS Architecture

Efficient Selectors:

  • Class-based selectors for performance
  • Minimal nesting depth
  • Optimized specificity

Transition Performance:

  • GPU-accelerated transforms
  • Efficient property animations (opacity, transform)
  • Reasonable transition durations (0.2s-0.3s)

JavaScript Optimization

Search Debouncing:

  • 300ms delay to reduce excessive searches
  • Efficient DOM queries using data attributes
  • Minimal DOM manipulation

Event Handling:

  • Event delegation for dynamic content
  • Passive event listeners where appropriate
  • Memory leak prevention

Customization Examples

Custom Navigation Styling

.nav-link {
  /* Add custom styles */
  border-left: 3px solid transparent;
  margin-bottom: 0.25rem;
}

.nav-link:hover {
  border-left-color: hsl(var(--primary));
  background: linear-gradient(90deg, 
    hsl(var(--primary) / 0.1), 
    transparent
  );
}

.nav-link.active {
  border-left-color: hsl(var(--primary));
  background-color: hsl(var(--primary) / 0.15);
}

Custom Search Styling

.search-container {
  /* Custom search appearance */
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: 0.75rem;
  padding: 1rem;
  margin-bottom: 1.5rem;
}

.search-input {
  /* Enhanced input styling */
  background: hsl(var(--background));
  border: 2px solid hsl(var(--border));
  border-radius: 0.5rem;
  padding: 0.75rem 1rem 0.75rem 2.5rem;
}

.search-input:focus {
  border-color: hsl(var(--primary));
  box-shadow: 0 0 0 3px hsl(var(--primary) / 0.1);
}

Custom Content Styling

.content-section {
  /* Enhanced content presentation */
  line-height: 1.75;
  max-width: 900px; /* Wider content area */
}

.content-section h1 {
  /* Custom heading styles */
  border-bottom: 2px solid hsl(var(--border));
  padding-bottom: 1rem;
  margin-bottom: 2rem;
}

.content-section h2 {
  /* Section heading enhancements */
  margin-top: 3rem;
  margin-bottom: 1.5rem;
  color: hsl(var(--primary));
}

This component system provides a solid foundation for building beautiful, functional documentation sites while maintaining consistency and accessibility across all interface elements.

Custom Styling

Advanced styling techniques and customization patterns for creating unique GlowDoc designs that match your brand and requirements.

Architecture Overview

GlowDoc's CSS architecture is designed for maximum customization while maintaining performance and accessibility. Understanding the core structure enables powerful customizations.

CSS Organization

The generated stylesheet follows this structure:

/* 1. CSS Reset & Base Styles */
/* 2. CSS Custom Properties (Design Tokens) */
/* 3. Layout Components */
/* 4. Navigation Components */
/* 5. Content Components */
/* 6. Interactive Components */
/* 7. Responsive Media Queries */
/* 8. Theme Variations */

Modification Approach

Since GlowDoc generates a single HTML file with embedded CSS, customizations should be added to the Rust source in the generate_css() function:

Location: src/main.rs - Look for the generate_css() function

Advanced Styling Techniques

Custom Brand Integration

Brand Color System

Create a comprehensive brand color palette:

:root {
  /* Primary brand colors */
  --brand-primary: 220 90% 56%;
  --brand-primary-dark: 220 90% 45%;
  --brand-primary-light: 220 90% 65%;
  
  /* Secondary brand colors */
  --brand-secondary: 160 60% 45%;
  --brand-accent: 25 95% 53%;
  --brand-neutral: 220 10% 50%;
  
  /* Semantic color mappings */
  --primary: var(--brand-primary);
  --accent: var(--brand-secondary);
  
  /* Brand gradients */
  --brand-gradient: linear-gradient(135deg, 
    hsl(var(--brand-primary)), 
    hsl(var(--brand-secondary))
  );
}

Logo and Brand Assets

Integrate custom logos and brand elements:

.logo {
  background-image: url('data:image/svg+xml;base64,...');
  background-size: contain;
  background-repeat: no-repeat;
  width: 120px;
  height: 40px;
  text-indent: -9999px; /* Hide text */
}

/* Alternative: Custom font logo */
.logo {
  font-family: 'Your Brand Font', sans-serif;
  font-weight: 700;
  font-size: 1.5rem;
  color: hsl(var(--brand-primary));
}

Advanced Layout Customizations

Multi-Column Content Layout

Create complex content layouts:

.content-section {
  display: grid;
  grid-template-columns: 1fr 300px;
  gap: 2rem;
  max-width: 1200px;
}

.content-main {
  min-width: 0; /* Prevent grid blowout */
}

.content-sidebar {
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: 0.5rem;
  padding: 1.5rem;
  height: fit-content;
  position: sticky;
  top: 100px; /* Account for header height */
}

@media (max-width: 1024px) {
  .content-section {
    grid-template-columns: 1fr;
  }
  
  .content-sidebar {
    order: -1; /* Move sidebar above content on mobile */
  }
}

Custom Navigation Layouts

Enhanced sidebar with custom sections:

.sidebar {
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 1rem;
}

.sidebar-header {
  padding: 1rem;
  border-bottom: 1px solid hsl(var(--border));
}

.sidebar-content {
  overflow-y: auto;
  padding: 0 1rem;
}

.sidebar-footer {
  padding: 1rem;
  border-top: 1px solid hsl(var(--border));
  background: hsl(var(--muted) / 0.5);
}

/* Custom navigation grouping */
.nav-group {
  margin-bottom: 2rem;
}

.nav-group-title {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: hsl(var(--muted-foreground));
  margin-bottom: 0.5rem;
  padding: 0 1rem;
}

Typography Enhancement

Custom Font Integration

Professional typography with web fonts:

/* Import custom fonts */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap');

:root {
  /* Typography system */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: 'JetBrains Mono', 'SF Mono', Consolas, monospace;
  
  /* Type scale */
  --text-xs: 0.75rem;    /* 12px */
  --text-sm: 0.875rem;   /* 14px */
  --text-base: 1rem;     /* 16px */
  --text-lg: 1.125rem;   /* 18px */
  --text-xl: 1.25rem;    /* 20px */
  --text-2xl: 1.5rem;    /* 24px */
  --text-3xl: 1.875rem;  /* 30px */
  --text-4xl: 2.25rem;   /* 36px */
  --text-5xl: 3rem;      /* 48px */
}

body {
  font-family: var(--font-sans);
}

code, pre {
  font-family: var(--font-mono);
}

Advanced Typography Styles

Rich text formatting and hierarchy:

.content-section {
  /* Enhanced reading experience */
  font-size: var(--text-lg);
  line-height: 1.7;
  color: hsl(var(--foreground));
}

.content-section h1 {
  font-size: var(--text-4xl);
  font-weight: 800;
  line-height: 1.1;
  margin-bottom: 1.5rem;
  background: var(--brand-gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.content-section h2 {
  font-size: var(--text-2xl);
  font-weight: 700;
  margin-top: 3rem;
  margin-bottom: 1rem;
  position: relative;
}

.content-section h2::before {
  content: '';
  position: absolute;
  left: -2rem;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 1.5rem;
  background: hsl(var(--primary));
  border-radius: 2px;
}

/* Enhanced blockquotes */
.content-section blockquote {
  border-left: 4px solid hsl(var(--primary));
  padding-left: 1.5rem;
  margin: 2rem 0;
  font-style: italic;
  font-size: var(--text-xl);
  color: hsl(var(--muted-foreground));
}

/* Improved lists */
.content-section ul {
  list-style: none;
  padding-left: 0;
}

.content-section li {
  position: relative;
  padding-left: 1.5rem;
  margin-bottom: 0.5rem;
}

.content-section li::before {
  content: '→';
  position: absolute;
  left: 0;
  color: hsl(var(--primary));
  font-weight: 600;
}

Interactive Element Enhancements

Advanced Button Styling

Custom button system with multiple variants:

/* Button base styles */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1.5rem;
  border: none;
  border-radius: 0.5rem;
  font-weight: 600;
  font-size: var(--text-sm);
  text-decoration: none;
  cursor: pointer;
  transition: all 0.2s ease;
  position: relative;
  overflow: hidden;
}

/* Primary button */
.btn-primary {
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
}

.btn-primary:hover {
  background: hsl(var(--primary) / 0.9);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px hsl(var(--primary) / 0.3);
}

/* Gradient button */
.btn-gradient {
  background: var(--brand-gradient);
  color: white;
  position: relative;
}

.btn-gradient::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--brand-gradient);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.btn-gradient:hover::before {
  opacity: 0.1;
}

/* Outline button */
.btn-outline {
  background: transparent;
  border: 2px solid hsl(var(--primary));
  color: hsl(var(--primary));
}

.btn-outline:hover {
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
}

Enhanced Form Styling

Professional form controls:

.form-group {
  margin-bottom: 1.5rem;
}

.form-label {
  display: block;
  font-weight: 600;
  font-size: var(--text-sm);
  color: hsl(var(--foreground));
  margin-bottom: 0.5rem;
}

.form-input {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 2px solid hsl(var(--border));
  border-radius: 0.5rem;
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  font-size: var(--text-base);
  transition: all 0.2s ease;
}

.form-input:focus {
  outline: none;
  border-color: hsl(var(--primary));
  box-shadow: 0 0 0 3px hsl(var(--primary) / 0.1);
}

.form-input::placeholder {
  color: hsl(var(--muted-foreground));
}

Animation and Micro-Interactions

Page Transition Effects

Smooth page transitions:

.content-section {
  opacity: 0;
  transform: translateY(20px);
  transition: all 0.3s ease;
}

.content-section.active {
  opacity: 1;
  transform: translateY(0);
}

/* Staggered animation for navigation items */
.nav-link {
  opacity: 0;
  transform: translateX(-20px);
  animation: slideInLeft 0.3s ease forwards;
}

.nav-link:nth-child(1) { animation-delay: 0.1s; }
.nav-link:nth-child(2) { animation-delay: 0.15s; }
.nav-link:nth-child(3) { animation-delay: 0.2s; }
/* ... continue pattern */

@keyframes slideInLeft {
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

Hover Effects and Micro-Interactions

Engaging interactive feedback:

/* Card hover effects */
.card {
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: 0.75rem;
  padding: 1.5rem;
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(45deg, 
    hsl(var(--primary) / 0.1), 
    hsl(var(--accent) / 0.1)
  );
  opacity: 0;
  transition: opacity 0.3s ease;
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 24px hsl(var(--foreground) / 0.1);
  border-color: hsl(var(--primary));
}

.card:hover::before {
  opacity: 1;
}

/* Ripple effect for buttons */
.btn {
  position: relative;
  overflow: hidden;
}

.btn::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.3);
  transform: translate(-50%, -50%);
  transition: width 0.6s, height 0.6s;
}

.btn:active::after {
  width: 300px;
  height: 300px;
}

Responsive Design Patterns

Advanced Responsive Typography

Fluid typography that scales smoothly:

:root {
  /* Fluid typography using clamp() */
  --text-fluid-sm: clamp(0.875rem, 0.8rem + 0.375vw, 1rem);
  --text-fluid-base: clamp(1rem, 0.9rem + 0.5vw, 1.125rem);
  --text-fluid-lg: clamp(1.125rem, 1rem + 0.625vw, 1.25rem);
  --text-fluid-xl: clamp(1.25rem, 1.1rem + 0.75vw, 1.5rem);
  --text-fluid-2xl: clamp(1.5rem, 1.3rem + 1vw, 2rem);
  --text-fluid-3xl: clamp(1.875rem, 1.5rem + 1.875vw, 2.5rem);
  --text-fluid-4xl: clamp(2.25rem, 1.8rem + 2.25vw, 3rem);
}

body {
  font-size: var(--text-fluid-base);
}

h1 { font-size: var(--text-fluid-4xl); }
h2 { font-size: var(--text-fluid-3xl); }
h3 { font-size: var(--text-fluid-2xl); }

Container Queries (Future-Forward)

Modern responsive design using container queries:

.content-section {
  container-type: inline-size;
}

/* Adjust layout based on container width, not viewport */
@container (min-width: 600px) {
  .content-grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 2rem;
  }
}

@container (min-width: 900px) {
  .content-grid {
    grid-template-columns: 1fr 2fr 1fr;
  }
}

Dark Mode Advanced Customizations

Theme-Aware Components

Components that adapt intelligently to theme changes:

/* Light theme specific styles */
[data-theme="light"] .hero-section {
  background: linear-gradient(135deg, 
    hsl(var(--background)), 
    hsl(var(--secondary))
  );
}

/* Dark theme specific styles */
[data-theme="dark"] .hero-section {
  background: linear-gradient(135deg, 
    hsl(var(--background)), 
    hsl(var(--card))
  );
}

/* Theme-aware shadows */
.elevated-card {
  box-shadow: 
    0 4px 6px hsl(var(--foreground) / 0.1),
    0 1px 3px hsl(var(--foreground) / 0.05);
}

[data-theme="dark"] .elevated-card {
  box-shadow: 
    0 4px 6px rgba(0, 0, 0, 0.3),
    0 1px 3px rgba(0, 0, 0, 0.2);
}

Performance Optimization

Efficient CSS Architecture

Optimized styles for better performance:

/* Use CSS custom properties for frequently changing values */
:root {
  --animation-speed: 0.2s;
  --animation-easing: cubic-bezier(0.4, 0, 0.2, 1);
}

/* Optimize animations for 60fps */
.animated-element {
  will-change: transform, opacity;
  transform: translateZ(0); /* Force hardware acceleration */
  transition: transform var(--animation-speed) var(--animation-easing);
}

/* Efficient selectors */
.nav-link { /* Good: class selector */ }
nav > ul > li > a { /* Avoid: deep nesting */ }
* { /* Avoid: universal selector */ }

Critical CSS Patterns

Inline critical styles for immediate rendering:

/* Critical above-the-fold styles */
.layout,
.header-content,
.sidebar,
.main-content {
  /* Essential layout properties only */
  display: flex;
  position: relative;
}

/* Non-critical styles can be loaded later */
.fancy-animations,
.decorative-elements {
  /* Complex animations and decorative styles */
}

Custom Styling Workflow

1. Planning Your Customizations

Before modifying styles:

  1. Audit existing styles: Understand the current CSS architecture
  2. Define your design system: Colors, typography, spacing, components
  3. Plan responsive behavior: Mobile-first approach
  4. Consider accessibility: Maintain contrast ratios and focus states

2. Implementation Strategy

Recommended approach:

  1. Start with CSS custom property overrides
  2. Add new component styles
  3. Implement responsive variations
  4. Test across themes (light/dark)
  5. Validate accessibility compliance

3. Testing Checklist

  • All themes (default, purple, vibrant)
  • Light and dark modes
  • Mobile and desktop layouts
  • Keyboard navigation
  • Screen reader compatibility
  • Performance impact

Troubleshooting Custom Styles

Styles not applying: Check CSS specificity and ensure your styles come after the base styles in the build order.

Theme conflicts: Verify that custom styles work with both light and dark modes.

Performance issues: Minimize complex selectors and excessive animations.

Responsive problems: Test on actual devices, not just browser dev tools.

Accessibility concerns: Use tools like axe-core to validate accessibility compliance.

API Reference

Comprehensive JavaScript API reference for programmatic control and customization of GlowDoc documentation sites.

Overview

GlowDoc generates a single-page application with a rich JavaScript API for navigation, search, theming, and customization. All functionality is embedded within the generated HTML file, providing a complete client-side documentation experience.

Core Navigation API

showContent(contentId, updateUrl = true)

Displays a specific documentation page by content ID.

Parameters:

  • contentId (string) - The unique identifier for the content section
  • updateUrl (boolean, optional) - Whether to update browser URL and history (default: true)

Returns: void

Example:

// Show the installation page
showContent('installation');

// Show content without updating URL (for programmatic navigation)
showContent('api-reference', false);

Behavior:

  • Switches from homepage to documentation layout if needed
  • Hides all content sections and displays the target section
  • Updates active state in navigation sidebar
  • Updates browser URL and history (unless updateUrl is false)
  • Automatically closes mobile sidebar
  • Logs content display for debugging

showHomepage()

Displays the homepage content and hides documentation layout.

Parameters: None
Returns: void

Example:

// Return to homepage
showHomepage();

Behavior:

  • Shows homepage element, hides documentation layout
  • Updates browser URL to root path
  • Uses HTML5 History API for navigation

showDocs()

Switches the interface to documentation mode (internal function).

Parameters: None
Returns: void

Usage: Typically called internally by showContent(), but available for custom implementations.

showContentFromSearch(contentId)

Displays content selected from search results and clears search state.

Parameters:

  • contentId (string) - The content ID to display

Returns: void

Example:

// Show search result and clear search
showContentFromSearch('quick-start');

Behavior:

  • Clears search input field
  • Hides search results, shows navigation
  • Calls showContent() to display the selected page

Theme Management API

toggleTheme()

Toggles between light and dark theme modes.

Parameters: None
Returns: void

Example:

// Toggle theme
toggleTheme();

// Programmatically check current theme
const currentTheme = document.documentElement.getAttribute('data-theme');
console.log('Current theme:', currentTheme); // 'light' or 'dark'

Behavior:

  • Toggles data-theme attribute between 'light' and 'dark'
  • Saves theme preference to localStorage
  • Provides smooth transitions via CSS
  • Respects system preferences on first visit

Theme Persistence:

// Theme is automatically saved to localStorage
localStorage.getItem('theme'); // Returns 'light' or 'dark'

toggleSidebar()

Toggles sidebar visibility (primarily for mobile interfaces).

Parameters: None
Returns: void

Example:

// Toggle mobile sidebar
toggleSidebar();

// Check sidebar state
const sidebar = document.querySelector('.sidebar');
const isVisible = sidebar.classList.contains('visible');

Behavior:

  • Toggles 'visible' class on sidebar element
  • Provides slide-in animation on mobile devices
  • Automatically handled for responsive breakpoints

toggleSection(sectionId)

Expands or collapses navigation sections in the sidebar.

Parameters:

  • sectionId (string) - The ID of the section to toggle

Returns: void

Example:

// Toggle a navigation section
toggleSection('getting-started');

// Check section state
const section = document.querySelector('[data-section="getting-started"]');
const isCollapsed = section.classList.contains('collapsed');

Behavior:

  • Toggles 'collapsed' class on section and its toggle icon
  • Provides smooth expand/collapse animations
  • State persisted for user experience

Search API

performSearch()

Performs real-time search across all documentation content.

Parameters: None (reads from search input element)
Returns: void

Example:

// Trigger search programmatically
document.querySelector('.search-input').value = 'installation';
performSearch();

// Search is automatically triggered on input

Search Features:

  • Real-time Results: Updates as user types
  • Content Indexing: Searches titles, sections, and full content
  • Result Ranking: Title matches rank higher than content matches
  • Snippet Generation: Shows relevant content excerpts
  • Keyword Highlighting: Highlights matching terms in results

Search Index Structure:

// Global searchIndex object
const searchIndex = {
  "page-id": {
    "title": "Page Title",
    "section": "Section Name",
    "content": "Full searchable content..."
  }
  // ... more pages
};

Custom Search Integration

// Access search index for custom functionality
function customSearch(query) {
  const results = [];
  for (const [id, data] of Object.entries(searchIndex)) {
    if (data.title.toLowerCase().includes(query.toLowerCase())) {
      results.push({ id, ...data });
    }
  }
  return results;
}

// Example: Find all pages in a specific section
function findBySection(sectionName) {
  return Object.entries(searchIndex)
    .filter(([id, data]) => data.section === sectionName)
    .map(([id, data]) => ({ id, ...data }));
}

URL and History Management

loadFromUrl()

Loads appropriate content based on current URL hash.

Parameters: None
Returns: void

Example:

// Load content based on URL
loadFromUrl();

// Handle URL changes
window.addEventListener('hashchange', loadFromUrl);

URL Format:

  • Homepage: # or no hash
  • Content pages: #page-id
  • Automatically handles invalid page IDs

History Management:

// Navigation automatically updates browser history
// Back/forward buttons work seamlessly
window.addEventListener('popstate', (event) => {
  if (event.state?.contentId) {
    showContent(event.state.contentId, false);
  } else if (event.state?.page === 'home') {
    showHomepage();
  }
});

Event System

Built-in Event Listeners

GlowDoc automatically registers several event listeners:

// Navigation clicks
document.addEventListener('click', (e) => {
  if (e.target.hasAttribute('data-content-id')) {
    e.preventDefault();
    showContent(e.target.getAttribute('data-content-id'));
  }
});

// Browser navigation
window.addEventListener('popstate', (event) => {
  // Handle back/forward navigation
});

// Initial load
document.addEventListener('DOMContentLoaded', () => {
  loadFromUrl();
});

// Mobile sidebar - outside clicks
document.addEventListener('click', (e) => {
  // Close sidebar when clicking outside on mobile
});

Custom Event Handling

// Listen for content changes
function onContentChange(contentId) {
  console.log('Content changed to:', contentId);
  // Custom logic here
}

// Override or extend existing functions
const originalShowContent = showContent;
showContent = function(contentId, updateUrl = true) {
  onContentChange(contentId);
  return originalShowContent(contentId, updateUrl);
};

Configuration and Customization

Global Configuration

// Access current state
const getCurrentContent = () => {
  const activeSection = document.querySelector('.content-section:not([style*="display: none"])');
  return activeSection?.id;
};

const getCurrentTheme = () => {
  return document.documentElement.getAttribute('data-theme');
};

// Get navigation state
const getNavigationState = () => {
  const collapsedSections = Array.from(document.querySelectorAll('.nav-section.collapsed'))
    .map(section => section.dataset.section);
  return { collapsedSections };
};

DOM Element Access

Required Elements:

// Core layout elements
const homepage = document.getElementById('homepage');
const docsLayout = document.getElementById('docs-layout');
const sidebar = document.querySelector('.sidebar');

// Search elements
const searchInput = document.querySelector('.search-input');
const searchResults = document.querySelector('.search-results');
const searchResultsList = document.querySelector('.search-results-list');

// Navigation elements
const navigationContainer = document.querySelector('.navigation-container');
const contentSections = document.querySelectorAll('.content-section');
const navLinks = document.querySelectorAll('.nav-link');

Data Attributes:

  • data-content-id: Links navigation items to content sections
  • data-section: Identifies collapsible navigation sections
  • data-theme: Current theme state on document element

Advanced Customization

Custom Navigation

// Add custom navigation item
function addCustomNavItem(sectionId, title, contentId) {
  const navSection = document.querySelector(`[data-section="${sectionId}"] .nav-section-content`);
  if (navSection) {
    const link = document.createElement('a');
    link.href = `#${contentId}`;
    link.className = 'nav-link';
    link.setAttribute('data-content-id', contentId);
    link.textContent = title;
    navSection.appendChild(link);
  }
}

// Custom content injection
function addCustomContent(contentId, title, htmlContent) {
  const contentSection = document.createElement('div');
  contentSection.className = 'content-section';
  contentSection.id = contentId;
  contentSection.style.display = 'none';
  contentSection.innerHTML = `<h1>${title}</h1>${htmlContent}`;
  
  document.querySelector('.main-content').appendChild(contentSection);
  
  // Add to search index
  searchIndex[contentId] = {
    title: title,
    section: 'Custom',
    content: contentSection.textContent
  };
}

Theme Customization

// Custom theme switching
function setCustomTheme(themeName) {
  document.documentElement.setAttribute('data-theme', themeName);
  localStorage.setItem('theme', themeName);
}

// Theme change detection
const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    if (mutation.attributeName === 'data-theme') {
      const newTheme = document.documentElement.getAttribute('data-theme');
      console.log('Theme changed to:', newTheme);
      // Custom theme change logic
    }
  });
});

observer.observe(document.documentElement, {
  attributes: true,
  attributeFilter: ['data-theme']
});

Search Customization

// Custom search implementation
function customPerformSearch() {
  const query = document.querySelector('.search-input').value.toLowerCase().trim();
  const resultsContainer = document.querySelector('.search-results-list');
  
  if (!query) {
    // Hide search results
    document.querySelector('.search-results').style.display = 'none';
    document.querySelector('.navigation-container').style.display = 'block';
    return;
  }
  
  const results = [];
  
  // Custom search logic
  for (const [id, data] of Object.entries(searchIndex)) {
    let score = 0;
    
    // Title match (highest priority)
    if (data.title.toLowerCase().includes(query)) score += 10;
    
    // Section match (medium priority)
    if (data.section.toLowerCase().includes(query)) score += 5;
    
    // Content match (lower priority)
    if (data.content.toLowerCase().includes(query)) score += 1;
    
    if (score > 0) {
      results.push({ id, ...data, score });
    }
  }
  
  // Sort by score (descending)
  results.sort((a, b) => b.score - a.score);
  
  // Display results
  displaySearchResults(results, query);
}

function displaySearchResults(results, query) {
  const resultsContainer = document.querySelector('.search-results-list');
  
  if (results.length === 0) {
    resultsContainer.innerHTML = '<div class="no-results">No results found</div>';
  } else {
    resultsContainer.innerHTML = results.map(result => {
      const snippet = generateSnippet(result.content, query);
      return `
        <div class="search-result" onclick="showContentFromSearch('${result.id}')">
          <div class="search-result-title">${highlightText(result.title, query)}</div>
          <div class="search-result-section">${result.section}</div>
          <div class="search-result-snippet">${snippet}</div>
        </div>
      `;
    }).join('');
  }
  
  // Show search results
  document.querySelector('.search-results').style.display = 'block';
  document.querySelector('.navigation-container').style.display = 'none';
}

function generateSnippet(content, query, maxLength = 150) {
  const queryIndex = content.toLowerCase().indexOf(query.toLowerCase());
  if (queryIndex === -1) {
    return content.substring(0, maxLength) + (content.length > maxLength ? '...' : '');
  }
  
  const start = Math.max(0, queryIndex - 50);
  const end = Math.min(content.length, queryIndex + query.length + 50);
  const snippet = content.substring(start, end);
  
  return (start > 0 ? '...' : '') + 
         highlightText(snippet, query) + 
         (end < content.length ? '...' : '');
}

function highlightText(text, query) {
  const regex = new RegExp(`(${query})`, 'gi');
  return text.replace(regex, '<mark class="search-highlight">$1</mark>');
}

Performance and Optimization

// Implement search debouncing
let searchTimeout;
function debouncedSearch() {
  clearTimeout(searchTimeout);
  searchTimeout = setTimeout(performSearch, 300);
}

// Replace default search input handler
document.querySelector('.search-input').addEventListener('input', debouncedSearch);

Lazy Loading

// Lazy load content sections
const observerOptions = {
  root: null,
  rootMargin: '100px',
  threshold: 0.1
};

const contentObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // Load heavy content when section becomes visible
      loadSectionAssets(entry.target);
    }
  });
}, observerOptions);

// Observe all content sections
document.querySelectorAll('.content-section').forEach(section => {
  contentObserver.observe(section);
});

Error Handling and Debugging

Debug Mode

// Enable debug mode
window.GLOWDOC_DEBUG = true;

// Enhanced showContent with debugging
function debugShowContent(contentId, updateUrl = true) {
  if (window.GLOWDOC_DEBUG) {
    console.log('Showing content:', contentId);
    console.log('Available content IDs:', Object.keys(searchIndex));
    console.log('Update URL:', updateUrl);
  }
  
  const contentElement = document.getElementById(contentId);
  if (!contentElement) {
    console.error(`Content element with ID '${contentId}' not found`);
    return;
  }
  
  return showContent(contentId, updateUrl);
}

Error Recovery

// Handle missing content gracefully
function safeShowContent(contentId, fallbackId = 'introduction') {
  const contentElement = document.getElementById(contentId);
  if (!contentElement) {
    console.warn(`Content '${contentId}' not found, showing fallback`);
    return showContent(fallbackId);
  }
  return showContent(contentId);
}

// Validate navigation state
function validateNavigation() {
  const issues = [];
  
  // Check for orphaned navigation links
  document.querySelectorAll('[data-content-id]').forEach(link => {
    const contentId = link.getAttribute('data-content-id');
    if (!document.getElementById(contentId)) {
      issues.push(`Navigation link points to missing content: ${contentId}`);
    }
  });
  
  // Check for content without navigation
  document.querySelectorAll('.content-section').forEach(section => {
    const contentId = section.id;
    const navLink = document.querySelector(`[data-content-id="${contentId}"]`);
    if (!navLink) {
      issues.push(`Content section has no navigation link: ${contentId}`);
    }
  });
  
  return issues;
}

Browser Compatibility

Supported Features:

  • ES6+ JavaScript (const, let, arrow functions, template literals)
  • HTML5 History API
  • CSS Custom Properties
  • LocalStorage
  • Modern DOM APIs

Minimum Browser Versions:

  • Chrome 49+
  • Firefox 44+
  • Safari 10+
  • Edge 12+

Graceful Degradation:

// Feature detection
if (!window.history?.pushState) {
  console.warn('History API not supported, using hash navigation');
  // Fallback to hash-based navigation
}

if (!window.localStorage) {
  console.warn('LocalStorage not supported, theme preference will not persist');
  // Use session-based theme storage
}

This comprehensive API reference provides complete control over GlowDoc's functionality, enabling deep customization while maintaining the system's performance and user experience benefits.

Deployment

Comprehensive guide to deploying your GlowDoc documentation site across various hosting platforms, from simple static hosting to advanced CI/CD pipelines.

Overview

GlowDoc generates a single index.html file containing your entire documentation site, making deployment simple and flexible. This approach offers several advantages:

  • Single File Deployment: No complex directory structures or dependencies
  • Universal Compatibility: Works with any static hosting service
  • Fast Loading: All assets embedded, no additional HTTP requests
  • Easy Backup: Single file contains everything
  • CDN Friendly: Perfect for content delivery networks

Pre-Deployment Checklist

Before deploying your documentation:

1. Build Verification

# Build your documentation
cargo run --release

# Verify the build succeeded
ls -la index.html

# Test locally
python3 -m http.server 8000
# Visit http://localhost:8000 to verify everything works

2. Content Review

  • All pages load correctly
  • Navigation works properly
  • Search functionality operates
  • All themes (light/dark) display correctly
  • Mobile responsive design works
  • All links are functional

3. Performance Optimization

# Check file size (typical range: 500KB - 2MB)
du -h index.html

# Optional: Minify if needed (for very large sites)
# Note: GlowDoc output is already optimized

Static Hosting Platforms

GitHub Pages

Deploy directly from your GitHub repository with automated builds.

Create .github/workflows/deploy.yml:

name: Deploy GlowDoc

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
    
    - name: Cache Cargo dependencies
      uses: actions/cache@v3
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
    
    - name: Build documentation
      run: cargo run --release
    
    - name: Deploy to GitHub Pages
      uses: peaceiris/actions-gh-pages@v3
      if: github.ref == 'refs/heads/main'
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: .
        publish_branch: gh-pages
        force_orphan: true
        enable_jekyll: false
        exclude_assets: |
          .github
          .gitignore
          Cargo.toml
          Cargo.lock
          src
          docs
          target
          README.md

Method 2: Manual Upload

# Build locally
cargo run --release

# Create gh-pages branch
git checkout --orphan gh-pages
git rm -rf .
git add index.html
git commit -m "Deploy documentation"
git push origin gh-pages

# Return to main branch
git checkout main

GitHub Pages Configuration

  1. Go to your repository → Settings → Pages
  2. Set Source to "Deploy from a branch"
  3. Select gh-pages branch
  4. Choose / (root) folder
  5. Save settings

Custom Domain Setup:

# Add CNAME file to repository root
echo "docs.yoursite.com" > CNAME
git add CNAME
git commit -m "Add custom domain"
git push

Netlify

Professional hosting with advanced features and global CDN.

  1. Connect Repository:

    • Sign up at netlify.com
    • Click "New site from Git"
    • Connect your GitHub/GitLab repository
  2. Build Configuration:

    # netlify.toml
    [build]
      command = "cargo run --release"
      publish = "."
    
    [build.environment]
      RUST_VERSION = "1.70"
    
    [[headers]]
      for = "/*"
      [headers.values]
        X-Frame-Options = "DENY"
        X-XSS-Protection = "1; mode=block"
        X-Content-Type-Options = "nosniff"
        Referrer-Policy = "strict-origin-when-cross-origin"
    
    [[redirects]]
      from = "/docs/*"
      to = "/#:splat"
      status = 200
    
  3. Deploy Settings:

    • Build command: cargo run --release
    • Publish directory: . (root)
    • Node version: Latest LTS

Method 2: Manual Upload

# Build documentation
cargo run --release

# Deploy via Netlify CLI
npm install -g netlify-cli
netlify login
netlify deploy --prod --dir=.

Advanced Netlify Features

Form Handling:

<!-- Add to your documentation for feedback forms -->
<form name="feedback" method="POST" data-netlify="true">
  <input type="hidden" name="form-name" value="feedback" />
  <input type="text" name="name" placeholder="Your name" required />
  <textarea name="message" placeholder="Feedback" required></textarea>
  <button type="submit">Send Feedback</button>
</form>

Analytics Integration:

// Add to your custom JavaScript
if (window.netlifyIdentity) {
  window.netlifyIdentity.on('init', user => {
    if (!user) {
      window.netlifyIdentity.on('login', () => {
        document.location.href = '/admin/';
      });
    }
  });
}

Vercel

Zero-configuration deployment with excellent performance.

Method 1: Git Integration

  1. Connect Repository:

    • Sign up at vercel.com
    • Import your Git repository
    • Vercel auto-detects the setup
  2. Configuration File:

    {
      "version": 2,
      "name": "glowdoc-docs",
      "builds": [
        {
          "src": "package.json",
          "use": "@vercel/static-build"
        }
      ],
      "routes": [
        {
          "src": "/(.*)",
          "dest": "/index.html"
        }
      ],
      "env": {
        "RUST_VERSION": "1.70"
      }
    }
    
  3. Package.json for Build:

    {
      "name": "glowdoc-site",
      "scripts": {
        "build": "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && source ~/.cargo/env && cargo run --release"
      }
    }
    

Method 2: Vercel CLI

# Install Vercel CLI
npm install -g vercel

# Build and deploy
cargo run --release
vercel --prod

Cloudflare Pages

High-performance hosting with global edge network.

Setup Process:

  1. Connect Repository:

  2. Build Configuration:

    • Build command: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && source ~/.cargo/env && cargo run --release
    • Build output directory: .
    • Environment variables: RUST_VERSION=1.70
  3. Custom Domains:

    # Configure custom domain in Cloudflare Dashboard
    # DNS automatically managed
    

Firebase Hosting

Google's hosting platform with global CDN.

Setup Process:

# Install Firebase CLI
npm install -g firebase-tools

# Initialize Firebase
firebase login
firebase init hosting

# Configure firebase.json
{
  "hosting": {
    "public": ".",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**",
      "src/**",
      "docs/**",
      "target/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ],
    "headers": [
      {
        "source": "**/*.@(js|css)",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "max-age=31536000"
          }
        ]
      }
    ]
  }
}
# Build and deploy
cargo run --release
firebase deploy

Traditional Web Hosting

Apache Configuration

For traditional web hosting with Apache:

# .htaccess
RewriteEngine On

# Handle client-side routing
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]

# Security headers
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

# Compression
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/css application/javascript
</IfModule>

# Caching
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/html "access plus 1 hour"
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType application/javascript "access plus 1 year"
</IfModule>

Nginx Configuration

For Nginx hosting:

server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.com;
    
    # Redirect HTTP to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name yourdomain.com;
    
    # SSL configuration
    ssl_certificate /path/to/certificate.crt;
    ssl_certificate_key /path/to/private.key;
    
    # Document root
    root /var/www/glowdoc;
    index index.html;
    
    # Handle client-side routing
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    # Security headers
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
    
    # Compression
    gzip on;
    gzip_types text/html text/css application/javascript;
    
    # Caching
    location ~* \.(css|js)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

Content Delivery Networks (CDN)

Cloudflare CDN

Enhance performance with Cloudflare:

  1. DNS Setup:

    • Add your domain to Cloudflare
    • Update nameservers
    • Enable "Proxied" status
  2. Optimization Settings:

    • Auto Minify: HTML, CSS, JS
    • Brotli compression: Enabled
    • Rocket Loader: Enabled
    • Cache Level: Standard
  3. Page Rules:

    yourdomain.com/*
    - Cache Level: Cache Everything
    - Edge Cache TTL: 1 month
    - Browser Cache TTL: 1 day
    

AWS CloudFront

Enterprise-grade CDN with AWS integration:

{
  "Distribution": {
    "Origins": [
      {
        "Id": "S3-glowdoc",
        "DomainName": "your-bucket.s3.amazonaws.com",
        "S3OriginConfig": {
          "OriginAccessIdentity": ""
        }
      }
    ],
    "DefaultCacheBehavior": {
      "TargetOriginId": "S3-glowdoc",
      "ViewerProtocolPolicy": "redirect-to-https",
      "Compress": true,
      "CachePolicyId": "managed-caching-optimized"
    },
    "CustomErrorResponses": [
      {
        "ErrorCode": 404,
        "ResponseCode": 200,
        "ResponsePagePath": "/index.html"
      }
    ]
  }
}

Automation and CI/CD

GitHub Actions Advanced Workflow

Complete CI/CD pipeline with testing and deployment:

name: Build, Test, and Deploy

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

env:
  CARGO_TERM_COLOR: always

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
    
    - name: Run tests
      run: cargo test --verbose
    
    - name: Check formatting
      run: cargo fmt -- --check
    
    - name: Run clippy
      run: cargo clippy -- -D warnings

  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
    
    - name: Cache dependencies
      uses: actions/cache@v3
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
    
    - name: Build documentation
      run: cargo run --release
    
    - name: Validate HTML
      run: |
        npm install -g html-validate
        html-validate index.html
    
    - name: Check file size
      run: |
        SIZE=$(stat -c%s index.html)
        echo "Generated file size: $SIZE bytes"
        if [ $SIZE -gt 5242880 ]; then
          echo "Warning: File size exceeds 5MB"
          exit 1
        fi
    
    - name: Upload artifacts
      uses: actions/upload-artifact@v3
      with:
        name: documentation
        path: index.html

  deploy-staging:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/develop'
    steps:
    - name: Download artifacts
      uses: actions/download-artifact@v3
      with:
        name: documentation
    
    - name: Deploy to staging
      run: |
        # Deploy to staging environment
        echo "Deploying to staging..."

  deploy-production:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
    - name: Download artifacts
      uses: actions/download-artifact@v3
      with:
        name: documentation
    
    - name: Deploy to GitHub Pages
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: .
        force_orphan: true
    
    - name: Notify deployment
      run: |
        curl -X POST ${{ secrets.SLACK_WEBHOOK }} \
          -H 'Content-type: application/json' \
          --data '{"text":"📚 Documentation deployed successfully!"}'

GitLab CI/CD

# .gitlab-ci.yml
stages:
  - test
  - build
  - deploy

variables:
  RUST_VERSION: "1.70"

before_script:
  - apt-get update -qq
  - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
  - source ~/.cargo/env

test:
  stage: test
  script:
    - cargo test --verbose
    - cargo fmt -- --check
    - cargo clippy -- -D warnings
  only:
    - merge_requests
    - main

build:
  stage: build
  script:
    - cargo run --release
  artifacts:
    paths:
      - index.html
    expire_in: 1 hour
  only:
    - main

pages:
  stage: deploy
  script:
    - mkdir public
    - cp index.html public/
  artifacts:
    paths:
      - public
  only:
    - main

Domain and SSL Configuration

Custom Domain Setup

DNS Configuration:

# A Records for root domain
@ 3600 IN A 185.199.108.153
@ 3600 IN A 185.199.109.153
@ 3600 IN A 185.199.110.153
@ 3600 IN A 185.199.111.153

# CNAME for www subdomain
www 3600 IN CNAME your-username.github.io.

# CNAME for docs subdomain
docs 3600 IN CNAME your-site.netlify.app.

SSL Certificate Setup:

Most modern hosting platforms provide automatic SSL:

  • GitHub Pages: Automatic with custom domains
  • Netlify: Automatic Let's Encrypt certificates
  • Vercel: Automatic SSL for all deployments
  • Cloudflare: Universal SSL included

Manual SSL Configuration

For traditional hosting:

# Generate Let's Encrypt certificate
certbot certonly --webroot -w /var/www/glowdoc -d yourdomain.com

# Auto-renewal
echo "0 12 * * * /usr/bin/certbot renew --quiet" | crontab -

Performance Optimization

Build Optimization

# Optimize for production
RUSTFLAGS="-C target-cpu=native" cargo run --release

# Profile build performance
cargo build --release --timings

Content Optimization

  1. Image Optimization: Use optimized images in markdown
  2. Font Subsetting: Include only needed font weights
  3. Code Splitting: Implement lazy loading for large sections

Monitoring and Analytics

Performance Monitoring:

// Add to your custom JavaScript
function trackPerformance() {
  window.addEventListener('load', () => {
    const perfData = performance.timing;
    const loadTime = perfData.loadEventEnd - perfData.navigationStart;
    
    // Send to analytics
    gtag('event', 'page_load_time', {
      value: loadTime,
      custom_parameter: 'documentation_site'
    });
  });
}

Uptime Monitoring:

Set up monitoring with services like:

  • StatusCake: Free uptime monitoring
  • Pingdom: Comprehensive monitoring suite
  • UptimeRobot: Free and paid monitoring options

Security Considerations

Content Security Policy

<!-- Add to your HTML head -->
<meta http-equiv="Content-Security-Policy" content="
  default-src 'self';
  script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com;
  style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
  font-src 'self' https://fonts.gstatic.com;
  img-src 'self' data: https:;
  connect-src 'self' https://www.google-analytics.com;
">

Security Headers

Implement security headers across all hosting platforms:

X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000; includeSubDomains
Referrer-Policy: strict-origin-when-cross-origin

Troubleshooting Deployment Issues

Common Problems

Build Failures:

# Check Rust version compatibility
rustc --version

# Verify dependencies
cargo check

# Clean and rebuild
cargo clean && cargo run --release

Routing Issues:

  • Ensure hosting platform supports SPA routing
  • Configure redirects for client-side routing
  • Verify base URL configuration

Performance Issues:

  • Check file size (should be under 5MB)
  • Verify compression is enabled
  • Test CDN configuration

SSL Certificate Problems:

  • Verify DNS propagation
  • Check certificate chain
  • Ensure HTTPS redirects are configured

Debug Deployment

# Test local build
cargo run --release
python3 -m http.server 8000

# Validate HTML
html-validate index.html

# Check file permissions
ls -la index.html

# Test from different networks
curl -I https://yourdomain.com

Best Practices

  1. Version Control: Always commit before deploying
  2. Staging Environment: Test changes before production
  3. Automated Backups: Regular backup of source files
  4. Performance Monitoring: Track load times and uptime
  5. Security Updates: Keep hosting platform updated
  6. Documentation: Document deployment process for team
  7. Rollback Plan: Maintain ability to quickly revert changes

This comprehensive deployment guide ensures your GlowDoc documentation is accessible, performant, and secure across any hosting platform.

Plugins and Extensions

Extend GlowDoc's functionality with custom plugins, third-party integrations, and advanced features to enhance your documentation experience.

Plugin Architecture Overview

GlowDoc's modular architecture allows for various extension points and integration patterns. While GlowDoc doesn't have a formal plugin system, you can extend functionality through several approaches:

Extension Methods

  1. CSS and JavaScript Extensions: Add custom functionality through the Rust build process
  2. Third-Party Integrations: Embed external services and tools
  3. Build Process Extensions: Modify the Rust source for custom features
  4. External Tool Integration: Combine GlowDoc with other documentation tools

Syntax Highlighting Enhancements

Advanced Code Highlighting

While GlowDoc includes basic syntax highlighting, you can enhance it with external libraries:

Prism.js Integration

Add advanced syntax highlighting with Prism.js:

// Add to the JavaScript section in src/main.rs
function initializePrism() {
  // Load Prism.js dynamically
  const script = document.createElement('script');
  script.src = 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js';
  script.onload = function() {
    // Load additional language support
    const languages = ['rust', 'javascript', 'python', 'bash', 'yaml'];
    languages.forEach(lang => {
      const langScript = document.createElement('script');
      langScript.src = `https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-${lang}.min.js`;
      document.head.appendChild(langScript);
    });
    
    // Load Prism CSS
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css';
    document.head.appendChild(link);
    
    // Re-highlight all code blocks
    Prism.highlightAll();
  };
  document.head.appendChild(script);
}

// Call during page initialization
initializePrism();

Custom Syntax Highlighting

Create custom highlighting for domain-specific languages:

function customHighlighter() {
  document.querySelectorAll('pre code').forEach(block => {
    const language = block.className.match(/language-(\w+)/);
    if (language && language[1] === 'custom-dsl') {
      highlightCustomDSL(block);
    }
  });
}

function highlightCustomDSL(codeBlock) {
  let html = codeBlock.innerHTML;
  
  // Define custom syntax patterns
  const patterns = [
    { regex: /\b(function|if|else|return)\b/g, class: 'keyword' },
    { regex: /\b\d+\b/g, class: 'number' },
    { regex: /"[^"]*"/g, class: 'string' },
    { regex: /\/\/.*$/gm, class: 'comment' }
  ];
  
  patterns.forEach(pattern => {
    html = html.replace(pattern.regex, `<span class="${pattern.class}">$&</span>`);
  });
  
  codeBlock.innerHTML = html;
}

Code Copy Functionality

Add copy-to-clipboard buttons for code blocks:

function addCopyButtons() {
  document.querySelectorAll('pre').forEach(pre => {
    const button = document.createElement('button');
    button.className = 'copy-button';
    button.textContent = 'Copy';
    button.onclick = () => copyToClipboard(pre.textContent, button);
    
    pre.style.position = 'relative';
    pre.appendChild(button);
  });
}

function copyToClipboard(text, button) {
  navigator.clipboard.writeText(text).then(() => {
    const originalText = button.textContent;
    button.textContent = 'Copied!';
    button.classList.add('copied');
    
    setTimeout(() => {
      button.textContent = originalText;
      button.classList.remove('copied');
    }, 2000);
  });
}

// CSS for copy button
const copyButtonCSS = `
.copy-button {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  padding: 0.25rem 0.5rem;
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  border: none;
  border-radius: 0.25rem;
  font-size: 0.75rem;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s ease;
}

pre:hover .copy-button {
  opacity: 1;
}

.copy-button.copied {
  background: hsl(var(--accent));
}
`;

Search Enhancements

Advanced Search Integration

Algolia DocSearch

Integrate Algolia's DocSearch for powerful search capabilities:

function initializeAlgoliaSearch() {
  // Load Algolia DocSearch
  const script = document.createElement('script');
  script.src = 'https://cdn.jsdelivr.net/npm/@docsearch/js@3';
  script.onload = function() {
    docsearch({
      appId: 'YOUR_APP_ID',
      apiKey: 'YOUR_SEARCH_API_KEY',
      indexName: 'YOUR_INDEX_NAME',
      container: '#docsearch',
      searchParameters: {
        facetFilters: ['language:en'],
      },
    });
  };
  document.head.appendChild(script);
  
  // Replace existing search input
  const searchContainer = document.querySelector('.search-container');
  searchContainer.innerHTML = '<div id="docsearch"></div>';
}

Implement advanced client-side search with Lunr.js:

function initializeLunrSearch() {
  // Build search index from content
  const documents = [];
  document.querySelectorAll('.content-section').forEach((section, idx) => {
    documents.push({
      id: idx,
      title: section.querySelector('h1')?.textContent || '',
      content: section.textContent,
      url: section.id
    });
  });
  
  // Create Lunr index
  const idx = lunr(function () {
    this.ref('id');
    this.field('title', { boost: 10 });
    this.field('content');
    
    documents.forEach((doc) => {
      this.add(doc);
    });
  });
  
  // Enhanced search function
  function performSearch(query) {
    const results = idx.search(query);
    return results.map(result => {
      const doc = documents[result.ref];
      return {
        ...doc,
        score: result.score,
        excerpt: generateExcerpt(doc.content, query)
      };
    });
  }
  
  function generateExcerpt(content, query, maxLength = 150) {
    const index = content.toLowerCase().indexOf(query.toLowerCase());
    if (index === -1) return content.substring(0, maxLength) + '...';
    
    const start = Math.max(0, index - 50);
    const end = Math.min(content.length, index + query.length + 50);
    const excerpt = content.substring(start, end);
    
    return (start > 0 ? '...' : '') + excerpt + (end < content.length ? '...' : '');
  }
}

Search Analytics

Track search behavior and popular queries:

function trackSearchAnalytics() {
  const searchInput = document.querySelector('.search-input');
  
  searchInput.addEventListener('input', debounce((e) => {
    const query = e.target.value;
    if (query.length > 2) {
      // Track search queries
      gtag('event', 'search', {
        search_term: query,
        page_title: document.title
      });
    }
  }, 1000));
  
  // Track search result clicks
  document.addEventListener('click', (e) => {
    if (e.target.classList.contains('search-result')) {
      gtag('event', 'search_result_click', {
        search_term: searchInput.value,
        result_title: e.target.textContent
      });
    }
  });
}

function debounce(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

Analytics and Tracking

Google Analytics 4 Integration

Implement comprehensive analytics tracking:

function initializeAnalytics() {
  // Load Google Analytics
  const script1 = document.createElement('script');
  script1.async = true;
  script1.src = 'https://www.googletagmanager.com/gtag/js?id=YOUR_GA_ID';
  document.head.appendChild(script1);
  
  const script2 = document.createElement('script');
  script2.innerHTML = `
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', 'YOUR_GA_ID', {
      page_title: document.title,
      page_location: window.location.href
    });
  `;
  document.head.appendChild(script2);
}

function trackUserBehavior() {
  // Track page navigation
  document.addEventListener('click', (e) => {
    if (e.target.classList.contains('nav-link')) {
      gtag('event', 'page_view', {
        page_title: e.target.textContent,
        page_location: window.location.href + '#' + e.target.getAttribute('href').substring(1)
      });
    }
  });
  
  // Track theme changes
  document.querySelector('.theme-toggle').addEventListener('click', () => {
    const currentTheme = document.documentElement.getAttribute('data-theme');
    gtag('event', 'theme_change', {
      theme: currentTheme === 'dark' ? 'light' : 'dark'
    });
  });
  
  // Track scroll depth
  let maxScroll = 0;
  window.addEventListener('scroll', debounce(() => {
    const scrollPercent = Math.round((window.scrollY + window.innerHeight) / document.body.scrollHeight * 100);
    if (scrollPercent > maxScroll) {
      maxScroll = scrollPercent;
      if (maxScroll % 25 === 0) { // Track at 25%, 50%, 75%, 100%
        gtag('event', 'scroll_depth', {
          percent: maxScroll,
          page_title: document.title
        });
      }
    }
  }, 500));
}

Hotjar Integration

Add user behavior tracking with Hotjar:

function initializeHotjar() {
  const script = document.createElement('script');
  script.innerHTML = `
    (function(h,o,t,j,a,r){
      h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
      h._hjSettings={hjid:YOUR_HOTJAR_ID,hjsv:6};
      a=o.getElementsByTagName('head')[0];
      r=o.createElement('script');r.async=1;
      r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
      a.appendChild(r);
    })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
  `;
  document.head.appendChild(script);
}

Accessibility Enhancements

Screen Reader Improvements

Enhance accessibility with ARIA attributes and screen reader support:

function enhanceAccessibility() {
  // Add skip navigation
  const skipLink = document.createElement('a');
  skipLink.href = '#main-content';
  skipLink.textContent = 'Skip to main content';
  skipLink.className = 'skip-link';
  document.body.insertBefore(skipLink, document.body.firstChild);
  
  // Improve navigation ARIA labels
  document.querySelectorAll('.nav-section-title').forEach(title => {
    const sectionId = title.getAttribute('data-section');
    title.setAttribute('aria-expanded', 'false');
    title.setAttribute('aria-controls', sectionId + '-content');
    
    const content = title.nextElementSibling;
    if (content) {
      content.setAttribute('id', sectionId + '-content');
      content.setAttribute('aria-labelledby', sectionId + '-title');
    }
  });
  
  // Announce page changes to screen readers
  const announcer = document.createElement('div');
  announcer.setAttribute('aria-live', 'polite');
  announcer.setAttribute('aria-atomic', 'true');
  announcer.className = 'sr-only';
  document.body.appendChild(announcer);
  
  // Announce when content changes
  function announcePageChange(title) {
    announcer.textContent = `Navigated to ${title}`;
    setTimeout(() => announcer.textContent = '', 1000);
  }
  
  return { announcePageChange };
}

// CSS for accessibility
const accessibilityCSS = `
.skip-link {
  position: absolute;
  top: -40px;
  left: 6px;
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  padding: 8px;
  text-decoration: none;
  border-radius: 0 0 4px 4px;
  z-index: 1000;
}

.skip-link:focus {
  top: 0;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
`;

Keyboard Navigation Enhancement

Improve keyboard navigation throughout the documentation:

function enhanceKeyboardNavigation() {
  let focusedSearchResult = -1;
  
  document.addEventListener('keydown', (e) => {
    // Search result navigation
    if (e.target.classList.contains('search-input')) {
      const results = document.querySelectorAll('.search-result');
      
      switch (e.key) {
        case 'ArrowDown':
          e.preventDefault();
          focusedSearchResult = Math.min(focusedSearchResult + 1, results.length - 1);
          updateSearchResultFocus(results);
          break;
          
        case 'ArrowUp':
          e.preventDefault();
          focusedSearchResult = Math.max(focusedSearchResult - 1, -1);
          updateSearchResultFocus(results);
          break;
          
        case 'Enter':
          if (focusedSearchResult >= 0 && results[focusedSearchResult]) {
            e.preventDefault();
            results[focusedSearchResult].click();
          }
          break;
          
        case 'Escape':
          e.target.blur();
          document.querySelector('.search-results').style.display = 'none';
          break;
      }
    }
    
    // Global shortcuts
    if (e.ctrlKey || e.metaKey) {
      switch (e.key) {
        case 'k':
          e.preventDefault();
          document.querySelector('.search-input').focus();
          break;
          
        case '/':
          e.preventDefault();
          document.querySelector('.search-input').focus();
          break;
      }
    }
  });
  
  function updateSearchResultFocus(results) {
    results.forEach((result, index) => {
      result.classList.toggle('focused', index === focusedSearchResult);
    });
    
    if (focusedSearchResult >= 0 && results[focusedSearchResult]) {
      results[focusedSearchResult].scrollIntoView({ block: 'nearest' });
    }
  }
}

Performance Enhancements

Lazy Loading and Code Splitting

Implement performance optimizations:

function implementLazyLoading() {
  // Lazy load heavy components
  const observerOptions = {
    root: null,
    rootMargin: '100px',
    threshold: 0.1
  };
  
  const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const section = entry.target;
        loadSectionAssets(section);
        observer.unobserve(section);
      }
    });
  }, observerOptions);
  
  // Observe content sections for lazy loading
  document.querySelectorAll('.content-section').forEach(section => {
    observer.observe(section);
  });
  
  function loadSectionAssets(section) {
    // Load section-specific assets
    const codeBlocks = section.querySelectorAll('pre code');
    if (codeBlocks.length > 0) {
      loadSyntaxHighlighting(codeBlocks);
    }
    
    const diagrams = section.querySelectorAll('.mermaid');
    if (diagrams.length > 0) {
      loadMermaidDiagrams(diagrams);
    }
  }
}

function implementServiceWorker() {
  if ('serviceWorker' in navigator) {
    const swContent = `
      const CACHE_NAME = 'glowdoc-v1';
      const urlsToCache = [
        '/',
        '/index.html'
      ];
      
      self.addEventListener('install', (event) => {
        event.waitUntil(
          caches.open(CACHE_NAME)
            .then((cache) => cache.addAll(urlsToCache))
        );
      });
      
      self.addEventListener('fetch', (event) => {
        event.respondWith(
          caches.match(event.request)
            .then((response) => {
              return response || fetch(event.request);
            })
        );
      });
    `;
    
    const blob = new Blob([swContent], { type: 'application/javascript' });
    const swURL = URL.createObjectURL(blob);
    
    navigator.serviceWorker.register(swURL)
      .then((registration) => {
        console.log('ServiceWorker registered:', registration);
      })
      .catch((error) => {
        console.log('ServiceWorker registration failed:', error);
      });
  }
}

Diagram and Visualization Support

Mermaid Diagrams

Add support for Mermaid diagrams:

function initializeMermaid() {
  const script = document.createElement('script');
  script.src = 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js';
  script.onload = function() {
    mermaid.initialize({
      startOnLoad: false,
      theme: document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'default',
      securityLevel: 'loose'
    });
    
    // Process Mermaid diagrams
    document.querySelectorAll('.language-mermaid').forEach(async (element, index) => {
      const graphDefinition = element.textContent;
      const graphId = `mermaid-graph-${index}`;
      
      try {
        const { svg } = await mermaid.render(graphId, graphDefinition);
        const wrapper = document.createElement('div');
        wrapper.className = 'mermaid-wrapper';
        wrapper.innerHTML = svg;
        element.closest('pre').replaceWith(wrapper);
      } catch (error) {
        console.error('Mermaid rendering error:', error);
      }
    });
  };
  document.head.appendChild(script);
}

// Update Mermaid theme when user changes theme
function updateMermaidTheme() {
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      if (mutation.attributeName === 'data-theme') {
        const newTheme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'default';
        if (window.mermaid) {
          mermaid.initialize({ theme: newTheme });
          // Re-render existing diagrams
          document.querySelectorAll('.mermaid-wrapper').forEach(async (wrapper, index) => {
            // Re-render logic here
          });
        }
      }
    });
  });
  
  observer.observe(document.documentElement, {
    attributes: true,
    attributeFilter: ['data-theme']
  });
}

Chart.js Integration

Add interactive charts and graphs:

function initializeCharts() {
  const script = document.createElement('script');
  script.src = 'https://cdn.jsdelivr.net/npm/chart.js';
  script.onload = function() {
    document.querySelectorAll('.chart-container').forEach(container => {
      const config = JSON.parse(container.dataset.config);
      const canvas = document.createElement('canvas');
      container.appendChild(canvas);
      
      new Chart(canvas, {
        ...config,
        options: {
          ...config.options,
          responsive: true,
          plugins: {
            ...config.options?.plugins,
            legend: {
              ...config.options?.plugins?.legend,
              labels: {
                color: getComputedStyle(document.documentElement)
                  .getPropertyValue('--foreground')
              }
            }
          }
        }
      });
    });
  };
  document.head.appendChild(script);
}

Plugin Development Guide

Creating Custom Extensions

Structure for building your own GlowDoc extensions:

// In src/main.rs, add to the generate_javascript() function

pub fn generate_custom_plugin_javascript() -> String {
    r#"
    // Custom Plugin Framework
    class GlowDocPlugin {
        constructor(name, options = {}) {
            this.name = name;
            this.options = options;
            this.hooks = {};
            this.initialized = false;
        }
        
        // Register event hooks
        on(event, callback) {
            if (!this.hooks[event]) {
                this.hooks[event] = [];
            }
            this.hooks[event].push(callback);
            return this;
        }
        
        // Trigger event hooks
        trigger(event, data) {
            if (this.hooks[event]) {
                this.hooks[event].forEach(callback => callback(data));
            }
        }
        
        // Initialize plugin
        init() {
            if (this.initialized) return;
            this.trigger('beforeInit', this.options);
            this.setup();
            this.initialized = true;
            this.trigger('afterInit', this.options);
        }
        
        // Override in subclasses
        setup() {
            throw new Error('Plugin must implement setup() method');
        }
    }
    
    // Plugin registry
    window.GlowDocPlugins = {
        plugins: new Map(),
        
        register(plugin) {
            this.plugins.set(plugin.name, plugin);
            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', () => plugin.init());
            } else {
                plugin.init();
            }
        },
        
        get(name) {
            return this.plugins.get(name);
        }
    };
    
    // Example plugin
    class ExamplePlugin extends GlowDocPlugin {
        setup() {
            this.on('beforeInit', (options) => {
                console.log('Example plugin initializing with options:', options);
            });
            
            // Add custom functionality
            this.addCustomButton();
        }
        
        addCustomButton() {
            const button = document.createElement('button');
            button.textContent = 'Custom Action';
            button.onclick = () => this.trigger('customAction', 'Hello from plugin!');
            document.querySelector('.header-content').appendChild(button);
        }
    }
    
    // Auto-register plugins
    document.addEventListener('DOMContentLoaded', () => {
        // Register built-in plugins
        const examplePlugin = new ExamplePlugin('example', { debug: true });
        GlowDocPlugins.register(examplePlugin);
    });
    "#.to_string()
}

Plugin Configuration

Allow users to configure plugins through config.yaml:

// Add to Config struct in src/main.rs
#[derive(Debug, Deserialize, Serialize)]
struct PluginConfig {
    name: String,
    enabled: bool,
    options: HashMap<String, serde_yaml::Value>,
}

#[derive(Debug, Deserialize, Serialize)]
struct Config {
    title: String,
    description: String,
    navigation: Vec<NavigationSection>,
    theme: String,
    plugins: Option<Vec<PluginConfig>>,
}

Best Practices for Extensions

Performance Considerations

  1. Lazy Loading: Only load plugins when needed
  2. Code Splitting: Separate plugin code from core functionality
  3. Memory Management: Clean up event listeners and resources
  4. Minimal Dependencies: Keep external dependencies lightweight

Security Guidelines

  1. Input Validation: Sanitize all user inputs
  2. Content Security Policy: Implement CSP headers
  3. External Resources: Use integrity hashes for CDN resources
  4. User Data: Handle user data securely

Accessibility Standards

  1. ARIA Support: Provide proper ARIA attributes
  2. Keyboard Navigation: Ensure all functionality is keyboard accessible
  3. Screen Reader Compatibility: Test with screen readers
  4. Color Contrast: Maintain adequate contrast ratios

Troubleshooting Plugins

Plugin not loading: Check browser console for JavaScript errors and verify script URLs.

Conflicts between plugins: Implement proper namespacing and avoid global variable conflicts.

Performance issues: Profile plugin performance and optimize heavy operations.

Theme compatibility: Ensure plugins work with all themes and dark mode.

Mobile responsiveness: Test plugin functionality on mobile devices.