diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
new file mode 100644
index 0000000..5f39301
--- /dev/null
+++ b/.github/workflows/pages.yml
@@ -0,0 +1,53 @@
+name: Deploy Docs
+
+on:
+ push:
+ branches:
+ - main
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+concurrency:
+ group: pages
+ cancel-in-progress: true
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.12'
+
+ - name: Install docs dependencies
+ run: pip install -r requirements-docs.txt
+
+ - name: Build site
+ run: mkdocs build --strict
+
+ - name: Configure Pages
+ uses: actions/configure-pages@v5
+
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: site
+
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/.gitignore b/.gitignore
index 702afd0..3377416 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,9 @@
*.vsix
assets/
+!docs/assets/
+!docs/assets/icon.png
+!docs/assets/icon.svg
node_modules/
+site/
+.venv-docs/
+.cache/
diff --git a/.vscodeignore b/.vscodeignore
index f7466b5..3d5e9c4 100644
--- a/.vscodeignore
+++ b/.vscodeignore
@@ -3,3 +3,9 @@ assets/**
.gitignore
*.vsix
.github/**
+docs/**
+mkdocs.yml
+requirements-docs.txt
+scripts/**
+site/**
+.venv-docs/**
diff --git a/docs/assets/icon.png b/docs/assets/icon.png
new file mode 100644
index 0000000..d71604d
Binary files /dev/null and b/docs/assets/icon.png differ
diff --git a/docs/assets/icon.svg b/docs/assets/icon.svg
new file mode 100644
index 0000000..c915ccf
--- /dev/null
+++ b/docs/assets/icon.svg
@@ -0,0 +1,23 @@
+
diff --git a/docs/changelog.md b/docs/changelog.md
new file mode 100644
index 0000000..3329a24
--- /dev/null
+++ b/docs/changelog.md
@@ -0,0 +1,24 @@
+# Changelog
+
+A short release overview is maintained here for site visitors.
+
+## 1.2.0
+
+- added Marketplace-oriented metadata
+- introduced icon, banner settings, and release scripts
+- added changelog and CI workflow
+- improved README and repository presentation
+
+## 1.1.0
+
+- optimized grammar performance
+- standardized function scopes for better theme compatibility
+- prepared repository metadata for publishing
+
+## 1.0.0
+
+- first standalone release of the PL/SQL syntax extension
+- custom language id and grammar structure
+- MIT licensing and initial documentation
+
+For the full project history, see the repository changelog.
diff --git a/docs/coverage.md b/docs/coverage.md
new file mode 100644
index 0000000..354a344
--- /dev/null
+++ b/docs/coverage.md
@@ -0,0 +1,75 @@
+# Coverage
+
+## Supported syntax areas
+
+The current grammar covers the main structures expected in day-to-day PL/SQL work.
+
+### PL/SQL structures
+
+- anonymous blocks
+- procedures
+- functions
+- packages and package bodies
+- triggers
+- types and type bodies
+- records, collections, and `%TYPE` / `%ROWTYPE`
+- exception handling and control flow
+
+### SQL syntax
+
+- DML: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `MERGE`
+- DDL: `CREATE`, `ALTER`, `DROP`, constraints, storage clauses
+- joins, ordering, grouping, predicates, and common modifiers
+
+### Literals and expressions
+
+- single-quoted strings
+- q-quote strings
+- national character strings
+- numeric literals
+- bind variables and substitution variables
+
+### Built-ins and runtime concepts
+
+- built-in functions grouped by category
+- predefined exceptions
+- SQL*Plus commands
+- common pseudocolumns and constants
+
+## Supported file extensions
+
+The extension currently registers these extensions with the `plsql` language id:
+
+```text
+.sql .pls .plsql .pks .pkb .plb
+.fnc .prc .trg .vw .pkg .pck
+.seq .job .src .act .bac .bas
+.scr .ut
+```
+
+## Validation assets
+
+The repository contains validation examples under `assets/examples` covering:
+
+- schema objects
+- packages and package bodies
+- standalone functions and procedures
+- triggers
+- views
+- anonymous blocks
+
+These files are used as manual test material while refining highlighting behavior.
+
+## Theme compatibility
+
+The grammar favors broad compatibility by using scope families that themes commonly style:
+
+- `comment.*`
+- `string.*`
+- `constant.*`
+- `storage.type.*`
+- `keyword.*`
+- `entity.name.function.*`
+- `variable.other.*`
+
+This improves the chance that tokens receive meaningful colors even in themes with limited custom scope rules.
diff --git a/docs/disclaimer.md b/docs/disclaimer.md
new file mode 100644
index 0000000..f7abf3d
--- /dev/null
+++ b/docs/disclaimer.md
@@ -0,0 +1,17 @@
+# Disclaimer
+
+This project is an independent Visual Studio Code extension.
+
+It is not affiliated with, endorsed by, or related to Oracle Corporation.
+
+"Oracle", "PL/SQL", and "SQL*Plus" are trademarks or registered trademarks of Oracle Corporation. These names are used only to identify the language and tooling concepts supported by the extension.
+
+## License
+
+This project is released under the MIT License.
+
+## Repository scope
+
+The public repository contains the extension source, documentation, site configuration, and release-related files required to build and publish the project.
+
+Generated site output is intentionally excluded from version control.
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..34fbb03
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,66 @@
+# PL/SQL for VS Code
+
+
+
+
Syntax highlighting extension
+
Practical PL/SQL highlighting for real database code.
+
A focused Visual Studio Code extension for PL/SQL, SQL, packages, triggers, procedures, functions, and SQL*Plus scripts. Lightweight, theme-friendly, and built to stay easy to maintain.
Current status: production-ready for manual installation, with Marketplace publication planned next.
+
+
+
+```text
+Language ID: plsql
+Scope name : source.plsql
+Theme mode : light + dark
+Install : VSIX (for now)
+Focus : syntax quality and maintainability
+```
+
+
+
+
+## Why this extension exists
+
+This project provides a dedicated PL/SQL highlighting experience for VS Code without bundling unnecessary extension features. It is designed for people who work with database code daily and want a grammar that stays organized, fast, and predictable.
+
+
+
+- ### Lightweight by design
+
+ The extension focuses on syntax highlighting and language registration only. No extra runtime features, no unnecessary payload.
+
+- ### Theme-compatible scopes
+
+ The grammar uses broadly supported scope families such as `entity.name.function.*`, `keyword.*`, and `storage.type.*` for better compatibility across popular themes.
+
+- ### Ready for real PL/SQL files
+
+ Common file types like `.sql`, `.pls`, `.pks`, `.pkb`, `.fnc`, `.prc`, `.trg`, and SQL*Plus-style scripts are already mapped.
+
+- ### Easy to maintain
+
+ The grammar, docs, validation scripts, and release workflow are organized to keep future changes simple.
+
+
+
+## Current release snapshot
+
+| Item | Value |
+| --- | --- |
+| Extension name | PL/SQL |
+| Current site branch | `site` |
+| Current extension version | `1.2.0` |
+| Install method | Manual VSIX installation |
+| Next milestone | Marketplace publication |
+
+## What you can do next
+
+1. Read the [overview](overview.md) to understand the project status and goals.
+2. Follow the [installation guide](installation.md) to build and install locally.
+3. Review [coverage](coverage.md) for supported syntax areas and file extensions.
+4. Use the [roadmap](roadmap.md) page to keep upcoming work visible.
diff --git a/docs/installation.md b/docs/installation.md
new file mode 100644
index 0000000..10cd07f
--- /dev/null
+++ b/docs/installation.md
@@ -0,0 +1,74 @@
+# Installation
+
+## Current installation method
+
+The extension is not published to the Marketplace yet, so installation is currently manual via VSIX.
+
+## Build locally
+
+From the repository root:
+
+```bash
+npm run validate:grammar
+npm run package
+```
+
+This generates a file like:
+
+```text
+vscode-plsql-syntax-1.2.0.vsix
+```
+
+## Install in VS Code
+
+```bash
+code --install-extension vscode-plsql-syntax-1.2.0.vsix --force
+```
+
+Then reload the window:
+
+```text
+Developer: Reload Window
+```
+
+## Validate highlighting
+
+Open one or more example files from `assets/examples` and inspect tokens if needed with:
+
+```text
+Developer: Inspect Editor Tokens and Scopes
+```
+
+## Local site preview
+
+The documentation site can also be tested locally before publishing.
+
+### Start preview server
+
+```bash
+./scripts/serve-docs.sh
+```
+
+Then open:
+
+```text
+http://127.0.0.1:8000
+```
+
+### Build static site
+
+```bash
+./scripts/build-docs.sh
+```
+
+### Run a simple offline validation
+
+```bash
+./scripts/test-docs.sh
+```
+
+## Notes
+
+- Generated site files go to `site/` and are ignored by Git.
+- The local Python environment is stored in `.venv-docs/` and is also ignored.
+- Marketplace publication can be added later without changing the documentation structure.
diff --git a/docs/overview.md b/docs/overview.md
new file mode 100644
index 0000000..aae0bc8
--- /dev/null
+++ b/docs/overview.md
@@ -0,0 +1,54 @@
+# Purpose and Status
+
+## Purpose
+
+The PL/SQL extension exists to provide a focused and maintainable syntax highlighting experience for database-oriented development in Visual Studio Code.
+
+The goal is straightforward:
+
+- highlight real PL/SQL and SQL code accurately
+- support common file naming conventions used in database projects
+- stay lightweight and fast
+- remain easy to evolve and publish
+
+## Current status
+
+The extension is currently ready for manual installation and local use.
+
+It already includes:
+
+- a standalone language id: `plsql`
+- a custom grammar in `syntaxes/plsql.tmLanguage.json`
+- a language configuration in `syntaxes/language-configuration.json`
+- local packaging with `vsce`
+- repository metadata, changelog, and CI
+- this site and documentation structure
+
+## What is planned next
+
+The next step is Marketplace publication.
+
+That work mainly involves:
+
+- final review of metadata and visuals
+- screenshots for Marketplace presentation
+- release tagging and publication flow
+- ongoing grammar refinements based on real usage
+
+## Project principles
+
+### 1. Keep scope intentional
+
+The extension should stay focused on syntax highlighting and file association. This keeps behavior predictable and reduces maintenance cost.
+
+### 2. Prefer clarity over size
+
+The grammar is optimized, but not at the cost of becoming opaque. It should remain understandable when future fixes are needed.
+
+### 3. Stay theme-friendly
+
+Scope names are chosen to work well with common VS Code themes in both dark and light mode.
+
+### 4. Make release operations repeatable
+
+Packaging, validation, documentation, and site generation should all be easy to run locally before publishing.
diff --git a/docs/roadmap.md b/docs/roadmap.md
new file mode 100644
index 0000000..ad9c0e3
--- /dev/null
+++ b/docs/roadmap.md
@@ -0,0 +1,35 @@
+# Roadmap
+
+## Near-term goals
+
+### Marketplace publication
+
+- finalize listing metadata
+- prepare screenshots
+- publish first official release
+
+### Grammar refinement
+
+- expand coverage based on real-world PL/SQL files
+- reduce false positives where generic SQL terms overlap with identifiers
+- keep performance stable on larger files
+
+### Documentation quality
+
+- add screenshots of light and dark themes
+- document typical development workflows
+- add release notes as versions evolve
+
+## Ongoing maintenance
+
+- validate grammar changes before release
+- keep CI green for packaging and site generation
+- review theme behavior periodically
+- keep the site aligned with the current release state
+
+## Long-term possibilities
+
+- Marketplace badges and install stats on the site
+- dedicated screenshots and comparison pages
+- more formal grammar regression testing
+- additional tooling only if it stays aligned with the lightweight scope of the extension
diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css
new file mode 100644
index 0000000..2a9ea18
--- /dev/null
+++ b/docs/stylesheets/extra.css
@@ -0,0 +1,283 @@
+/* ── Brand tokens ─────────────────────────────────────────── */
+:root {
+ --pa-amber: #f59e0b;
+ --pa-amber-dim: #d97706;
+ --pa-amber-glow: rgba(245, 158, 11, 0.12);
+ --pa-amber-line: rgba(245, 158, 11, 0.32);
+ --pa-dark: #0f172a;
+ --pa-surface: rgba(255, 255, 255, 0.80);
+ --pa-border: rgba(148, 163, 184, 0.18);
+ --pa-shadow: 0 4px 16px rgba(15, 23, 42, 0.08), 0 1px 4px rgba(15, 23, 42, 0.05);
+ --pa-radius: 18px;
+}
+
+[data-md-color-scheme="slate"] {
+ --pa-surface: rgba(15, 23, 42, 0.75);
+ --pa-border: rgba(148, 163, 184, 0.12);
+ --pa-shadow: 0 4px 16px rgba(2, 6, 23, 0.40), 0 1px 4px rgba(2, 6, 23, 0.20);
+}
+
+/* ── Page background ──────────────────────────────────────── */
+.md-main {
+ background:
+ radial-gradient(ellipse 60% 30% at 100% 0%, rgba(245, 158, 11, 0.13) 0%, transparent 55%),
+ radial-gradient(ellipse 45% 35% at 0% 70%, rgba(59, 130, 246, 0.06) 0%, transparent 60%);
+}
+
+/* ── Content container ────────────────────────────────────── */
+.md-grid {
+ max-width: 66rem;
+}
+
+/* ── Primary button ───────────────────────────────────────── */
+.md-typeset .md-button--primary {
+ background-color: var(--pa-amber);
+ border-color: var(--pa-amber);
+ color: #111827;
+ font-weight: 700;
+ letter-spacing: 0.02em;
+ box-shadow: 0 2px 10px rgba(245, 158, 11, 0.28);
+ transition: background 0.18s, box-shadow 0.18s, transform 0.14s;
+}
+
+.md-typeset .md-button--primary:hover {
+ background-color: var(--pa-amber-dim);
+ border-color: var(--pa-amber-dim);
+ color: #fff;
+ box-shadow: 0 4px 18px rgba(245, 158, 11, 0.40);
+ transform: translateY(-1px);
+}
+
+.md-typeset .md-button {
+ transition: transform 0.14s;
+}
+
+.md-typeset .md-button:hover {
+ transform: translateY(-1px);
+}
+
+/* ══════════════════════════════════════════════════════════
+ HERO
+ ══════════════════════════════════════════════════════════ */
+.hero {
+ display: grid;
+ grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
+ gap: 2.5rem;
+ padding: 2.5rem 0 3rem;
+ align-items: center;
+}
+
+.eyebrow {
+ display: inline-flex;
+ padding: 0.28rem 0.75rem;
+ border-radius: 999px;
+ font-size: 0.69rem;
+ letter-spacing: 0.10em;
+ text-transform: uppercase;
+ font-weight: 700;
+ color: var(--pa-amber-dim);
+ background: var(--pa-amber-glow);
+ border: 1px solid var(--pa-amber-line);
+}
+
+.hero h1 {
+ margin: 0.5rem 0 0.9rem;
+ font-size: clamp(2rem, 4.2vw, 3.2rem);
+ line-height: 1.08;
+ letter-spacing: -0.02em;
+}
+
+.hero-copy {
+ font-size: 1.03rem;
+ line-height: 1.68;
+ max-width: 42rem;
+ opacity: 0.88;
+}
+
+.hero-actions {
+ display: flex;
+ gap: 0.75rem;
+ margin: 1.4rem 0 1rem;
+ flex-wrap: wrap;
+}
+
+.hero-note {
+ margin: 0;
+ font-size: 0.865rem;
+ opacity: 0.62;
+}
+
+/* Hero panel — right column */
+.hero-panel {
+ border: 1px solid var(--pa-border);
+ border-radius: 22px;
+ padding: 1.5rem 1.5rem 1.25rem;
+ background: var(--pa-surface);
+ box-shadow: var(--pa-shadow), inset 0 1px 0 rgba(255, 255, 255, 0.10);
+ backdrop-filter: blur(16px);
+ position: relative;
+ overflow: hidden;
+}
+
+.hero-panel::before {
+ content: '';
+ position: absolute;
+ top: 0; left: 0; right: 0;
+ height: 3px;
+ background: linear-gradient(90deg, var(--pa-amber), var(--pa-amber-dim));
+ border-radius: 22px 22px 0 0;
+}
+
+.hero-panel pre {
+ margin: 0;
+ background: transparent !important;
+ border: 0 !important;
+ box-shadow: none !important;
+ font-size: 0.875rem;
+ line-height: 1.72;
+}
+
+/* ══════════════════════════════════════════════════════════
+ SECTION HEADINGS — amber left accent
+ ══════════════════════════════════════════════════════════ */
+.md-typeset h2 {
+ display: flex;
+ align-items: center;
+ gap: 0.65rem;
+ margin-top: 3rem;
+}
+
+.md-typeset h2::before {
+ content: '';
+ display: inline-block;
+ width: 4px;
+ height: 1.15em;
+ border-radius: 2px;
+ background: var(--pa-amber);
+ flex-shrink: 0;
+}
+
+/* ══════════════════════════════════════════════════════════
+ CARD GRID — fixed 2-col on desktop, 1-col on mobile
+ ══════════════════════════════════════════════════════════ */
+.card-grid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 1.1rem;
+ margin-top: 1.5rem;
+}
+
+.card-grid > ul {
+ display: contents;
+}
+
+.card-grid li {
+ list-style: none;
+ margin: 0;
+ padding: 1.4rem 1.5rem 1.2rem;
+ border-radius: var(--pa-radius);
+ background: var(--pa-surface);
+ border: 1px solid var(--pa-border);
+ box-shadow: var(--pa-shadow);
+ transition: transform 0.18s, box-shadow 0.18s;
+ position: relative;
+ overflow: hidden;
+}
+
+.card-grid li::after {
+ content: '';
+ position: absolute;
+ bottom: 0; left: 1.5rem; right: 1.5rem;
+ height: 2px;
+ background: linear-gradient(90deg, var(--pa-amber-line), transparent);
+ border-radius: 2px;
+}
+
+.card-grid li:hover {
+ transform: translateY(-3px);
+ box-shadow: var(--pa-shadow), 0 10px 28px rgba(245, 158, 11, 0.10);
+}
+
+.card-grid h3 {
+ margin-top: 0;
+ margin-bottom: 0.55rem;
+ font-size: 0.975rem;
+ font-weight: 700;
+ letter-spacing: -0.01em;
+}
+
+.card-grid li p {
+ margin: 0;
+ font-size: 0.875rem;
+ line-height: 1.62;
+ opacity: 0.82;
+}
+
+/* ══════════════════════════════════════════════════════════
+ TABLE
+ ══════════════════════════════════════════════════════════ */
+.md-typeset table:not([class]) {
+ border-radius: 14px;
+ overflow: hidden;
+ border: 1px solid var(--pa-border);
+ box-shadow: var(--pa-shadow);
+ border-collapse: separate;
+ border-spacing: 0;
+}
+
+.md-typeset table:not([class]) th {
+ background: var(--pa-amber-glow);
+ color: var(--pa-amber-dim);
+ font-size: 0.76rem;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ border-bottom: 1px solid var(--pa-amber-line);
+}
+
+.md-typeset table:not([class]) td,
+.md-typeset table:not([class]) th {
+ padding: 0.75rem 1rem;
+ border: none;
+}
+
+.md-typeset table:not([class]) tr:not(:last-child) td {
+ border-bottom: 1px solid var(--pa-border);
+}
+
+/* ── Responsive ───────────────────────────────────────────── */
+@media (max-width: 1024px) {
+ .hero {
+ grid-template-columns: 1fr;
+ gap: 2rem;
+ padding: 2rem 0 2.5rem;
+ }
+
+ .hero-panel {
+ max-width: 40rem;
+ }
+}
+
+@media (max-width: 680px) {
+ .hero {
+ gap: 1.5rem;
+ padding: 1.25rem 0 2rem;
+ }
+
+ .hero h1 {
+ font-size: clamp(1.8rem, 9vw, 2.4rem);
+ }
+
+ .hero-panel {
+ max-width: 100%;
+ padding: 1.25rem;
+ }
+
+ .card-grid {
+ grid-template-columns: 1fr;
+ gap: 0.9rem;
+ }
+
+ .card-grid li {
+ padding: 1.2rem 1.1rem 1rem;
+ }
+}
diff --git a/media/icon.png b/media/icon.png
index 8637c1d..d71604d 100644
Binary files a/media/icon.png and b/media/icon.png differ
diff --git a/media/icon.svg b/media/icon.svg
new file mode 100644
index 0000000..c915ccf
--- /dev/null
+++ b/media/icon.svg
@@ -0,0 +1,23 @@
+
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 0000000..8dfcd44
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,80 @@
+site_name: PL/SQL
+site_description: PL/SQL syntax highlighting extension for Visual Studio Code.
+site_url: https://bortoloso.github.io/vscode-plsql-syntax/
+repo_url: https://github.com/bortoloso/vscode-plsql-syntax
+repo_name: bortoloso/vscode-plsql-syntax
+edit_uri: edit/main/docs/
+site_dir: site
+copyright: Copyright (c) 2026 bortoloso
+
+theme:
+ name: material
+ logo: assets/icon.svg
+ favicon: assets/icon.svg
+ language: en
+ font:
+ text: IBM Plex Sans
+ code: IBM Plex Mono
+ palette:
+ - scheme: default
+ primary: blue grey
+ accent: amber
+ toggle:
+ icon: material/weather-night
+ name: Switch to dark mode
+ - scheme: slate
+ primary: blue grey
+ accent: amber
+ toggle:
+ icon: material/weather-sunny
+ name: Switch to light mode
+ features:
+ - navigation.sections
+ - navigation.top
+ - navigation.footer
+ - navigation.indexes
+ - content.code.copy
+ - content.tabs.link
+ - content.tooltips
+ - search.highlight
+ - search.suggest
+ - toc.follow
+
+nav:
+ - Home: index.md
+ - Overview:
+ - Purpose and Status: overview.md
+ - Coverage: coverage.md
+ - Installation: installation.md
+ - Roadmap: roadmap.md
+ - Project:
+ - Changelog: changelog.md
+ - Disclaimer: disclaimer.md
+
+markdown_extensions:
+ - admonition
+ - attr_list
+ - def_list
+ - footnotes
+ - md_in_html
+ - pymdownx.details
+ - pymdownx.superfences
+ - pymdownx.tabbed:
+ alternate_style: true
+ - pymdownx.highlight:
+ anchor_linenums: true
+ - pymdownx.inlinehilite
+ - pymdownx.snippets
+ - tables
+
+extra:
+ social:
+ - icon: fontawesome/brands/github
+ link: https://github.com/bortoloso/vscode-plsql-syntax
+ name: GitHub repository
+
+extra_css:
+ - stylesheets/extra.css
+
+plugins:
+ - search
diff --git a/package.json b/package.json
index 9ab3133..b98bc14 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "vscode-plsql-syntax",
"displayName": "PL/SQL",
"description": "PL/SQL syntax highlighting for SQL, procedures, packages, triggers, and SQL*Plus scripts",
- "version": "1.2.0",
+ "version": "1.2.1",
"publisher": "bortoloso",
"license": "MIT",
"icon": "media/icon.png",
@@ -24,6 +24,9 @@
},
"scripts": {
"validate:grammar": "node -e \"JSON.parse(require('fs').readFileSync('syntaxes/plsql.tmLanguage.json','utf8')); JSON.parse(require('fs').readFileSync('syntaxes/language-configuration.json','utf8')); console.log('Grammar JSON OK');\"",
+ "docs:serve": "./scripts/serve-docs.sh",
+ "docs:build": "./scripts/build-docs.sh",
+ "docs:test": "./scripts/test-docs.sh",
"package": "vsce package",
"package:ci": "vsce package --out vscode-plsql-syntax.vsix"
},
diff --git a/requirements-docs.txt b/requirements-docs.txt
new file mode 100644
index 0000000..948c9be
--- /dev/null
+++ b/requirements-docs.txt
@@ -0,0 +1,2 @@
+mkdocs==1.6.1
+mkdocs-material==9.6.14
diff --git a/scripts/build-docs.sh b/scripts/build-docs.sh
new file mode 100755
index 0000000..3325992
--- /dev/null
+++ b/scripts/build-docs.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+VENV_DIR="$ROOT_DIR/.venv-docs"
+
+if [[ ! -d "$VENV_DIR" ]]; then
+ python3 -m venv "$VENV_DIR"
+fi
+
+source "$VENV_DIR/bin/activate"
+pip install --disable-pip-version-check -r "$ROOT_DIR/requirements-docs.txt" >/dev/null
+cd "$ROOT_DIR"
+mkdocs build --strict
diff --git a/scripts/serve-docs.sh b/scripts/serve-docs.sh
new file mode 100755
index 0000000..db711b6
--- /dev/null
+++ b/scripts/serve-docs.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+VENV_DIR="$ROOT_DIR/.venv-docs"
+
+if [[ ! -d "$VENV_DIR" ]]; then
+ python3 -m venv "$VENV_DIR"
+fi
+
+source "$VENV_DIR/bin/activate"
+pip install --disable-pip-version-check -r "$ROOT_DIR/requirements-docs.txt" >/dev/null
+cd "$ROOT_DIR"
+mkdocs serve -a 127.0.0.1:8000
diff --git a/scripts/test-docs.sh b/scripts/test-docs.sh
new file mode 100755
index 0000000..e607bd1
--- /dev/null
+++ b/scripts/test-docs.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+"$ROOT_DIR/scripts/build-docs.sh"
+if [[ -f "$ROOT_DIR/site/index.html" ]]; then
+ echo "Site build OK"
+else
+ echo "Site build failed: site/index.html not found" >&2
+ exit 1
+fi