Add a manual workflow to deploy the docs to gh-pages

Publishing the docs meant building the site and pushing it to gh-pages by
hand. This adds a workflow_dispatch job that builds the site, then copies it
over a gh-pages checkout with rsync. The copy omits --delete, so every older
docs/<version> directory survives while the root files and the current version
get replaced.

The job uses no third-party actions. GitHub's own Pages actions replace the
whole site on each deploy, so they cannot keep the version archive.

Also drop release-drafter. The release UI now generates the notes, and
.github/release.yml keeps the same label categories.
diff --git a/.cspell.json b/.cspell.json
index 39e7791..07f2141 100644
--- a/.cspell.json
+++ b/.cspell.json
@@ -132,6 +132,7 @@
     "Neue",
     "nextjs",
     "noindex",
+    "nojekyll",
     "nonmodal",
     "nvmrc",
     "oklab",
diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml
deleted file mode 100644
index 0289984..0000000
--- a/.github/release-drafter.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-name-template: 'v$NEXT_MAJOR_VERSION'
-tag-template: 'v$NEXT_MAJOR_VERSION'
-prerelease: true
-exclude-labels:
-  - 'skip-changelog'
-categories:
-  - title: '❗ Breaking Changes'
-    labels:
-      - 'breaking-change'
-  - title: '🚀 Highlights'
-    labels:
-      - 'release-highlight'
-  - title: '🚀 Features'
-    labels:
-      - 'new-feature'
-      - 'feature'
-      - 'enhancement'
-  - title: '🐛 Bug fixes'
-    labels:
-      - 'fix'
-      - 'bugfix'
-      - 'bug'
-  - title: '⚡ Performance improvements'
-    labels:
-      - 'performance'
-  - title: '🎨 CSS'
-    labels:
-      - 'css'
-  - title: '☕️ JavaScript'
-    labels:
-      - 'js'
-  - title: '📖 Docs'
-    labels:
-      - 'docs'
-  - title: '🛠 Examples'
-    labels:
-      - 'examples'
-  - title: '🌎 Accessibility'
-    labels:
-      - 'accessibility'
-  - title: '🔧 Utility API'
-    labels:
-      - 'utility API'
-      - 'utilities'
-  - title: '🏭 Tests'
-    labels:
-      - 'tests'
-  - title: '🧰 Misc'
-    labels:
-      - 'build'
-      - 'meta'
-      - 'chore'
-      - 'CI'
-  - title: '📦 Dependencies'
-    labels:
-      - 'dependencies'
-change-template: '- #$NUMBER: $TITLE'
-template: |
-  ## Changes
-  $CHANGES
diff --git a/.github/release.yml b/.github/release.yml
new file mode 100644
index 0000000..751e288
--- /dev/null
+++ b/.github/release.yml
@@ -0,0 +1,62 @@
+# Configuration for GitHub's automatically generated release notes.
+# Use the "Generate release notes" button in the release UI.
+# https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes
+
+changelog:
+  exclude:
+    labels:
+      - 'skip-changelog'
+  categories:
+    - title: '❗ Breaking Changes'
+      labels:
+        - 'breaking-change'
+    - title: '🚀 Highlights'
+      labels:
+        - 'release-highlight'
+    - title: '🚀 Features'
+      labels:
+        - 'new-feature'
+        - 'feature'
+        - 'enhancement'
+    - title: '🐛 Bug fixes'
+      labels:
+        - 'fix'
+        - 'bugfix'
+        - 'bug'
+    - title: '⚡ Performance improvements'
+      labels:
+        - 'performance'
+    - title: '🎨 CSS'
+      labels:
+        - 'css'
+    - title: '☕️ JavaScript'
+      labels:
+        - 'js'
+    - title: '📖 Docs'
+      labels:
+        - 'docs'
+    - title: '🛠 Examples'
+      labels:
+        - 'examples'
+    - title: '🌎 Accessibility'
+      labels:
+        - 'accessibility'
+    - title: '🔧 Utility API'
+      labels:
+        - 'utility API'
+        - 'utilities'
+    - title: '🏭 Tests'
+      labels:
+        - 'tests'
+    - title: '🧰 Misc'
+      labels:
+        - 'build'
+        - 'meta'
+        - 'chore'
+        - 'CI'
+    - title: '📦 Dependencies'
+      labels:
+        - 'dependencies'
+    - title: '🗒 Other changes'
+      labels:
+        - '*'
diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml
new file mode 100644
index 0000000..0d9ef46
--- /dev/null
+++ b/.github/workflows/docs-deploy.yml
@@ -0,0 +1,74 @@
+name: Docs deploy
+
+# Manual only. Dispatch this workflow from the branch you want to publish
+# (for example `v6-dev`). It builds the docs and pushes them to `gh-pages`.
+
+on:
+  workflow_dispatch:
+
+env:
+  FORCE_COLOR: 2
+
+permissions:
+  contents: read
+
+jobs:
+  deploy:
+    runs-on: ubuntu-latest
+    if: github.repository == 'twbs/bootstrap'
+    permissions:
+      # allow the job to push the built site to the `gh-pages` branch
+      contents: write
+
+    steps:
+      - name: Clone repository
+        uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+        with:
+          persist-credentials: false
+
+      - name: Set up Node.js
+        uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
+        with:
+          node-version-file: ".nvmrc"
+          cache: npm
+
+      - name: Install npm dependencies
+        run: npm ci
+
+      - name: Build dist
+        run: npm run dist
+
+      - name: Build docs
+        run: npm run docs-build
+
+      # Checked out after the build so the docs build never sees this directory.
+      # Keeps its credentials, because the push at the end needs them.
+      - name: Check out gh-pages
+        uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+        with:
+          ref: gh-pages
+          path: .gh-pages
+
+      # `rsync` runs without `--delete`, so the deploy adds the current version
+      # and overwrites the root files, but keeps every older `docs/<version>`
+      # directory. Each build holds one version only.
+      - name: Copy the built site over gh-pages
+        run: |
+          rsync --archive --exclude .git _site/ .gh-pages/
+          touch .gh-pages/.nojekyll
+
+      - name: Commit and push
+        working-directory: .gh-pages
+        env:
+          SOURCE_REF: ${{ github.ref_name }}
+          SOURCE_SHA: ${{ github.sha }}
+        run: |
+          git config user.name "github-actions[bot]"
+          git config user.email "github-actions[bot]@users.noreply.github.com"
+          git add --all
+          if git diff --staged --quiet; then
+            echo "The built site matches gh-pages. Nothing to publish."
+            exit 0
+          fi
+          git commit -m "Deploy docs from ${SOURCE_REF}@${SOURCE_SHA}"
+          git push origin gh-pages
diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml
deleted file mode 100644
index 12354b2..0000000
--- a/.github/workflows/release-notes.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Release notes
-
-on:
-  push:
-    branches:
-      - main
-      - v6-dev
-  workflow_dispatch:
-
-permissions:
-  contents: read
-
-jobs:
-  update_release_draft:
-    permissions:
-      # allow release-drafter/release-drafter to create GitHub releases and add labels to PRs
-      contents: write
-      pull-requests: write
-    runs-on: ubuntu-latest
-    if: github.repository == 'twbs/bootstrap'
-    steps:
-      - uses: release-drafter/release-drafter@34d80673e067bdc0c24568d3af899c216adcfaa9 # v7.7.0
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}