diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..d3f94de
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,31 @@
+version: 2
+
+updates:
+ - package-ecosystem: npm
+ directory: /website
+ schedule:
+ interval: weekly
+ target-branch: main
+ open-pull-requests-limit: 3
+ cooldown:
+ default-days: 7
+ semver-major-days: 30
+ semver-minor-days: 7
+ semver-patch-days: 3
+ groups:
+ development-dependencies:
+ dependency-type: development
+ update-types:
+ - minor
+ - patch
+
+ - package-ecosystem: github-actions
+ directory: /
+ schedule:
+ interval: weekly
+ target-branch: main
+ open-pull-requests-limit: 1
+ groups:
+ github-actions:
+ patterns:
+ - "*"
diff --git a/.github/workflows/pages-deploy.yml b/.github/workflows/pages-deploy.yml
new file mode 100644
index 0000000..27fcca9
--- /dev/null
+++ b/.github/workflows/pages-deploy.yml
@@ -0,0 +1,151 @@
+name: Pages deployment
+
+on:
+ workflow_run:
+ workflows:
+ - Website checks
+ types:
+ - completed
+ workflow_dispatch:
+ inputs:
+ run_id:
+ description: Successful Website checks run containing inkcre-website-dist
+ required: true
+ type: number
+
+permissions:
+ actions: read
+ contents: read
+
+concurrency:
+ group: pages-main
+ cancel-in-progress: true
+
+jobs:
+ identity:
+ name: Resolve trusted production identity
+ if: >-
+ github.event_name == 'workflow_dispatch' || (
+ github.event.workflow_run.conclusion == 'success' &&
+ github.event.workflow_run.head_branch == 'main'
+ )
+ runs-on: ubuntu-latest
+ outputs:
+ head_sha: ${{ steps.identity.outputs.head_sha }}
+ run_id: ${{ steps.identity.outputs.run_id }}
+ steps:
+ - name: Resolve the exact current main artifact
+ id: identity
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const runId = context.eventName === 'workflow_dispatch'
+ ? Number(context.payload.inputs.run_id)
+ : context.payload.workflow_run.id
+ const { data: run } = await github.rest.actions.getWorkflowRun({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ run_id: runId,
+ })
+ if (run.name !== 'Website checks' || run.path !== '.github/workflows/website-check.yml') {
+ core.setFailed('Artifact must come from the trusted Website checks workflow.')
+ return
+ }
+ if (run.conclusion !== 'success' || run.head_branch !== 'main') {
+ core.setFailed('Production delivery requires a successful main run.')
+ return
+ }
+ const currentMain = await github.rest.git.getRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: 'heads/main',
+ })
+ if (currentMain.data.object.sha !== run.head_sha) {
+ core.setFailed('Production delivery requires the current exact main head.')
+ return
+ }
+ core.setOutput('head_sha', run.head_sha)
+ core.setOutput('run_id', String(runId))
+
+ deploy:
+ name: Deploy checked website artifact
+ needs: identity
+ permissions:
+ actions: read
+ contents: read
+ deployments: write
+ runs-on: ubuntu-latest
+ timeout-minutes: 20
+ environment:
+ name: production
+ url: https://inkcre.dev
+ steps:
+ - name: Checkout the trusted delivery controller
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ ref: main
+ path: controller
+ persist-credentials: false
+
+ - name: Set up Node
+ uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
+ with:
+ node-version-file: controller/website/package.json
+
+ - name: Download the exact checked artifact
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: inkcre-website-dist
+ path: .pages-delivery/dist
+ run-id: ${{ needs.identity.outputs.run_id }}
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Reverify main before delivery
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ RELEASE_HEAD_SHA: ${{ needs.identity.outputs.head_sha }}
+ with:
+ script: |
+ const currentMain = await github.rest.git.getRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: 'heads/main',
+ })
+ if (currentMain.data.object.sha !== process.env.RELEASE_HEAD_SHA) {
+ core.setFailed('Main changed after artifact selection; refusing delivery.')
+ }
+
+ - name: Ensure the Pages project
+ run: node controller/website/scripts/configure-pages.mjs project
+ env:
+ CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
+ CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
+ CLOUDFLARE_PAGES_DOMAIN: inkcre.dev
+ CLOUDFLARE_PAGES_PROJECT: ${{ vars.CLOUDFLARE_PAGES_PROJECT }}
+
+ - name: Deploy to Cloudflare Pages
+ id: pages
+ uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
+ with:
+ apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
+ accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
+ packageManager: npm
+ wranglerVersion: 4.114.0
+ workingDirectory: .pages-delivery
+ command: >-
+ pages deploy dist --project-name=${{ vars.CLOUDFLARE_PAGES_PROJECT }} --branch=main
+
+ - name: Ensure the custom domain
+ run: node controller/website/scripts/configure-pages.mjs domain
+ env:
+ CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
+ CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
+ CLOUDFLARE_PAGES_DOMAIN: inkcre.dev
+ CLOUDFLARE_PAGES_PROJECT: ${{ vars.CLOUDFLARE_PAGES_PROJECT }}
+
+ - name: Smoke-test Pages and inkcre.dev
+ run: node controller/website/scripts/verify-pages-deployment.mjs
+ env:
+ CLOUDFLARE_PAGES_DEPLOYMENT_ID: ${{ steps.pages.outputs.pages-deployment-id }}
+ CLOUDFLARE_PAGES_DEPLOYMENT_URL: ${{ steps.pages.outputs.deployment-url }}
+ INKCRE_WEBSITE_ORIGIN: https://inkcre.dev
diff --git a/.github/workflows/website-check.yml b/.github/workflows/website-check.yml
new file mode 100644
index 0000000..8dce620
--- /dev/null
+++ b/.github/workflows/website-check.yml
@@ -0,0 +1,53 @@
+name: Website checks
+
+on:
+ pull_request:
+ branches:
+ - main
+ push:
+ branches:
+ - main
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+concurrency:
+ group: website-checks-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ website:
+ name: Website contract
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ steps:
+ - name: Checkout
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+
+ - name: Install the pinned pnpm release
+ uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
+ with:
+ package_json_file: website/package.json
+
+ - name: Set up Node
+ uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
+ with:
+ node-version-file: website/package.json
+ cache: pnpm
+ cache-dependency-path: website/pnpm-lock.yaml
+
+ - name: Install the frozen website package
+ run: pnpm --dir website install --frozen-lockfile
+
+ - name: Verify the website contract
+ run: pnpm --dir website check
+
+ - name: Upload the exact checked website artifact
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: inkcre-website-dist
+ path: website/.vitepress/dist
+ if-no-files-found: error
+ include-hidden-files: true
+ retention-days: 7
diff --git a/tasks/vitepress-documentation-site/foundation-audit.md b/tasks/vitepress-documentation-site/foundation-audit.md
new file mode 100644
index 0000000..d45f763
--- /dev/null
+++ b/tasks/vitepress-documentation-site/foundation-audit.md
@@ -0,0 +1,195 @@
+# VitePress Website Evolution Foundation Audit
+
+Date: 2026-07-28
+
+## Purpose
+
+This audit asks a stricter question than whether the current proposal can build: which early
+decisions become expensive after URLs are published, content grows, or CI becomes a merge
+contract?
+
+The answer is not to pre-build the future site. It is to establish a few stable seams now and
+leave reversible features unimplemented.
+
+## Decision Matrix
+
+| Concern | Correct early decision | Activation point |
+|---|---|---|
+| Site boundary | Keep one independent `website/` package and expose only its content root. | Initial scaffold |
+| Locale-ready source | Store the default-language source in `website/content/en/**`; rewrite it to public root routes. | Initial scaffold |
+| Public URL shape | Use `base: '/'`, `cleanUrls: true`, extensionless links, and stable section-index routes. | Initial scaffold |
+| Active locales | Configure only the default root locale; do not advertise an incomplete second locale. | Initial scaffold |
+| Content conventions | Use one H1, useful page descriptions, public-route links, and explicit anchors for durable deep links. | First page |
+| Formatting | Add package-local EditorConfig and pinned formatter checks before content accumulates. | Initial scaffold |
+| CI contract | Run one always-reporting required check with frozen install, least privilege, concurrency, timeout, and pinned actions. | First CI slice |
+| Dependency upkeep | Add a scoped weekly updater for `/website`, without auto-merge. | First CI slice |
+| Canonical origin | Confirm hostname, canonical URLs, sitemap hostname, robots behavior, and social URLs. | Before first public deployment |
+| Redirect ownership | Keep direct redirects in version control under the site public directory. | Before the first published route moves |
+| Section namespaces | Choose a durable route before publishing the first page in that section; do not create placeholders now. | First section page |
+| Search and custom UI | Add only after corpus size or a real reader need justifies them. | Later pressure |
+
+## Recommended Initial Route Contract
+
+The initial configuration should encode:
+
+```text
+source root: website/content
+default source: website/content/en/**
+default public root: /**
+future Chinese root: /zh/**
+deployment base: /
+clean URLs: enabled
+active locales: English root only
+```
+
+The relevant VitePress model is:
+
+```text
+srcDir: 'content'
+base: '/'
+cleanUrls: true
+rewrites: { 'en/:rest*': ':rest*' }
+locales.root: English
+```
+
+English at the public root is a recommendation, not yet a confirmed product decision. It
+matches the language of the current durable Hub documents and avoids an `/en/` migration if
+Chinese is added later. Sir should confirm it before implementation.
+
+Public route rules:
+
+- `/` is the simple site index.
+- Section indexes use a trailing slash, for example `/manual/`.
+- Leaf pages are extensionless, for example `/manual/getting-started`.
+- Route segments are lowercase ASCII kebab-case and do not contain numeric ordering prefixes.
+- Internal Markdown links target public routes and omit `.md` and `.html`.
+- A heading used as a durable cross-page target receives an explicit custom anchor.
+- Once published, a route is an external contract; a move requires a direct permanent redirect.
+
+Candidate future namespaces are `/manual/`, `/developer/`, and `/about/`. They reserve no content
+and should not appear in navigation until real pages exist. Their names must be confirmed before
+the first page in each section is published, not necessarily for the one-page scaffold.
+
+## Why This Must Be Done Early
+
+### Locale-ready source without locale-prefixed default URLs
+
+VitePress itself stores English under `docs/en/**` and rewrites it to root routes. This separates
+source ownership from public addresses: adding `docs/zh/**` does not force English URLs or files
+to move.
+
+Starting with `content/index.md` is simpler only for the first page. Moving an established
+corpus to `content/en/**` later creates a broad source rename, affects relative links and edit
+history, and makes translation rollout harder to review.
+
+### URL shape is independent from canonical-host metadata
+
+`cleanUrls` controls the shape of every internal link, so postponing it creates avoidable URL
+and redirect churn. Cloudflare Pages serves clean paths for generated `.html` and `index.html`
+files, so the intended host supports this contract.
+
+By contrast, sitemap hostnames, canonical links, Open Graph URLs, and production robots rules
+depend on the final origin. Those should be decided before publication, not invented during the
+local scaffold.
+
+### Formatting is a content migration concern
+
+Adding a formatter after dozens of Markdown pages creates a repository-wide mechanical rewrite
+that obscures meaningful history. A package-local EditorConfig, pinned formatter, and
+`format:check` gate are small now and expensive to retrofit.
+
+Execution-time inspection found that modern neighboring InKCre repositories use Oxfmt. Its
+official language support includes Markdown, TypeScript, JSON, and YAML, so the website should
+reuse a pinned Oxfmt release instead of creating a project-local Prettier exception.
+
+### A required CI check must always report
+
+GitHub documents that a workflow skipped by path filtering can leave a required check pending.
+For this small site, an always-run website check is cheaper and more reliable than a
+path-filtered required workflow. If execution cost later becomes material, an always-reporting
+change-detection job can replace it without changing the branch-protection contract.
+
+## Evolution Pre-mortem
+
+### Adding Chinese
+
+Add `website/content/zh/**` and a `zh` locale while keeping English at root. Do not enable the
+locale switcher merely because one translated page exists.
+
+A disposable VitePress 2 fixture showed that the build succeeds even when the generated locale
+switch points to a missing counterpart route. Therefore translation rollout needs one of:
+
+- route parity for the published locale set; or
+- a deliberate locale-switch implementation that falls back safely.
+
+The minimal site should use only the root locale until that rule is implemented.
+
+### Expanding sections
+
+Navigation and sidebar data can remain inline while there is one page and split into
+section-local configuration modules later. Do not create empty directories, placeholder pages,
+or speculative navigation merely to reserve the future information architecture.
+
+### Moving a published page
+
+Keep redirect rules in `website/content/public/_redirects` when the first redirect is needed.
+Use direct old-to-new mappings rather than chains, and test both the canonical destination and
+the old URL in deployment smoke checks.
+
+### Versioning unstable product documentation
+
+Keep current documentation versionless at root. Do not introduce `/latest/`, `/v0/`, or version
+subdomains before InKCre has an explicit multi-version support obligation. If historical
+documentation later becomes necessary, preserve current routes and add an archive rather than
+moving the current corpus.
+
+### Deploying
+
+Build once in the unprivileged verification job and deploy that exact artifact in a separate
+privileged job. Before first publication, confirm the canonical hostname and add sitemap,
+canonical/social metadata, production robots behavior, and preview `noindex` handling.
+
+Cloudflare's default cache behavior is sufficient for the first static site; custom global
+cache rules are not an early requirement.
+
+## Disposable Route Experiment
+
+A VitePress `2.0.0-alpha.18` fixture used `srcDir: 'content'`, `cleanUrls: true`, an
+`en/:rest* -> :rest*` rewrite, and only a root English locale.
+
+Observed output:
+
+- `content/en/index.md` produced `/index.html`, not `/en/index.html`;
+- `content/en/manual/index.md` produced `/manual/index.html`;
+- `content/en/manual/getting-started.md` produced
+ `/manual/getting-started.html`;
+- generated internal links used clean public paths without `.html`;
+- adding a `zh` locale produced `/zh/**`;
+- a missing Chinese counterpart did not fail the production build.
+
+This validates the proposed source/public split and disproves an assumption that the normal
+VitePress build alone enforces translation-route parity.
+
+## Intentionally Reversible Later
+
+No initial placeholder or abstraction is needed for:
+
+- search;
+- custom theme components and CSS;
+- split navigation/sidebar modules;
+- edit links and last-updated display;
+- PWA, Twoslash, LLM exports, analytics, or external search;
+- data loaders and generated pages without an executable canonical owner;
+- a dedicated external-link crawler.
+
+## Primary Evidence
+
+- [VitePress routing and rewrites](https://vitepress.dev/guide/routing)
+- [VitePress internationalization](https://vitepress.dev/guide/i18n)
+- [VitePress Markdown custom anchors](https://vitepress.dev/guide/markdown)
+- [VitePress asset and public-directory behavior](https://vitepress.dev/guide/asset-handling)
+- [VitePress's own locale-ready configuration](https://github.com/vuejs/vitepress/blob/430a890a17910593e26e9654b141ef3855ecceac/docs/.vitepress/config.ts)
+- [Oxfmt language support](https://oxc.rs/docs/guide/usage/formatter/language-support)
+- [Cloudflare Pages serving behavior](https://developers.cloudflare.com/pages/configuration/serving-pages/)
+- [Cloudflare Pages redirects](https://developers.cloudflare.com/pages/configuration/redirects/)
+- [GitHub Actions path-filter status behavior](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax)
diff --git a/tasks/vitepress-documentation-site/implementation-plan.md b/tasks/vitepress-documentation-site/implementation-plan.md
new file mode 100644
index 0000000..316eb62
--- /dev/null
+++ b/tasks/vitepress-documentation-site/implementation-plan.md
@@ -0,0 +1,256 @@
+# VitePress Documentation Site Implementation Plan
+
+Status: local website implemented and verified on 2026-07-28; production deployment is
+authorized and in progress. English owns the public root and future Chinese content will use
+`/zh/`.
+
+## Impact Handshake
+
+- **Address and Object**: add an isolated VitePress package, configuration, locale-ready content
+ root, formatting contract, and simple index under `website/**`; later add one root-level
+ website-check workflow and scoped dependency-updater configuration.
+- **State Diff**: no site runtime or public build -> one locally buildable documentation site
+ whose content is a human-facing projection of Hub truth and whose first URLs can evolve
+ without a default-language migration.
+- **Blast Radius**: Hub-local website development and future static publication move; canonical
+ `00-meta/**`, `10-prd/**`, and `20-product-tdd/**` content and Spoke-local implementations do
+ not. Website-only commits do not require Spoke shared-reference bumps.
+- **Invariants**: canonical Hub owners stay authoritative; VitePress reads only website-owned
+ Markdown; the site does not imply a stable, productized User Manual, Developer Guide, About
+ surface, or marketing landing page.
+- **Verification**: formatting, an explicit dependency audit, deterministic VitePress production
+ build with default dead-link failure, route-output assertions, manual preview acceptance, SVC
+ health/no-op, and `git diff --check`.
+
+## Confirmed Language Contract
+
+Sir confirmed:
+
+```text
+English source: website/content/en/**
+English public URLs: /**
+future Chinese URLs: /zh/**
+active locales now: English root only
+```
+
+This follows the language of the current Hub corpus and VitePress's own source/public split.
+
+The following are engineering defaults rather than additional content commitments:
+
+- deploy the official website at root with `base: '/'`;
+- enable `cleanUrls` from the first build;
+- use extensionless public-route links;
+- keep future sections unpublished until real content exists;
+- keep current documentation versionless.
+
+## Slice 0: Re-check Toolchain
+
+Immediately before mutation, run:
+
+```text
+node --version
+pnpm --version
+npm view vitepress version dist-tags
+npm view vitepress@next version dependencies
+```
+
+Resolve and audit the exact dependency graph in a disposable directory. Stop if the selected
+graph has a high-severity advisory or the minimal fixture no longer builds. Keep this
+network-dependent audit as an explicit dependency-selection and dependency-update check rather
+than embedding it in the deterministic website `check` command.
+
+Prepared baseline from 2026-07-28:
+
+- Node `22.22.3`;
+- pnpm `11.17.0`;
+- exact VitePress `2.0.0-alpha.18`.
+
+These versions are implementation candidates, not timeless project truth. Re-check them instead
+of floating on `latest` or `next`.
+
+## Slice 1: Establish The Isolated Website Package
+
+Create:
+
+```text
+website/
+ README.md
+ package.json
+ pnpm-lock.yaml
+ .editorconfig
+ .gitignore
+ .oxfmtrc.json
+ .vitepress/
+ config.mts
+ content/
+ en/
+ index.md
+ scripts/
+ verify-build.mjs
+```
+
+Use existing InKCre Node package conventions:
+
+- package-local `packageManager`;
+- package-local `devEngines.runtime`;
+- exact Node, pnpm, VitePress, and Oxfmt versions;
+- package-local ignores for `node_modules`, VitePress cache, and build output;
+- `pnpm install --frozen-lockfile` in CI;
+- `dev`, `build`, `preview`, `format`, `format:check`, and deterministic `check` scripts.
+
+The `check` script runs formatting verification, the production build, and generated-route
+verification. Keep the network-dependent advisory audit explicit and separate.
+
+Configure:
+
+```text
+srcDir: 'content'
+base: '/'
+cleanUrls: true
+rewrites: { 'en/:rest*': ':rest*' }
+locales.root: English
+```
+
+Do not point VitePress at the repository root or canonical Hub directories. Do not add a public
+directory until there is a real fixed-name asset or redirect to own.
+
+`website/README.md` records the route and authoring contract so future pages follow it without
+requiring a formatter or URL migration.
+
+## Slice 2: Add The Minimal Website
+
+The initial index contains only:
+
+- repository/site identity;
+- one concise description;
+- links to the canonical Product PRD and Product TDD sources;
+- optionally a link to the source repository.
+
+The page uses one H1 and a useful description. Internal links target public routes and omit
+`.md` and `.html`; headings that become cross-page targets receive explicit anchors.
+
+Use the default VitePress theme with minimal title, description, language, and navigation
+configuration. Keep the default dead-link behavior. Do not add:
+
+- marketing hero copy or feature grids;
+- product CTAs;
+- User Manual, Developer Guide, or About pages;
+- empty future navigation or placeholder directories;
+- copied Hub document trees;
+- a search control for the one-page corpus;
+- sitemap, canonical URLs, or deployment-origin metadata before the hostname is confirmed;
+- PWA, LLM output, Twoslash, custom Markdown transforms, or custom theme components.
+
+Future website pages may summarize or reorganize Hub truth for their audience. They should link
+to canonical sources when useful, but no build-time inclusion or freshness automation is
+required.
+
+## Slice 3: Verify The Local Site
+
+Repository-level verification:
+
+```text
+pnpm --dir website install --frozen-lockfile
+pnpm --dir website check
+pnpm --dir website audit --audit-level high
+svc status --json
+svc init --agent codex --json
+git diff --check
+```
+
+Assert from the production output:
+
+- the index is emitted at `/`, not `/en/`;
+- page language is the selected root locale;
+- no default-language prefix leaks into generated URLs;
+- generated page links are clean and extensionless;
+- default dead-link checking remains enabled;
+- only website-owned Markdown becomes routable.
+
+Manually inspect:
+
+- the production site through `pnpm --dir website preview`;
+- narrow and wide viewport layout;
+- keyboard navigation and visible focus;
+- title, description, and language metadata;
+- simple navigation with no speculative sections;
+- canonical Hub documents remain unchanged.
+
+Do not add an SVC `dev` target in this slice. There is not yet repeated multi-worktree
+coordination pressure or an instance-aware readiness contract to justify it.
+
+## Slice 4: Add The CI And Update Contract
+
+After local verification passes:
+
+1. add one website-check workflow using pinned action SHAs;
+2. trigger it for relevant PR and branch events without workflow-level path filtering, so a
+ required check always reports;
+3. declare least privilege, concurrency cancellation, and a finite timeout;
+4. set up pnpm and Node from `website/package.json`, cache against
+ `website/pnpm-lock.yaml`, then run frozen install and `pnpm --dir website check`;
+5. add a weekly dependency updater scoped to `/website`, without auto-merge;
+6. include GitHub Actions digest updates in the existing repository-level updater contract;
+7. upload static output only when a later deployment slice needs artifact handoff.
+
+Reuse InKCre's toolchain and dependency-update conventions, not the application-specific
+client-web Pages workflow. Do not copy database E2E, SPA fallback, release identity, preview
+cleanup, or Changesets logic.
+
+If CI cost later becomes meaningful, use an always-reporting change-detection job instead of
+making a required workflow skippable.
+
+## Authorized Deployment Slice
+
+Publish through a Cloudflare Pages Direct Upload project named `inkcre-website`:
+
+1. add sitemap hostname, canonical/Open Graph URLs, production robots behavior, and explicit
+ `noindex` headers for `pages.dev` origins;
+2. upload the exact artifact produced by the unprivileged website contract job;
+3. in a separate production-environment job, idempotently ensure the Direct Upload project and
+ `inkcre.dev` custom domain through the Cloudflare Pages API;
+4. deploy the downloaded artifact using the existing organization Cloudflare credentials;
+5. smoke-test the immutable Pages deployment and `https://inkcre.dev`;
+6. keep application deployment at `app.inkcre.dev` independent.
+
+External state in scope:
+
+- allow `InKCre/docs` to consume the existing selected organization secrets
+ `CLOUDFLARE_ACCOUNT_ID` and `CLOUDFLARE_API_TOKEN`;
+- set repository variable `CLOUDFLARE_PAGES_PROJECT=inkcre-website`;
+- create or reconcile the `inkcre-website` Pages project with production branch `main`;
+- attach `inkcre.dev`, allowing Cloudflare to create the apex DNS record and certificate;
+- create a GitHub `production` deployment environment through the workflow.
+
+GitHub preparation completed on 2026-07-28: the selected organization secrets now also allow
+`InKCre/docs`, the repository variable is set, and the `production` environment accepts
+deployments only from `main`. The workflow remains responsible for idempotently reconciling the
+Cloudflare Pages project and custom domain.
+
+When the first published route moves, add its direct permanent redirect under
+`website/content/public/_redirects` and verify both old and new URLs. Do not add custom global
+cache rules until measured behavior requires them.
+
+## Deferred Content Expansion
+
+Add User Manual, Developer Guide, About, and a fuller Landing only when real content and stable
+product pressure exist. Candidate route namespaces are `/manual/`, `/developer/`, and `/about/`;
+confirm each before its first page is published rather than creating placeholders now.
+
+When Chinese content enters scope, add `/zh/**` only after the published locale set has route
+parity or a deliberate fallback-capable locale switch. A normal VitePress build does not detect
+missing translated counterparts.
+
+Keep current documentation versionless. Add historical versions only when InKCre has a real
+multi-version support obligation, without moving the current public routes.
+
+## Stop Conditions
+
+Return to discussion before continuing if:
+
+- website implementation would require changing canonical Hub truth;
+- a dependency or VitePress prerelease migration changes the planned minimal surface;
+- site setup starts to introduce root workspace metadata or unrelated repository tooling;
+- dead-link repair would require publishing an internal page;
+- implementation starts to create speculative product documentation;
+- deployment or external-domain work enters scope without explicit authorization.
diff --git a/tasks/vitepress-documentation-site/industry-benchmark.md b/tasks/vitepress-documentation-site/industry-benchmark.md
new file mode 100644
index 0000000..aa0d5bc
--- /dev/null
+++ b/tasks/vitepress-documentation-site/industry-benchmark.md
@@ -0,0 +1,262 @@
+# VitePress Documentation Site Industry Benchmark
+
+Date: 2026-07-28
+
+## Purpose And Method
+
+This benchmark tests both whether the planned InKCre boundary is sound and which foundations
+successful VitePress projects establish before content scale makes them expensive to change. It
+is not a feature checklist or a justification of choices already made.
+
+The sample deliberately covers three different pressures:
+
+- a dedicated documentation repository: Vue documentation;
+- documentation packages inside product repositories: VitePress, Vite, and Vitest;
+- large generated or multi-surface documentation systems: VueUse and UnoCSS.
+
+All repository claims below were checked against the named default-branch commit and official
+VitePress documentation. Popularity is only a filter for operational evidence, not proof that
+every mechanism should be copied. At the time of inspection, the repositories ranged from about
+3,200 to 82,000 GitHub stars.
+
+## Repository Comparison
+
+| Project | Snapshot | Site topology and source model | Build and publication | Relevant lesson |
+|---|---|---|---|---|
+| [Vue docs](https://github.com/vuejs/docs/tree/7681134fd8505e61a265d161d73d28acb3c74822) | `7681134` | The repository is the site. VitePress configuration lives in `.vitepress/`, while `srcDir: 'src'` keeps public Markdown in one content root. Navigation is explicit; theme and marketing integrations are extensive. | `dev`, `build`, `preview`, and Vue type-check scripts; VitePress build retains default dead-link failure. Netlify builds `.vitepress/dist`; there is no PR site-build workflow. | Closest positioning match. Adopt the bounded content root and typed configuration, but not its mature marketing/theme surface or provider-only validation. |
+| [VitePress](https://github.com/vuejs/vitepress/tree/430a890a17910593e26e9654b141ef3855ecceac) | `430a890` | `docs/` is a workspace package that dogfoods the framework through `workspace:*`. Locale content, translation tracking, search, and metadata are split only because the project serves the framework itself in many languages. | Framework `check` covers formatting, build, types, unit, init, and browser E2E. Netlify separately builds the production docs and translation report. | Treat VitePress's tests as framework-owner obligations, not normal site requirements. Its minimal default-theme extension is more relevant than its locale and E2E machinery. |
+| [Vite](https://github.com/vitejs/vite/tree/d17d739eedc4e8ede5973f1533826f27554c2078) | `d17d739` | `docs/` is a workspace package inside the product monorepo. Markdown is primary; small data loaders and a `buildEnd` hook produce blog/RSS data. Version data comes from the product package. | `test-docs` runs the VitePress build in GitHub CI. Netlify runs `ci-docs`, which builds product packages before the site because the docs consume them. | Strongest CI reference: make the production docs build a merge gate. Do not copy the product-build dependency, RSS hook, custom theme, or version-site redirects. |
+| [Vitest](https://github.com/vitest-dev/vitest/tree/eb16ab80330c7f33cc894eede76633191358d7b4) | `eb16ab8` | `docs/` is a workspace package. Most content is handwritten, while CLI pages are generated from executable CLI definitions. The site adds PWA, custom theme, and build-time contributor data. | CI checks that generated CLI content is current. Netlify performs the full docs build, including a product build and network prefetch. | Generate only content with an executable canonical owner and a demonstrated drift problem. Avoid PWA and build-time network dependencies for the InKCre first slice. |
+| [VueUse](https://github.com/vueuse/vueuse/tree/a7d9aba02985c8f71931b99ae903b458a8d652da) | `a7d9aba` | VitePress uses `packages/` as its site root. Function metadata, types, source files, demos, Git history, and Markdown transforms produce navigation and rich API pages. | A high-memory build first refreshes metadata and package outputs. Netlify publishes the result; repository CI primarily protects the library. | This is a scale-specific code-to-doc projection system. It is evidence against introducing generation before InKCre has many uniform executable documentation units. |
+| [UnoCSS](https://github.com/unocss/unocss/tree/e28a47c557fe179935a37a4fbeb650292d0d1d5a) | `e28a47c` | `docs/` remains mostly handwritten with explicit navigation, while shared generated package data powers documentation, playground, and interactive surfaces. | Netlify builds product packages, docs, playground, and interactive apps together. CI spans operating systems and product tests. | Its local search and narrow dead-link exceptions are reusable later. Its multi-product build, interactive tools, and package-generation graph are outside InKCre's current pressure. |
+
+## Version And Toolchain Evidence
+
+The external sample has already moved to the VitePress 2 prerelease line:
+
+| Project | Declared VitePress version |
+|---|---|
+| Vue docs | `^2.0.0-alpha.17` |
+| Vite | `^2.0.0-alpha.18` |
+| Vitest | `2.0.0-alpha.16` |
+| VueUse | `^2.0.0-alpha.17` through its workspace catalog |
+| UnoCSS | `^2.0.0-alpha.17` through its workspace catalog |
+
+VitePress itself was at `2.0.0-alpha.18`. This supports the preflight conclusion that VitePress
+2 is a credible implementation candidate, but does not justify floating on `next`. InKCre
+should keep one exact version in `website/package.json` and its lockfile, then re-evaluate that
+pin when implementation starts.
+
+The sample consistently declares pnpm and uses Node 20 or newer; current hosted builds commonly
+use Node 24. InKCre's prepared Node `22.22.3` and pnpm `11.17.0` remain compatible candidates,
+subject to the execution-time package check.
+
+## Cross-Project Findings
+
+### 1. A bounded site root is the common architectural seam
+
+Every project gives VitePress a deliberate source boundary: a dedicated repository root, a
+`docs/` package, `srcDir`, or a package subtree. None treats unrelated repository Markdown as
+implicitly public.
+
+This supports:
+
+```text
+website/ package and site root
+ .vitepress/ site configuration
+ content/ only routable Markdown
+```
+
+It also supports the prior projection decision. Mature projects generate from code only when
+their product topology makes code an appropriate canonical owner; they do not demonstrate a
+general need to compile an internal collaboration Hub directly.
+
+### 2. The production build is the basic content contract
+
+VitePress's `ignoreDeadLinks` default is `false`: a production build fails on dead links unless
+the site deliberately opts out. The sampled sites generally rely on this behavior instead of a
+second internal-link checker. Vite goes further and executes the docs build in GitHub CI.
+
+For InKCre:
+
+- `pnpm --dir website check` should be deterministic and include the production build;
+- do not set `ignoreDeadLinks: true`;
+- add only narrow exceptions if a real non-page route later requires one;
+- do not add browser E2E while the site is static Markdown plus the default theme.
+
+### 3. Build verification and deployment are separate concerns
+
+Most sampled sites publish through Netlify, while repository CI protects selected source
+contracts. The official VitePress GitHub Pages example also separates a build job from the
+privileged deployment job and gives the deployment job explicit permissions and concurrency.
+
+For InKCre:
+
+- add a PR/push site-build workflow after the local package works;
+- use frozen installation and pinned action SHAs;
+- keep deployment, credentials, domain metadata, previews, and post-deploy smoke in the later
+ deployment slice;
+- build once and deploy the checked artifact when publication enters scope.
+
+### 4. Search follows corpus size
+
+Vite, Vitest, and UnoCSS use built-in local search. Vue docs, VitePress, and VueUse use Algolia
+because their established corpora and traffic justify an external index. VitePress supports
+local search without an external service.
+
+The one-page InKCre slice should show no search control. When reader-facing documentation pages
+exist, local search is the default next step; Algolia requires separate scale or relevance
+evidence.
+
+### 5. URL shape is an early contract; origin metadata follows the hostname
+
+Large sites commonly enable clean URLs, sitemap generation, canonical metadata, Open Graph
+metadata, edit links, and last-updated timestamps. They do not all have the same activation
+point:
+
+- public route shape, `base`, and internal-link conventions affect every page and should be
+ stable from the first build;
+- Cloudflare Pages supports clean paths for the intended static output, so enable `cleanUrls`
+ in the first slice rather than migrating published links later;
+- sitemap, canonical URLs, and `og:url` require the confirmed public hostname;
+- `lastUpdated` requires useful Git history in the build checkout;
+- edit links become useful when the site has reader-facing documentation pages.
+
+The initial index still needs correct language, title, description, responsive behavior, and
+accessible default-theme interaction.
+
+### 6. Locale-ready source is cheaper than a later source-tree migration
+
+VitePress itself stores default English content under `docs/en/**`, rewrites it to the public
+root, and places other locales under prefixes such as `/zh/`. This preserves root English URLs
+while keeping source ownership explicit.
+
+InKCre should start with `website/content/en/**` and publish it at root, subject to Sir
+confirming English as the default public language. Only the root locale should be active now.
+A disposable build proved that VitePress does not fail when a locale switch points to a missing
+translation, so a future locale needs route parity or a deliberate fallback-capable switch.
+
+### 7. Formatting, CI status, and dependency updates are lifecycle foundations
+
+Vue docs and VitePress establish formatting configuration and checks before their content
+corpora grow. Vite and Vitest run documentation build or repository checks in CI. VitePress,
+Vite, and neighboring InKCre packages also show least-privilege workflows, concurrency control,
+frozen dependency installation, and automated dependency maintenance.
+
+These details are inexpensive in the first engineering slice and costly to retrofit:
+
+- add package-local EditorConfig and pinned formatter configuration;
+- make formatting verification and the production build the deterministic `check`;
+- use one always-reporting required workflow;
+- avoid workflow-level path filters for a required check because a skipped workflow can remain
+ pending in GitHub;
+- add a weekly updater scoped to `/website`, with no auto-merge, because the selected VitePress
+ version is a pinned prerelease.
+
+A dedicated external-link crawler is not a consistent baseline across the sample. Add one only
+when outbound-link volume creates a demonstrated maintenance problem.
+
+The external sample establishes the need for an early formatting contract, not a mandatory
+formatter brand. Execution-time inspection found that modern neighboring InKCre repositories
+use Oxfmt, whose current language support includes Markdown and the site's configuration
+formats. The implementation therefore reuses pinned Oxfmt rather than introducing Prettier as a
+local exception.
+
+### 8. Generated content is justified by a canonical executable owner
+
+Vitest generates CLI documentation from CLI definitions. VueUse derives pages from function
+metadata, source, types, and demos. UnoCSS shares generated package data with its docs and
+interactive tools. Each generation graph exists because there are many uniform units and a
+real executable owner.
+
+This does not justify a Hub-to-website mirror. InKCre has already accepted editorial projection,
+and the current site has no repetitive executable documentation surface. If a future CLI,
+schema, or API becomes canonical and produces many pages, add one narrow generator for that
+surface and verify generated output freshness.
+
+## InKCre Engineering Baseline
+
+### Adopt in the first implementation slice
+
+- one independent `website/` package with its own exact tool declarations and lockfile;
+- one explicit website-owned Markdown root through `srcDir: 'content'`, with default-language
+ source under `content/en/**` rewritten to public root routes;
+- `base: '/'`, `cleanUrls: true`, extensionless public links, and stable route conventions;
+- only the root locale until a second locale has route parity or safe fallback behavior;
+- default VitePress theme, typed minimal configuration, and a simple index;
+- package-local EditorConfig and pinned Oxfmt configuration;
+- `dev`, `build`, `preview`, `format`, `format:check`, and deterministic `check` scripts;
+- production build as the dead-link and static-rendering gate;
+- one always-reporting GitHub Actions workflow after local verification, using frozen install,
+ least privilege, concurrency cancellation, timeout, and pinned action SHAs;
+- a weekly dependency updater scoped to `/website`, without auto-merge;
+- dependency audit as an explicit dependency-selection and update check;
+- production-output assertions for root rewrite and clean-link behavior;
+- manual wide/narrow viewport and keyboard review.
+
+### Add only when triggered
+
+- local search: when a reader-facing documentation corpus exists;
+- edit links and last-updated data: when documentation pages warrant them;
+- sitemap, canonical/Open Graph URLs, robots behavior, and deployment smoke: when the hostname
+ is confirmed;
+- custom theme components: when a real brand or reader interaction cannot be expressed by the
+ default theme;
+- generated pages: when an executable canonical owner and repetitive page family exist;
+- source-controlled redirects: when the first published URL changes;
+- version routing: when a real multi-version support obligation exists.
+
+### Do not include in the current plan
+
+- Algolia, PWA, offline caching, or browser E2E;
+- Twoslash, Graphviz, tabs, group icons, or custom Markdown transforms;
+- `vitepress-plugin-llms` or another website-derived agent corpus: the website is not InKCre's
+ canonical agent knowledge surface;
+- a published second locale, translation tracking, version subdomains, or redirect fleets;
+- contributor, sponsor, avatar, analytics, advertising, or marketing integrations;
+- generated Hub mirrors, source-route manifests, hash/freshness gates, or global dead-link
+ suppression;
+- product builds, playgrounds, interactive apps, or Spoke test matrices in the website pipeline.
+
+## Changes To The Prepared Plan
+
+The benchmark preserves the selected architecture and narrows the first slice:
+
+1. Keep `website/content` and the editorial projection boundary.
+2. Put default-language source under `content/en/**`, rewrite it to public root routes, and
+ activate only the root locale.
+3. Set the root deployment base, clean URLs, extensionless links, formatting contract, and
+ route conventions in the first slice.
+4. Omit search from the one-page site; prefer local search when content expands.
+5. Let VitePress production build enforce internal dead links, but add explicit output
+ assertions for route rewrites because the build does not prove locale parity.
+6. Keep `check` deterministic. Run the network-dependent dependency audit explicitly during
+ dependency selection and updates instead of embedding it in every `check`.
+7. Use `preview` for manual acceptance and later deployment smoke, not as a background process
+ inside the normal CI check.
+8. Use an always-reporting CI workflow and a scoped weekly dependency updater from the first CI
+ slice.
+9. Defer hostname-dependent metadata, not URL shape, until deployment is confirmed.
+
+## Primary Sources
+
+- [VitePress site configuration](https://vitepress.dev/reference/site-config)
+- [VitePress routing and rewrites](https://vitepress.dev/guide/routing)
+- [VitePress internationalization](https://vitepress.dev/guide/i18n)
+- [VitePress asset handling](https://vitepress.dev/guide/asset-handling)
+- [VitePress search](https://vitepress.dev/reference/default-theme-search)
+- [VitePress deployment](https://vitepress.dev/guide/deploy)
+- [VitePress's own locale-ready configuration](https://github.com/vuejs/vitepress/blob/430a890a17910593e26e9654b141ef3855ecceac/docs/.vitepress/config.ts)
+- [Oxfmt language support](https://oxc.rs/docs/guide/usage/formatter/language-support)
+- [Cloudflare Pages serving behavior](https://developers.cloudflare.com/pages/configuration/serving-pages/)
+- [Cloudflare Pages redirects](https://developers.cloudflare.com/pages/configuration/redirects/)
+- [GitHub Actions path-filter status behavior](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax)
+- [Vue docs package](https://github.com/vuejs/docs/blob/7681134fd8505e61a265d161d73d28acb3c74822/package.json)
+- [Vue docs configuration](https://github.com/vuejs/docs/blob/7681134fd8505e61a265d161d73d28acb3c74822/.vitepress/config.ts)
+- [Vite docs package](https://github.com/vitejs/vite/blob/d17d739eedc4e8ede5973f1533826f27554c2078/docs/package.json)
+- [Vite docs CI gate](https://github.com/vitejs/vite/blob/d17d739eedc4e8ede5973f1533826f27554c2078/.github/workflows/ci.yml)
+- [Vitest docs package](https://github.com/vitest-dev/vitest/blob/eb16ab80330c7f33cc894eede76633191358d7b4/docs/package.json)
+- [VueUse site configuration](https://github.com/vueuse/vueuse/blob/a7d9aba02985c8f71931b99ae903b458a8d652da/packages/.vitepress/config.ts)
+- [VueUse Markdown transform](https://github.com/vueuse/vueuse/blob/a7d9aba02985c8f71931b99ae903b458a8d652da/packages/.vitepress/plugins/markdownTransform.ts)
+- [UnoCSS site configuration](https://github.com/unocss/unocss/blob/e28a47c557fe179935a37a4fbeb650292d0d1d5a/docs/.vitepress/config.ts)
+- [UnoCSS deployment configuration](https://github.com/unocss/unocss/blob/e28a47c557fe179935a37a4fbeb650292d0d1d5a/netlify.toml)
diff --git a/tasks/vitepress-documentation-site/packet.md b/tasks/vitepress-documentation-site/packet.md
new file mode 100644
index 0000000..89d1a3f
--- /dev/null
+++ b/tasks/vitepress-documentation-site/packet.md
@@ -0,0 +1,154 @@
+# VitePress Documentation Site
+
+- **Objective**: establish and publish an independent VitePress website at `https://inkcre.dev`
+ as a human-facing projection of the InKCre shared-doc Hub. Keep only a simple index page while
+ the product is unstable, and preserve the future public-site information architecture without
+ prematurely writing productized guidance.
+- **Guardrails**: keep this repository authoritative for shared product and cross-unit truth;
+ keep the VitePress project isolated under `website/`; do not turn the current index into a
+ marketing landing page; do not create placeholder User Manual, Developer Guide, or About
+ sections; do not treat website wording as a replacement owner for canonical Hub truth; do not
+ add manifest, hash, or route machinery merely to eliminate editorial drift; do not expose
+ `tasks/**`, `AGENTS.md`, generated SVC integration, local configuration, or other Hub-local
+ collaboration state; keep Spoke-local implementation, deployment, and task truth in each
+ Spoke; preserve the existing Hub-first and isolated-commit workflow.
+- **Verification**: `svc status --json` remains healthy and `svc init --agent codex --json`
+ remains a no-op; VitePress reads only website-owned content under `website/`; formatting and
+ the simple home page pass a deterministic production check with default dead-link failure;
+ route-output assertions prove that the default language stays at root and links remain clean;
+ manual preview passes; the selected dependency graph passes an explicit audit; canonical Hub
+ documents remain unchanged; GitHub deploys the exact checked artifact to Cloudflare Pages;
+ `inkcre.dev` serves HTTPS, canonical metadata, sitemap, robots, and a real `404`; Pages preview
+ origins remain `noindex`; `git diff --check` passes.
+- **Current Truth**: the repository now has an independent `website/` package with only
+ website-owned Markdown routable. English source begins under `content/en/**` and rewrites to
+ clean public root routes; only the English root locale is active. The package pins Node
+ `22.22.3`, pnpm `11.17.0`, VitePress `2.0.0-alpha.18`, and Oxfmt `0.60.0` in package metadata
+ and its lockfile. The simple index describes active development, links to canonical Hub
+ sources, and creates no speculative sections. Its deterministic check formats, builds with
+ default dead-link failure, and verifies generated language and URL contracts. One
+ always-reporting GitHub Actions workflow protects the website contract with pinned actions,
+ frozen install, least privilege, concurrency cancellation, and timeout. Dependabot maintains
+ `/website` npm dependencies and root GitHub Actions weekly without auto-merge. Product
+ behavior and language remain in `10-prd/**`; cross-unit contracts remain in
+ `20-product-tdd/**`; Hub/Spoke operations remain in `00-meta/**`; `tasks/**` remains volatile.
+ The website is an editorial projection and no canonical Hub document changed. The repository
+ can consume the existing organization Cloudflare account and API-token secrets, owns
+ `CLOUDFLARE_PAGES_PROJECT=inkcre-website`, and has a GitHub `production` environment restricted
+ to the `main` branch.
+- **Next Step**: publish through the normal branch, pull-request, and main-branch workflow path;
+ monitor the Pages deployment and verify `inkcre.dev`.
+
+## Supporting Material
+
+- [Implementation plan](implementation-plan.md)
+- [Preflight evidence and projection decision](preflight.md)
+- [Industry benchmark and selected engineering baseline](industry-benchmark.md)
+- [Evolution foundation audit](foundation-audit.md)
+
+## Confirmed Direction
+
+- The repository remains the InKCre shared documentation Hub.
+- `website/` is an independent presentation, content, and build surface.
+- The initial website is documentation-first and has only a simple home page.
+- Website content is an editorial projection of Hub truth, not a byte-identical rendering.
+- Ordinary editing judgment and source links are sufficient; zero-drift automation is not a
+ requirement.
+- The website may later become the unified InKCre public site, but current implementation must
+ not imply product maturity that does not exist.
+- Responsive layout, basic accessibility, essential page metadata, dead-link checks, and a
+ website-local content root remain valid first-slice requirements.
+- Search remains a future requirement but is omitted from the one-page site. Built-in local
+ search is the default when a reader-facing documentation corpus exists.
+- The website publishes at `inkcre.dev`; the application remains independently owned at
+ `app.inkcre.dev`.
+
+## Confirmed Language Contract
+
+Sir confirmed:
+
+```text
+English source: website/content/en/**
+English public URLs: /**
+future Chinese URLs: /zh/**
+active locales now: English root only
+```
+
+This matches the current English Hub corpus and avoids a later English source-tree and URL
+migration.
+
+Candidate future section namespaces are `/manual/`, `/developer/`, and `/about/`. They remain
+unpublished and absent from navigation; confirm each before its first real page rather than
+creating placeholders now.
+
+## Content Topology
+
+```text
+authoritative Hub truth
+ 00-meta/** Hub/Spoke operating contracts
+ 10-prd/** product truth and vocabulary
+ 20-product-tdd/** cross-unit technical contracts
+ |
+ | editorial projection, summary, and links
+ v
+website/ public content, VitePress configuration, theme, navigation, assets
+ |
+ v
+static documentation site
+```
+
+The website projection must not make these routable:
+
+```text
+tasks/**
+AGENTS.md
+.agents/**
+docs/index.md
+svc.json
+svc.local.json
+other generated or machine-local collaboration state
+```
+
+## Deferred Information Architecture
+
+These sections describe the intended long-term role of the site. They are preserved for future
+product pressure and must not be scaffolded with speculative content now.
+
+### Landing
+
+- Remain a simple project and documentation index during rapid development.
+- Later, when product claims and availability are stable, it may become a fuller public landing
+ page.
+
+### User Manual
+
+- Task-oriented guidance for actual user journeys.
+- Likely progression: start, concepts, collect, organize, retrieve/use, extensions,
+ troubleshooting.
+- Procedures must be derived from verified client behavior, not inferred from PRD or technical
+ contracts.
+
+### Developer Guide
+
+- Unified orientation for repository topology, architecture, shared runtime, extension
+ development, contracts, and contribution.
+- Spoke-local commands, implementation mechanics, deployment, and recovery remain linked to
+ their Spoke owners rather than copied into the Hub.
+
+### About
+
+- Organization mission, principles, repositories, governance, licensing, contribution, and
+ contact information.
+- Durable organization claims require an explicit owner before publication.
+
+## Projection Decision
+
+- VitePress compiles website-owned Markdown only.
+- Hub documents remain canonical inputs for human editing judgment, not build-time inputs.
+- A website page may summarize or reorganize Hub truth and should link to a canonical source
+ when that link materially helps readers or maintainers.
+- Editorial drift is accepted as a normal consequence of serving different audiences.
+- No exact source-to-route manifest, wrapper fleet, generated mirror, source hash gate, or
+ cross-surface freshness mechanism is required.
+- When drift exposes a real product or contract mismatch, update the canonical Hub owner first
+ and adjust the relevant website page in the same task when it is in scope.
diff --git a/tasks/vitepress-documentation-site/preflight.md b/tasks/vitepress-documentation-site/preflight.md
new file mode 100644
index 0000000..c346463
--- /dev/null
+++ b/tasks/vitepress-documentation-site/preflight.md
@@ -0,0 +1,166 @@
+# VitePress Documentation Site Preflight
+
+Date: 2026-07-28
+
+All experiments ran in a disposable `/tmp` fixture copied from the current Hub. No website,
+package, configuration, CI, or canonical Hub document was changed in the working repository.
+
+## Decision Outcome
+
+Directly building canonical Hub Markdown into website pages was technically feasible but was
+not selected.
+
+Sir accepted normal editorial drift between canonical Hub truth and a human-facing website.
+The selected architecture keeps all VitePress Markdown under `website/`; Hub documents inform
+website content through ordinary editing judgment, summaries, and links. There is no
+source-to-route manifest, wrapper fleet, generated mirror, source hash gate, or cross-surface
+freshness mechanism.
+
+This is the simpler and deeper boundary:
+
+```text
+Hub owns shared product and cross-unit truth.
+Website owns public presentation and reader-oriented structure.
+```
+
+When a website page depends materially on a Hub claim, a normal source link is sufficient.
+When a real mismatch is discovered, update the canonical Hub owner first and then adjust the
+website page when it is in scope.
+
+## Reusable Environment Evidence
+
+- Local runtime: Node `22.22.3`, npm `10.9.8`, pnpm `11.17.0`, macOS arm64.
+- Neighboring InKCre packages already use Node `22.22.3`, package-local pnpm declarations,
+ `devEngines.runtime`, frozen installs, and aggregate `check` commands.
+- Registry state during preflight:
+ - VitePress stable: `1.6.4`;
+ - VitePress `next`: `2.0.0-alpha.18`;
+ - Vite stable: `8.1.5`.
+- VitePress 1.6.4 built the disposable fixture, but its resolved dependency graph reported
+ three moderate and one high vulnerability.
+- VitePress 2.0.0-alpha.18 built and previewed successfully, and
+ `pnpm audit --audit-level high` reported no known vulnerabilities.
+- The prerelease must be pinned exactly and re-evaluated at execution time; implementation must
+ not float on the `next` tag.
+
+## Findings That Shaped The Plan
+
+- Root `README.md` is a repository entry and links to Hub-local task state, so it should not be
+ reused as the public index.
+- A minimal site-owned index avoids changing README or weakening dead-link checks.
+- Keeping VitePress source and dependencies inside `website/` removes the parent-source module
+ resolution seam and makes Hub-local files unreachable by construction.
+- Development-server HTTP status is not useful publication evidence because VitePress serves an
+ SPA shell for unknown paths; production build and preview remain the meaningful checks.
+- The client-web Cloudflare Pages workflow contains application-specific artifact identity,
+ SPA, preview-cleanup, and database concerns. The documentation site should reuse only the
+ Node/pnpm and pinned-action conventions, not that workflow's complexity.
+
+## Route And Locale Evolution Experiment
+
+A second disposable fixture tested the source and URL model that would otherwise be expensive
+to retrofit. It used VitePress `2.0.0-alpha.18` with:
+
+```text
+srcDir: 'content'
+base: '/'
+cleanUrls: true
+rewrites: { 'en/:rest*': ':rest*' }
+locales.root: English
+```
+
+The source tree contained:
+
+```text
+content/en/index.md
+content/en/manual/index.md
+content/en/manual/getting-started.md
+```
+
+The production build passed and emitted:
+
+```text
+.vitepress/dist/index.html
+.vitepress/dist/manual/index.html
+.vitepress/dist/manual/getting-started.html
+```
+
+It emitted no `/en/` output, used `en-US` page language, and generated clean internal links
+without `.html`. Adding a Chinese locale and `content/zh/**` generated `/zh/**` while English
+remained at root.
+
+The negative test was more important: when the English leaf page had no Chinese counterpart,
+the locale switch still linked to `/zh/manual/getting-started`, and the production build still
+passed. Therefore:
+
+- default-language source should start under `content/en/**`;
+- only the root locale should be active initially;
+- a future locale requires route parity or a fallback-capable locale switch;
+- production build remains the dead-link baseline but is not a translation-parity check.
+
+Cloudflare Pages' documented clean-path behavior supports enabling `cleanUrls` from the first
+build. Hostname-dependent sitemap, canonical, social, and robots metadata can still wait until
+the public origin is confirmed.
+
+## Selected Verification Baseline
+
+Implementation should verify:
+
+```text
+pnpm --dir website install --frozen-lockfile
+pnpm --dir website check
+svc status --json
+svc init --agent codex --json
+git diff --check
+```
+
+The deterministic website `check` command should run formatting verification followed by the
+VitePress production build and its default dead-link check. The network-dependent advisory
+audit remains an explicit dependency-selection and update check. Production-output assertions
+verify that the default language stays at root and generated links use the selected clean URL
+contract. Preview remains a manual acceptance and later deployment-smoke tool rather than a
+background process in the normal check.
+
+Canonical Hub directories remain outside VitePress's source root and therefore need no
+publication manifest or hash comparison.
+
+## Execution Result
+
+The authorized implementation completed on 2026-07-28 with these exact local package pins:
+
+```text
+Node: 22.22.3
+pnpm: 11.17.0
+VitePress: 2.0.0-alpha.18
+Oxfmt: 0.60.0
+```
+
+Oxfmt replaced the planned Prettier dependency after execution-time inspection showed that
+modern neighboring InKCre repositories already use Oxfmt and its official language support
+covers Markdown and the website's configuration formats. `0.60.0` was selected instead of the
+newly published `0.61.0`: pnpm's supply-chain policy required release-age exceptions for the
+new version and its platform bindings, while `0.60.0` is already used by neighboring
+repositories and needs no exception.
+
+Implemented surfaces:
+
+- independent package, lockfile, ignores, formatter, configuration, content, and generated-route
+ verifier under `website/`;
+- a single English index rewritten from `content/en/index.md` to `/`;
+- one always-reporting website contract workflow with pinned actions;
+- weekly Dependabot coverage for `/website` and root GitHub Actions.
+
+Verification passed:
+
+- frozen installation;
+- Oxfmt check;
+- VitePress production build and default dead-link gate;
+- generated output checks for root `en-US`, no `/en/`, and no internal `.md` or `.html` links;
+- deliberate negative probes for `/en?probe=1` and `guide.html?probe=1`, both correctly rejected;
+- high-severity dependency audit with no known vulnerabilities;
+- desktop `1280x720` and mobile `390x844` browser acceptance;
+- root `200`, missing-route `404`, responsive layout, accessible landmarks and controls, and no
+ browser console warnings or errors.
+
+The independent final review accepted the implementation. Its two URL-assertion edge cases were
+resolved by parsing and normalizing generated local URLs before validation.
diff --git a/website/.editorconfig b/website/.editorconfig
new file mode 100644
index 0000000..8b857ca
--- /dev/null
+++ b/website/.editorconfig
@@ -0,0 +1,12 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+max_line_length = 100
diff --git a/website/.gitignore b/website/.gitignore
new file mode 100644
index 0000000..c76bc00
--- /dev/null
+++ b/website/.gitignore
@@ -0,0 +1,3 @@
+node_modules/
+.vitepress/cache/
+.vitepress/dist/
diff --git a/website/.oxfmtrc.json b/website/.oxfmtrc.json
new file mode 100644
index 0000000..81354bd
--- /dev/null
+++ b/website/.oxfmtrc.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "./node_modules/oxfmt/configuration_schema.json",
+ "arrowParens": "always",
+ "ignorePatterns": [
+ "node_modules/**",
+ ".vitepress/cache/**",
+ ".vitepress/dist/**",
+ "pnpm-lock.yaml"
+ ],
+ "printWidth": 100,
+ "proseWrap": "always",
+ "semi": false,
+ "singleQuote": true,
+ "sortPackageJson": true,
+ "tabWidth": 2,
+ "trailingComma": "es5",
+ "useTabs": false
+}
diff --git a/website/.vitepress/config.mts b/website/.vitepress/config.mts
new file mode 100644
index 0000000..3af1a52
--- /dev/null
+++ b/website/.vitepress/config.mts
@@ -0,0 +1,50 @@
+import { defineConfig, type HeadConfig } from 'vitepress'
+
+const description =
+ 'Public documentation for InKCre, an actively developed system for reusable information.'
+const siteOrigin = 'https://inkcre.dev'
+
+export default defineConfig({
+ srcDir: 'content',
+ base: '/',
+ cleanUrls: true,
+ title: 'InKCre',
+ description,
+ rewrites: {
+ 'en/:rest*': ':rest*',
+ },
+ locales: {
+ root: {
+ label: 'English',
+ lang: 'en-US',
+ title: 'InKCre',
+ description,
+ },
+ },
+ sitemap: {
+ hostname: siteOrigin,
+ },
+ transformPageData(pageData) {
+ const url = new URL(pageData.relativePath.replace(/(?:(^|\/)index)?\.md$/, '$1'), siteOrigin)
+ .href
+ const title =
+ pageData.title && pageData.title !== 'InKCre' ? `${pageData.title} | InKCre` : 'InKCre'
+ const pageDescription = pageData.description || description
+
+ ;((pageData.frontmatter.head ??= []) as HeadConfig[]).push(
+ ['link', { rel: 'canonical', href: url }],
+ ['meta', { property: 'og:type', content: 'website' }],
+ ['meta', { property: 'og:site_name', content: 'InKCre' }],
+ ['meta', { property: 'og:locale', content: 'en_US' }],
+ ['meta', { property: 'og:url', content: url }],
+ ['meta', { property: 'og:title', content: title }],
+ ['meta', { property: 'og:description', content: pageDescription }],
+ ['meta', { name: 'twitter:card', content: 'summary' }],
+ ['meta', { name: 'twitter:title', content: title }],
+ ['meta', { name: 'twitter:description', content: pageDescription }]
+ )
+ },
+ themeConfig: {
+ socialLinks: [{ icon: 'github', link: 'https://github.com/InKCre/docs' }],
+ },
+})
diff --git a/website/README.md b/website/README.md
new file mode 100644
index 0000000..563fa0c
--- /dev/null
+++ b/website/README.md
@@ -0,0 +1,82 @@
+# InKCre Website
+
+This package builds the public InKCre documentation site. Its Markdown is a reader-oriented
+projection of the canonical shared product truth in the repository root; it does not replace that
+truth or make Hub-local collaboration files public.
+
+## Commands
+
+Run commands from the repository root:
+
+```sh
+pnpm --dir website dev
+pnpm --dir website check
+pnpm --dir website preview
+```
+
+The deterministic `check` command verifies formatting, builds the production site with VitePress's
+dead-link checks enabled, and checks the generated route contract. Dependency advisories remain a
+separate, network-dependent check:
+
+```sh
+pnpm --dir website audit --audit-level high
+```
+
+## Content And Route Contract
+
+- VitePress reads only `content/`.
+- English source lives under `content/en/` and is published at the public root.
+- Future Chinese source will live under `content/zh/` and be published under `/zh/`.
+- Only English is active until the Chinese route set is complete or the locale switch has a
+ deliberate fallback.
+- Section indexes use trailing-slash routes, such as `/manual/`.
+- Leaf pages use lowercase ASCII kebab-case routes without an extension, such as
+ `/manual/getting-started`.
+- Source ordering belongs in navigation configuration, not numeric filename prefixes.
+- Published routes are compatibility contracts. Move one only with a direct permanent redirect.
+
+Internal Markdown links target rewritten public routes and omit `.md` and `.html`. Relative links
+are resolved from the rewritten route, not the source file location.
+
+## Page Authoring
+
+- Keep exactly one H1 per page.
+- Add a concise page `description` in frontmatter.
+- Give headings explicit custom anchors only when another page or external consumer needs a durable
+ deep link.
+- Keep current product behavior tentative where the canonical Hub does not claim stability.
+- Link to a canonical Hub source when it materially helps readers or maintainers.
+- Do not create empty pages or navigation for future User Manual, Developer Guide, or About
+ sections.
+
+Update canonical Hub truth first when a public page reveals a real product or cross-unit contract
+mismatch.
+
+## Publication
+
+`Website checks` builds and uploads `inkcre-website-dist`. The separate `Pages deployment` workflow
+accepts only a successful artifact for the exact current `main` commit, downloads that artifact
+without rebuilding it, and deploys it to the `inkcre-website` Cloudflare Pages Direct Upload
+project.
+
+The deployment controller idempotently owns:
+
+- production branch `main`;
+- custom domain `inkcre.dev`;
+- canonical, sitemap, robots, and Open Graph metadata;
+- `noindex` headers on production and immutable `pages.dev` origins;
+- smoke checks for HTTPS, root HTML, real `404`, sitemap, robots, and canonical behavior.
+
+GitHub provides the deployment inputs without copying credentials into this package:
+
+```text
+organization secrets:
+ CLOUDFLARE_ACCOUNT_ID
+ CLOUDFLARE_API_TOKEN
+
+repository variable:
+ CLOUDFLARE_PAGES_PROJECT=inkcre-website
+```
+
+The Cloudflare token requires Pages Write access. The application at `app.inkcre.dev` remains an
+independent deployment.
diff --git a/website/content/en/index.md b/website/content/en/index.md
new file mode 100644
index 0000000..b0e17e6
--- /dev/null
+++ b/website/content/en/index.md
@@ -0,0 +1,19 @@
+---
+title: InKCre
+description: Public documentation index for the actively developed InKCre project.
+---
+
+# InKCre
+
+InKCre is under active development. The project is being built to collect information, organize it
+into a reusable base, and make that information available to later retrieval, indexing, and
+downstream workflows.
+
+This site is currently a compact entry point to the project's shared product and technical
+documentation.
+
+## Project documentation
+
+- [Product requirements](https://github.com/InKCre/docs/blob/main/10-prd/index.md)
+- [Cross-unit technical design](https://github.com/InKCre/docs/tree/main/20-product-tdd)
+- [Documentation source](https://github.com/InKCre/docs)
diff --git a/website/content/public/_headers b/website/content/public/_headers
new file mode 100644
index 0000000..e8e8936
--- /dev/null
+++ b/website/content/public/_headers
@@ -0,0 +1,5 @@
+https://inkcre-website.pages.dev/*
+ X-Robots-Tag: noindex
+
+https://:version.inkcre-website.pages.dev/*
+ X-Robots-Tag: noindex
diff --git a/website/content/public/robots.txt b/website/content/public/robots.txt
new file mode 100644
index 0000000..1cb7083
--- /dev/null
+++ b/website/content/public/robots.txt
@@ -0,0 +1,4 @@
+User-agent: *
+Allow: /
+
+Sitemap: https://inkcre.dev/sitemap.xml
diff --git a/website/package.json b/website/package.json
new file mode 100644
index 0000000..574de7a
--- /dev/null
+++ b/website/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "@inkcre/docs-website",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "build": "vitepress build",
+ "check": "pnpm format:check && pnpm build && pnpm verify:build",
+ "dev": "vitepress dev",
+ "format": "oxfmt .",
+ "format:check": "oxfmt --check .",
+ "preview": "vitepress preview",
+ "verify:build": "node scripts/verify-build.mjs"
+ },
+ "devDependencies": {
+ "oxfmt": "0.60.0",
+ "vitepress": "2.0.0-alpha.18"
+ },
+ "devEngines": {
+ "runtime": {
+ "name": "node",
+ "version": "22.22.3",
+ "onFail": "download"
+ }
+ },
+ "packageManager": "pnpm@11.17.0"
+}
diff --git a/website/pnpm-lock.yaml b/website/pnpm-lock.yaml
new file mode 100644
index 0000000..f4b44bf
--- /dev/null
+++ b/website/pnpm-lock.yaml
@@ -0,0 +1,1624 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ devDependencies:
+ node:
+ specifier: runtime:22.22.3
+ version: runtime:22.22.3
+ oxfmt:
+ specifier: 0.60.0
+ version: 0.60.0
+ vitepress:
+ specifier: 2.0.0-alpha.18
+ version: 2.0.0-alpha.18(postcss@8.5.23)
+
+packages:
+
+ '@babel/helper-string-parser@7.29.7':
+ resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.29.7':
+ resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.29.7':
+ resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/types@7.29.7':
+ resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==}
+ engines: {node: '>=6.9.0'}
+
+ '@docsearch/css@4.6.3':
+ resolution: {integrity: sha512-nlOwcXcsNAptQl4vlL4MA78qNJKO0Qlds5GuBjCoePgkebTXLSf8Qt1oyZ3YBshYupKXG9VRGEsk1zr23d+bzQ==}
+
+ '@docsearch/js@4.6.3':
+ resolution: {integrity: sha512-qUIX2b4Apew3tv4F0qhmgShsl/Lfw4m6mqv/5/5dWNxwTcDdLMp2s3YwZ+NMGh3IKCg0pBaXm7Q5VdyU5Rj+cQ==}
+
+ '@docsearch/sidepanel-js@4.6.3':
+ resolution: {integrity: sha512-grGSmvXzG0if+mrzdIKykvpIAuEQ9u0sEJ2eLRRCaQfJvsWqh2C2/aY04bIzWvDh7myi5rvl8D+tUNsVrjYQ3A==}
+
+ '@emnapi/core@1.11.1':
+ resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==}
+
+ '@emnapi/runtime@1.11.1':
+ resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==}
+
+ '@emnapi/wasi-threads@1.2.2':
+ resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==}
+
+ '@iconify-json/simple-icons@1.2.92':
+ resolution: {integrity: sha512-hR0ozxR97t1dzWw+esoxFijZ15gagt7EIgF3CNifu2yICXhS7gnun4Y+j+odJQtNSl7wvqMdoLbViIShwe/fdw==}
+
+ '@iconify/types@2.0.0':
+ resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@napi-rs/wasm-runtime@1.1.6':
+ resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==}
+ peerDependencies:
+ '@emnapi/core': ^1.7.1
+ '@emnapi/runtime': ^1.7.1
+
+ '@oxc-project/types@0.139.0':
+ resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==}
+
+ '@oxfmt/binding-android-arm-eabi@0.60.0':
+ resolution: {integrity: sha512-1q4q4Jc8FlOMVojEisyFAVyl8h1yawNv6phjgmhGVEDeyeOdsSnSr9x0+D4mOnEKvpO5L4mxKZ/DP9X6U3A/Mw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [android]
+
+ '@oxfmt/binding-android-arm64@0.60.0':
+ resolution: {integrity: sha512-tD41I6nCt9k8SQXft0CSjjU9jg6SwG7uMu7PxodSEHXl+GDW0868oy6tTtoJkyUze8YKFgTpz/k5LuPUnFiGLw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [android]
+
+ '@oxfmt/binding-darwin-arm64@0.60.0':
+ resolution: {integrity: sha512-TTpzPug96Zxdyb46KvTyIUQDdsqbumXh2TKG9C23PCT0kF7JkW56Z/quPuG9rqOFKQIi1gpRNZ7DX18LwxXPnw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@oxfmt/binding-darwin-x64@0.60.0':
+ resolution: {integrity: sha512-CnOoWgQ7L+JL/YQaRJ+NyATciSfcftncm7y3kqyte1cGtFEGnStaCd1TAyrinkfQ7nRBfHrTs1/vTwUJr3WF2Q==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@oxfmt/binding-freebsd-x64@0.60.0':
+ resolution: {integrity: sha512-ychJo7S3hZxdO6eDZ9zM6F2lM9fpJS3EKS5CAUSWyprdLYxTu4gbaUKV/VBPTcMJwQa2Bpo+643y3OJ537pihA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@oxfmt/binding-linux-arm-gnueabihf@0.60.0':
+ resolution: {integrity: sha512-36IH5o55T2Fx7E0feDttt+mifxN6yk9pWv4KfhAIsP0dFnUq27331OwbpOsZdoXF9soOLWm7mQUz5+UUmyec4g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@oxfmt/binding-linux-arm-musleabihf@0.60.0':
+ resolution: {integrity: sha512-G1Ve7lAa6sFBolVI2LWHfEAqy0YKh4vnioH8uYO9kAEdgM7mR40IksIx9/Zk4+vbYew/sGa4J9Q4tZ3n9gXDHA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@oxfmt/binding-linux-arm64-gnu@0.60.0':
+ resolution: {integrity: sha512-LTQdRBf6uzj/h7Xk6lKzbGD2hrF/fK4YI9LIN1c0509tPUn8wRa3mCmrFQpEWJPLYGFrLFFMTYW1Ljj6VqW2Hw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxfmt/binding-linux-arm64-musl@0.60.0':
+ resolution: {integrity: sha512-2JMo3XPxMPx3hiqddSZYyaH+fKJm6cz0u8n1naYjP/CdOQOZW34i8lKBUfmbWiuFvd6KoYXLmhAyBuvojsYS7Q==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@oxfmt/binding-linux-ppc64-gnu@0.60.0':
+ resolution: {integrity: sha512-L3C+nBD13lr306tr/PjM3RMll+BVqgFrIgUyoeHuai5oueJrRLgO3j+GO5/Cbhtkf5PSlHYTI1JY7iqBd1qa6A==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxfmt/binding-linux-riscv64-gnu@0.60.0':
+ resolution: {integrity: sha512-M4MsmvqlxFiPtSRGyBYQSZxchEf463AOyd+Dh4/9xDpjWBsRtDUTDMFN5EdHinjVK1/eDJQ8MLpcYjpYayaCnA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxfmt/binding-linux-riscv64-musl@0.60.0':
+ resolution: {integrity: sha512-OH+9UskYuxRB+GxqdGkVN8f5UpwhqG8YscNo1wl8+KJ62cd7wZdGga6iGLJIf8kibF1WBwvlfDUx3cez/VXwFg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [musl]
+
+ '@oxfmt/binding-linux-s390x-gnu@0.60.0':
+ resolution: {integrity: sha512-y7AAFutt9wFWBFOAn6+BHaV39usZmcr3YYH2385f+NHgPNpIF9HpqKp0jgUxPaUOCyG3oaX5VhJduL1Nw164rw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxfmt/binding-linux-x64-gnu@0.60.0':
+ resolution: {integrity: sha512-yKZ9+CXAI+1RO5nH/4Z/9M6DAsfOzd5bw/gtWk81KB4mpalMaRRSXfouc5/tHxazDmBek55HNPepNYBgaCew0Q==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxfmt/binding-linux-x64-musl@0.60.0':
+ resolution: {integrity: sha512-bCUGaF6hJOYnQzLJdHLZbvGsOd5oSvGAyJhPAKum2uyLYUuXmP8vqg690DWi2hqcnIoYpqSqCrjzE5aiUAgwQg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@oxfmt/binding-openharmony-arm64@0.60.0':
+ resolution: {integrity: sha512-GrUeZOvzP30ExxfCuQiyofuUGI+OmvAgFwOO5w5p9mGPlxcyuqI+6Sy9fAKFFfLQrqKYWFgc5sYA2Unj/29nPg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@oxfmt/binding-win32-arm64-msvc@0.60.0':
+ resolution: {integrity: sha512-WD4Q954kUl2TDJV/6q7UnE2rlKk047kXLJsr4bJ2mXRaAqNXcmV3nwKUsGCc3mz/jYDBnXtJEaBErJEybK8iQQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@oxfmt/binding-win32-ia32-msvc@0.60.0':
+ resolution: {integrity: sha512-HqDekjr8JXzVDUP1YthDZ1Y3CBEcuZT4WX3B+1kaxj8CvZA8Y2YhcEsXqoSop3tVsgjACxjnFQFDkBo0r/jq1Q==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@oxfmt/binding-win32-x64-msvc@0.60.0':
+ resolution: {integrity: sha512-tz78yhmGPKboTMHCHSaUqXK8JrmoSejgDcWeqAtg2s07ZGKQ3rH5Jn8NuXPGNG33CDbY2e9NoQWXIVEmKO21Rw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@rolldown/binding-android-arm64@1.1.5':
+ resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [android]
+
+ '@rolldown/binding-darwin-arm64@1.1.5':
+ resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rolldown/binding-darwin-x64@1.1.5':
+ resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rolldown/binding-freebsd-x64@1.1.5':
+ resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rolldown/binding-linux-arm-gnueabihf@1.1.5':
+ resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@rolldown/binding-linux-arm64-gnu@1.1.5':
+ resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rolldown/binding-linux-arm64-musl@1.1.5':
+ resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@rolldown/binding-linux-ppc64-gnu@1.1.5':
+ resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rolldown/binding-linux-s390x-gnu@1.1.5':
+ resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@rolldown/binding-linux-x64-gnu@1.1.5':
+ resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rolldown/binding-linux-x64-musl@1.1.5':
+ resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@rolldown/binding-openharmony-arm64@1.1.5':
+ resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rolldown/binding-wasm32-wasi@1.1.5':
+ resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [wasm32]
+
+ '@rolldown/binding-win32-arm64-msvc@1.1.5':
+ resolution: {integrity: sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rolldown/binding-win32-x64-msvc@1.1.5':
+ resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@rolldown/pluginutils@1.0.1':
+ resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
+
+ '@shikijs/core@4.3.1':
+ resolution: {integrity: sha512-ANMDxuaPsNMdDC1m4vfvhlDmJweMwkE5XitTwrq2rWHx5jM+dlm4MmHt2PP6t0uejfR77SuhrhJ0zEijIF/uhA==}
+ engines: {node: '>=20'}
+
+ '@shikijs/engine-javascript@4.3.1':
+ resolution: {integrity: sha512-JBItcnPuYq7jVJdZo/vMj94r+szT7XEjHFX+mvFDGSEIbVAXAGyHAHzhbWzpGOwYidCZrErJLLgn2PVeiokHnQ==}
+ engines: {node: '>=20'}
+
+ '@shikijs/engine-oniguruma@4.3.1':
+ resolution: {integrity: sha512-OXyNMzg0pews+msMj4cHeqT4xiYKKvbnn6VbdAXxfoFl3SSx4fJTc8FadECuc5/H9p3BzhNAoAUXKwAu9rWYhg==}
+ engines: {node: '>=20'}
+
+ '@shikijs/langs@4.3.1':
+ resolution: {integrity: sha512-m0l9nsDqgBHvbZbk7A0/kXz/impK3uB/c6rAn6Gpg/uPtdZRQ+alsN/17MU5thb68XTj/4DxkZAotrM0GGSpDQ==}
+ engines: {node: '>=20'}
+
+ '@shikijs/primitive@4.3.1':
+ resolution: {integrity: sha512-CXQRQOYy1leqQ8ceTeJdmXv/bsUY++6QyLpXJ94LZAAYj5X2SKRdc5ipguv4NPyGVKItB2PPwUpRNe0Sjh5S1A==}
+ engines: {node: '>=20'}
+
+ '@shikijs/themes@4.3.1':
+ resolution: {integrity: sha512-dgpoJ4WqNi2yTmizQHBJ5zcX6j2lE6icN/0yt4l1kkf16jrY/pwPLoTb1ETsWMz0OBLf9ZNvwmxft+cH+N9qSA==}
+ engines: {node: '>=20'}
+
+ '@shikijs/transformers@4.3.1':
+ resolution: {integrity: sha512-z6ir0bGDgWcF2FduktEfPgIsdOtIlDiLAjFBgBzE42Q9xHbkkIXZtORHzlLVB71iZP9elEcqKg6keajvOUwE2A==}
+ engines: {node: '>=20'}
+
+ '@shikijs/types@4.3.1':
+ resolution: {integrity: sha512-CHFxE0jztBIZRHH6gxXE7DXUCFXjReEGxZ/j0rfSLGKZuwp2xBYycEP14875DSa9KLL/6700oxIq6oO6ef9K2g==}
+ engines: {node: '>=20'}
+
+ '@shikijs/vscode-textmate@10.0.2':
+ resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
+
+ '@tybys/wasm-util@0.10.3':
+ resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==}
+
+ '@types/hast@3.0.5':
+ resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==}
+
+ '@types/linkify-it@5.0.0':
+ resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
+
+ '@types/markdown-it@14.1.2':
+ resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
+
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/mdurl@2.0.0':
+ resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@types/web-bluetooth@0.0.21':
+ resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
+
+ '@ungap/structured-clone@1.3.3':
+ resolution: {integrity: sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==}
+
+ '@vitejs/plugin-vue@6.0.8':
+ resolution: {integrity: sha512-0ZjgOg7oO6farnNGup7yvoM/YXZV84OZxHAwtflItNa/6zzQyVb5LNxyea3FEKEX2XlagIKzrlH7wwxkKgtiew==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ peerDependencies:
+ vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
+ vue: ^3.2.25
+
+ '@vue/compiler-core@3.5.40':
+ resolution: {integrity: sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==}
+
+ '@vue/compiler-dom@3.5.40':
+ resolution: {integrity: sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==}
+
+ '@vue/compiler-sfc@3.5.40':
+ resolution: {integrity: sha512-gIf497P4kpuALcvs5n3AEg1Vdn0pSY4XbjASIfHNYF1/MP3T2Mf2STERTubysBxCRxzJGJYtF/O7vwJrxFB3Vw==}
+
+ '@vue/compiler-ssr@3.5.40':
+ resolution: {integrity: sha512-rrE5xiXG663+vHCHa3J9p2z5OcBRjXmoqenprJxAFQxg5pSshzeBiCE6pu46axapRJ2Adk0YDA2BRZVjiHXnhg==}
+
+ '@vue/devtools-api@8.2.1':
+ resolution: {integrity: sha512-6u4vXBlIBAC1wMplIZgpyPn7uh/s4Bf6F5bMzvLv+EdJ0aHs/+4B7Ygv864EStQSjRbsRzTko/kUG1A1IejQ3A==}
+
+ '@vue/devtools-kit@8.2.1':
+ resolution: {integrity: sha512-FIGIuq3AWReEpbAHY/cRGeHDfI0qOb8OCQ3YjbEAX04uaxIDbGc9rhkbVcG7rnfHPXE3RsU5KrWOu9V/okd8AQ==}
+
+ '@vue/devtools-shared@8.2.1':
+ resolution: {integrity: sha512-Fkac7lUdGReh6pVOi3AYPRGe82LQqRmAfThW7RRligOAP0ZA/Z1z9XLHDM9dv34pV2HRc79DK8uKPeG2fLnA/g==}
+
+ '@vue/reactivity@3.5.40':
+ resolution: {integrity: sha512-B7ot9UlUZOi1zbq61/LvE88ZLTV8IlajTdiZTAEiDQgrnIMIZoPr9kGw0Zw46ObW62O9+H/Be3kMbfb7kYPQZA==}
+
+ '@vue/runtime-core@3.5.40':
+ resolution: {integrity: sha512-KAZLweuZ6uUJPK1PMSQPgBU5gCjgrrfjUhSglmU9NhH+Zjepa8cnwSydPWDWHDwOgY4g3VcZ+PljbiHlURNCbw==}
+
+ '@vue/runtime-dom@3.5.40':
+ resolution: {integrity: sha512-ZfrX8ssZQds900L9pr8AuK05ddnMsR4MPMZr8cPN9GoqoPWcXLhjvvbIA2SMv+7a97sJ1vv9pj/zxK0Cq/eEFQ==}
+
+ '@vue/server-renderer@3.5.40':
+ resolution: {integrity: sha512-XNJym9WpevhTVt1HuwOrCRJ5Q+9z4BjTMrDtjTrvx74SmUll8spNTw6whWJa9mEkO4PKn5TihI/bm/8ds2QVJw==}
+
+ '@vue/shared@3.5.40':
+ resolution: {integrity: sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==}
+
+ '@vueuse/core@14.3.0':
+ resolution: {integrity: sha512-aHfz47g0ZhMtTVHmIzMVpJy8ePhhOy68GY5bv110+5DVtZ+W7BsOx+m61UNQqfrWyPztIHIanWa3E2tib3NFIw==}
+ peerDependencies:
+ vue: ^3.5.0
+
+ '@vueuse/integrations@14.3.0':
+ resolution: {integrity: sha512-76I5FT2ESvCmCaSwapI+a/u/CFtNXmzl9f9lNp1hRtx8vKB8hfiokJr8IvQqcQG5ckGXElyXK516b54ozV3MvA==}
+ peerDependencies:
+ async-validator: ^4
+ axios: ^1
+ change-case: ^5
+ drauu: ^0.4
+ focus-trap: ^7 || ^8
+ fuse.js: ^7
+ idb-keyval: ^6
+ jwt-decode: ^4
+ nprogress: ^0.2
+ qrcode: ^1.5
+ sortablejs: ^1
+ universal-cookie: ^7 || ^8
+ vue: ^3.5.0
+ peerDependenciesMeta:
+ async-validator:
+ optional: true
+ axios:
+ optional: true
+ change-case:
+ optional: true
+ drauu:
+ optional: true
+ focus-trap:
+ optional: true
+ fuse.js:
+ optional: true
+ idb-keyval:
+ optional: true
+ jwt-decode:
+ optional: true
+ nprogress:
+ optional: true
+ qrcode:
+ optional: true
+ sortablejs:
+ optional: true
+ universal-cookie:
+ optional: true
+
+ '@vueuse/metadata@14.3.0':
+ resolution: {integrity: sha512-BwxmbAzwAVF50+MW57GXOUEV61nFBGnlBvrTqj49PqWJu3uw7hdu72ztXeZ33RdZtDY6kO+bfCAE1PCn88Tktw==}
+
+ '@vueuse/shared@14.3.0':
+ resolution: {integrity: sha512-bZpge9eSXwa4ToSiqJ7j6KRwhAsneMFoSz3LMWKQDkqimm3D/tbFlrklrs/IOqC8tEcYmXQZJ6N0UrjhBirVCg==}
+ peerDependencies:
+ vue: ^3.5.0
+
+ birpc@2.9.0:
+ resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==}
+
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+
+ character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+
+ character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
+ entities@7.0.1:
+ resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
+ engines: {node: '>=0.12'}
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ focus-trap@8.2.2:
+ resolution: {integrity: sha512-qV0g8hRYBqgACcFOH3f9wXc4zPKhr/0z9RI2a6ZijZ72EeBi4g8oBy8zAWuUR1TsMpOzwpUMFvjdasrC41Joug==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ hast-util-to-html@9.0.5:
+ resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
+ hookable@5.5.3:
+ resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
+
+ html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+
+ lightningcss-android-arm64@1.33.0:
+ resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [android]
+
+ lightningcss-darwin-arm64@1.33.0:
+ resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ lightningcss-darwin-x64@1.33.0:
+ resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ lightningcss-freebsd-x64@1.33.0:
+ resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ lightningcss-linux-arm-gnueabihf@1.33.0:
+ resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ lightningcss-linux-arm64-gnu@1.33.0:
+ resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ lightningcss-linux-arm64-musl@1.33.0:
+ resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ lightningcss-linux-x64-gnu@1.33.0:
+ resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ lightningcss-linux-x64-musl@1.33.0:
+ resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ lightningcss-win32-arm64-msvc@1.33.0:
+ resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ lightningcss-win32-x64-msvc@1.33.0:
+ resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ lightningcss@1.33.0:
+ resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==}
+ engines: {node: '>= 12.0.0'}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ mark.js@8.11.1:
+ resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==}
+
+ mdast-util-to-hast@13.2.1:
+ resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
+
+ micromark-util-character@2.1.1:
+ resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
+
+ micromark-util-encode@2.0.1:
+ resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
+
+ micromark-util-sanitize-uri@2.0.1:
+ resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
+
+ micromark-util-symbol@2.0.1:
+ resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
+
+ micromark-util-types@2.0.2:
+ resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
+
+ minisearch@7.2.0:
+ resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==}
+
+ nanoid@3.3.16:
+ resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ node@runtime:22.22.3:
+ resolution:
+ type: variations
+ variants:
+ - resolution:
+ archive: tarball
+ bin:
+ node: bin/node
+ integrity: sha256-QAJqz3ioCOQ9IioLDg5xG5X/J5NGlreSW1Mpi8fIxgo=
+ type: binary
+ url: https://nodejs.org/download/release/v22.22.3/node-v22.22.3-aix-ppc64.tar.gz
+ targets:
+ - cpu: ppc64
+ os: aix
+ - resolution:
+ archive: tarball
+ bin:
+ node: bin/node
+ integrity: sha256-Daf/dO+GETKMghLxeUM2hxOirZU/t9iajIoOrofCMgc=
+ type: binary
+ url: https://nodejs.org/download/release/v22.22.3/node-v22.22.3-darwin-arm64.tar.gz
+ targets:
+ - cpu: arm64
+ os: darwin
+ - resolution:
+ archive: tarball
+ bin:
+ node: bin/node
+ integrity: sha256-RYMLp1L6DYksbc1kCUZmmAEpPKyCCjNZHe1ArAdRmOw=
+ type: binary
+ url: https://nodejs.org/download/release/v22.22.3/node-v22.22.3-darwin-x64.tar.gz
+ targets:
+ - cpu: x64
+ os: darwin
+ - resolution:
+ archive: tarball
+ bin:
+ node: bin/node
+ integrity: sha256-zIvIKy3QtZXDuVpMPJyMNQkHz/ARr73uPRN56BLh4+M=
+ type: binary
+ url: https://nodejs.org/download/release/v22.22.3/node-v22.22.3-linux-arm64.tar.gz
+ targets:
+ - cpu: arm64
+ os: linux
+ - resolution:
+ archive: tarball
+ bin:
+ node: bin/node
+ integrity: sha256-GPvhv91CBFrxXwIlauPllJDRuf+T38J6IjrMLJJ0AlA=
+ type: binary
+ url: https://nodejs.org/download/release/v22.22.3/node-v22.22.3-linux-armv7l.tar.gz
+ targets:
+ - cpu: armv7l
+ os: linux
+ - resolution:
+ archive: tarball
+ bin:
+ node: bin/node
+ integrity: sha256-qQ9SPPFk4cdhv0xZtcaqDZ1VKJJwGraUmeaD7h/Aa7w=
+ type: binary
+ url: https://nodejs.org/download/release/v22.22.3/node-v22.22.3-linux-ppc64le.tar.gz
+ targets:
+ - cpu: ppc64le
+ os: linux
+ - resolution:
+ archive: tarball
+ bin:
+ node: bin/node
+ integrity: sha256-S4TkPCnZDk+QGBXDmRBqSa9O5zDRKTOvgsgtTcRQMIw=
+ type: binary
+ url: https://nodejs.org/download/release/v22.22.3/node-v22.22.3-linux-s390x.tar.gz
+ targets:
+ - cpu: s390x
+ os: linux
+ - resolution:
+ archive: tarball
+ bin:
+ node: bin/node
+ integrity: sha256-x6ENaBbajqqnU03XPHHG4rLDkdu/hF42SQLRVmFd0bg=
+ type: binary
+ url: https://nodejs.org/download/release/v22.22.3/node-v22.22.3-linux-x64.tar.gz
+ targets:
+ - cpu: x64
+ os: linux
+ - resolution:
+ archive: zip
+ bin:
+ node: node.exe
+ integrity: sha256-AL4SmgnohyzVLTu4u6EkEsVzPSIkEjpIKi3KSm+/JYY=
+ prefix: node-v22.22.3-win-arm64
+ type: binary
+ url: https://nodejs.org/download/release/v22.22.3/node-v22.22.3-win-arm64.zip
+ targets:
+ - cpu: arm64
+ os: win32
+ - resolution:
+ archive: zip
+ bin:
+ node: node.exe
+ integrity: sha256-bI1U9jX+/033bCyoD0UzLrL/V9JSJu3ONlkuUaF37jM=
+ prefix: node-v22.22.3-win-x64
+ type: binary
+ url: https://nodejs.org/download/release/v22.22.3/node-v22.22.3-win-x64.zip
+ targets:
+ - cpu: x64
+ os: win32
+ - resolution:
+ archive: zip
+ bin:
+ node: node.exe
+ integrity: sha256-e6QmD2nha6libQd8sRJPP7AfYEIa8qbHOWrrTi0Nja4=
+ prefix: node-v22.22.3-win-x86
+ type: binary
+ url: https://nodejs.org/download/release/v22.22.3/node-v22.22.3-win-x86.zip
+ targets:
+ - cpu: x86
+ os: win32
+ - resolution:
+ archive: tarball
+ bin:
+ node: bin/node
+ integrity: sha256-Cch6y6+uZeGPzA6xiDdsElTKt03HaRGPS2BHnF+jJs8=
+ type: binary
+ url: https://unofficial-builds.nodejs.org/download/release/v22.22.3/node-v22.22.3-linux-arm64-musl.tar.gz
+ targets:
+ - cpu: arm64
+ os: linux
+ libc: musl
+ - resolution:
+ archive: tarball
+ bin:
+ node: bin/node
+ integrity: sha256-0idpJYPWrhfEQCj9jxfLGzZyFnprqgNYGCQMu5226ko=
+ type: binary
+ url: https://unofficial-builds.nodejs.org/download/release/v22.22.3/node-v22.22.3-linux-x64-musl.tar.gz
+ targets:
+ - cpu: x64
+ os: linux
+ libc: musl
+ version: 22.22.3
+ hasBin: true
+
+ oniguruma-parser@0.12.2:
+ resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==}
+
+ oniguruma-to-es@4.3.6:
+ resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==}
+
+ oxfmt@0.60.0:
+ resolution: {integrity: sha512-fViX6i+gJuZWY+jI/fnR6WRbRj70GZ9RlCd30MygJrHTUNc4DxvKHWw8vBjMjffv3PgU5qWDR0AzmojQByqaZA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ svelte: ^5.0.0
+ vite-plus: '*'
+ peerDependenciesMeta:
+ svelte:
+ optional: true
+ vite-plus:
+ optional: true
+
+ perfect-debounce@2.1.0:
+ resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@4.0.5:
+ resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==}
+ engines: {node: '>=12'}
+
+ postcss@8.5.23:
+ resolution: {integrity: sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ property-information@7.2.0:
+ resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==}
+
+ regex-recursion@6.0.2:
+ resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
+
+ regex-utilities@2.3.0:
+ resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
+
+ regex@6.1.0:
+ resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==}
+
+ rolldown@1.1.5:
+ resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+
+ shiki@4.3.1:
+ resolution: {integrity: sha512-oR+qDVi2OjX1tmDpyv+3KviX01KzO6Af+0NNnKnsp9491UEGz2YpxTuJboS/6VhYpTdqzmuJBuiTlrAWWJAssw==}
+ engines: {node: '>=20'}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+
+ stringify-entities@4.0.4:
+ resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
+
+ tabbable@6.5.0:
+ resolution: {integrity: sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA==}
+
+ tinyglobby@0.2.17:
+ resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
+ engines: {node: '>=12.0.0'}
+
+ tinypool@2.1.0:
+ resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==}
+ engines: {node: ^20.0.0 || >=22.0.0}
+
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ unist-util-is@6.0.1:
+ resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-parents@6.0.2:
+ resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==}
+
+ unist-util-visit@5.1.0:
+ resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==}
+
+ vfile-message@4.0.3:
+ resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
+ vite@8.1.5:
+ resolution: {integrity: sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ '@vitejs/devtools': ^0.3.0
+ esbuild: ^0.27.0 || ^0.28.0
+ jiti: '>=1.21.0'
+ less: ^4.0.0
+ sass: ^1.70.0
+ sass-embedded: ^1.70.0
+ stylus: '>=0.54.8'
+ sugarss: ^5.0.0
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ '@vitejs/devtools':
+ optional: true
+ esbuild:
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vitepress@2.0.0-alpha.18:
+ resolution: {integrity: sha512-Lk1G2/QqSf+MwNLICl9fmzWOtoCEwjZoWgaQy41QvWTfcGpLE9XwJDbcCyES/9rj6R2g1zFqFvLVkYKLLDALFw==}
+ hasBin: true
+ peerDependencies:
+ markdown-it-mathjax3: ^4
+ postcss: ^8
+ peerDependenciesMeta:
+ markdown-it-mathjax3:
+ optional: true
+ postcss:
+ optional: true
+
+ vue@3.5.40:
+ resolution: {integrity: sha512-+8PJ4SJXdn/cHGImF4CKdxlWHIN5Dkt7DoufRREM6h6uVCx2m7QxgcEQmmzyOK8A9mcafg7sFbJFYsdFVubTig==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
+snapshots:
+
+ '@babel/helper-string-parser@7.29.7': {}
+
+ '@babel/helper-validator-identifier@7.29.7': {}
+
+ '@babel/parser@7.29.7':
+ dependencies:
+ '@babel/types': 7.29.7
+
+ '@babel/types@7.29.7':
+ dependencies:
+ '@babel/helper-string-parser': 7.29.7
+ '@babel/helper-validator-identifier': 7.29.7
+
+ '@docsearch/css@4.6.3': {}
+
+ '@docsearch/js@4.6.3': {}
+
+ '@docsearch/sidepanel-js@4.6.3': {}
+
+ '@emnapi/core@1.11.1':
+ dependencies:
+ '@emnapi/wasi-threads': 1.2.2
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/runtime@1.11.1':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/wasi-threads@1.2.2':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@iconify-json/simple-icons@1.2.92':
+ dependencies:
+ '@iconify/types': 2.0.0
+
+ '@iconify/types@2.0.0': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)':
+ dependencies:
+ '@emnapi/core': 1.11.1
+ '@emnapi/runtime': 1.11.1
+ '@tybys/wasm-util': 0.10.3
+ optional: true
+
+ '@oxc-project/types@0.139.0': {}
+
+ '@oxfmt/binding-android-arm-eabi@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-android-arm64@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-darwin-arm64@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-darwin-x64@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-freebsd-x64@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-linux-arm-gnueabihf@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-linux-arm-musleabihf@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-linux-arm64-gnu@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-linux-arm64-musl@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-linux-ppc64-gnu@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-linux-riscv64-gnu@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-linux-riscv64-musl@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-linux-s390x-gnu@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-linux-x64-gnu@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-linux-x64-musl@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-openharmony-arm64@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-win32-arm64-msvc@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-win32-ia32-msvc@0.60.0':
+ optional: true
+
+ '@oxfmt/binding-win32-x64-msvc@0.60.0':
+ optional: true
+
+ '@rolldown/binding-android-arm64@1.1.5':
+ optional: true
+
+ '@rolldown/binding-darwin-arm64@1.1.5':
+ optional: true
+
+ '@rolldown/binding-darwin-x64@1.1.5':
+ optional: true
+
+ '@rolldown/binding-freebsd-x64@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-arm-gnueabihf@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-arm64-gnu@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-arm64-musl@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-ppc64-gnu@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-s390x-gnu@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-x64-gnu@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-x64-musl@1.1.5':
+ optional: true
+
+ '@rolldown/binding-openharmony-arm64@1.1.5':
+ optional: true
+
+ '@rolldown/binding-wasm32-wasi@1.1.5':
+ dependencies:
+ '@emnapi/core': 1.11.1
+ '@emnapi/runtime': 1.11.1
+ '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)
+ optional: true
+
+ '@rolldown/binding-win32-arm64-msvc@1.1.5':
+ optional: true
+
+ '@rolldown/binding-win32-x64-msvc@1.1.5':
+ optional: true
+
+ '@rolldown/pluginutils@1.0.1': {}
+
+ '@shikijs/core@4.3.1':
+ dependencies:
+ '@shikijs/primitive': 4.3.1
+ '@shikijs/types': 4.3.1
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.5
+ hast-util-to-html: 9.0.5
+
+ '@shikijs/engine-javascript@4.3.1':
+ dependencies:
+ '@shikijs/types': 4.3.1
+ '@shikijs/vscode-textmate': 10.0.2
+ oniguruma-to-es: 4.3.6
+
+ '@shikijs/engine-oniguruma@4.3.1':
+ dependencies:
+ '@shikijs/types': 4.3.1
+ '@shikijs/vscode-textmate': 10.0.2
+
+ '@shikijs/langs@4.3.1':
+ dependencies:
+ '@shikijs/types': 4.3.1
+
+ '@shikijs/primitive@4.3.1':
+ dependencies:
+ '@shikijs/types': 4.3.1
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.5
+
+ '@shikijs/themes@4.3.1':
+ dependencies:
+ '@shikijs/types': 4.3.1
+
+ '@shikijs/transformers@4.3.1':
+ dependencies:
+ '@shikijs/core': 4.3.1
+ '@shikijs/types': 4.3.1
+
+ '@shikijs/types@4.3.1':
+ dependencies:
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.5
+
+ '@shikijs/vscode-textmate@10.0.2': {}
+
+ '@tybys/wasm-util@0.10.3':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@types/hast@3.0.5':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/linkify-it@5.0.0': {}
+
+ '@types/markdown-it@14.1.2':
+ dependencies:
+ '@types/linkify-it': 5.0.0
+ '@types/mdurl': 2.0.0
+
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdurl@2.0.0': {}
+
+ '@types/unist@3.0.3': {}
+
+ '@types/web-bluetooth@0.0.21': {}
+
+ '@ungap/structured-clone@1.3.3': {}
+
+ '@vitejs/plugin-vue@6.0.8(vite@8.1.5)(vue@3.5.40)':
+ dependencies:
+ '@rolldown/pluginutils': 1.0.1
+ vite: 8.1.5
+ vue: 3.5.40
+
+ '@vue/compiler-core@3.5.40':
+ dependencies:
+ '@babel/parser': 7.29.7
+ '@vue/shared': 3.5.40
+ entities: 7.0.1
+ estree-walker: 2.0.2
+ source-map-js: 1.2.1
+
+ '@vue/compiler-dom@3.5.40':
+ dependencies:
+ '@vue/compiler-core': 3.5.40
+ '@vue/shared': 3.5.40
+
+ '@vue/compiler-sfc@3.5.40':
+ dependencies:
+ '@babel/parser': 7.29.7
+ '@vue/compiler-core': 3.5.40
+ '@vue/compiler-dom': 3.5.40
+ '@vue/compiler-ssr': 3.5.40
+ '@vue/shared': 3.5.40
+ estree-walker: 2.0.2
+ magic-string: 0.30.21
+ postcss: 8.5.23
+ source-map-js: 1.2.1
+
+ '@vue/compiler-ssr@3.5.40':
+ dependencies:
+ '@vue/compiler-dom': 3.5.40
+ '@vue/shared': 3.5.40
+
+ '@vue/devtools-api@8.2.1':
+ dependencies:
+ '@vue/devtools-kit': 8.2.1
+
+ '@vue/devtools-kit@8.2.1':
+ dependencies:
+ '@vue/devtools-shared': 8.2.1
+ birpc: 2.9.0
+ hookable: 5.5.3
+ perfect-debounce: 2.1.0
+
+ '@vue/devtools-shared@8.2.1': {}
+
+ '@vue/reactivity@3.5.40':
+ dependencies:
+ '@vue/shared': 3.5.40
+
+ '@vue/runtime-core@3.5.40':
+ dependencies:
+ '@vue/reactivity': 3.5.40
+ '@vue/shared': 3.5.40
+
+ '@vue/runtime-dom@3.5.40':
+ dependencies:
+ '@vue/reactivity': 3.5.40
+ '@vue/runtime-core': 3.5.40
+ '@vue/shared': 3.5.40
+ csstype: 3.2.3
+
+ '@vue/server-renderer@3.5.40':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.40
+ '@vue/runtime-dom': 3.5.40
+ '@vue/shared': 3.5.40
+
+ '@vue/shared@3.5.40': {}
+
+ '@vueuse/core@14.3.0(vue@3.5.40)':
+ dependencies:
+ '@types/web-bluetooth': 0.0.21
+ '@vueuse/metadata': 14.3.0
+ '@vueuse/shared': 14.3.0(vue@3.5.40)
+ vue: 3.5.40
+
+ '@vueuse/integrations@14.3.0(focus-trap@8.2.2)(vue@3.5.40)':
+ dependencies:
+ '@vueuse/core': 14.3.0(vue@3.5.40)
+ '@vueuse/shared': 14.3.0(vue@3.5.40)
+ vue: 3.5.40
+ optionalDependencies:
+ focus-trap: 8.2.2
+
+ '@vueuse/metadata@14.3.0': {}
+
+ '@vueuse/shared@14.3.0(vue@3.5.40)':
+ dependencies:
+ vue: 3.5.40
+
+ birpc@2.9.0: {}
+
+ ccount@2.0.1: {}
+
+ character-entities-html4@2.1.0: {}
+
+ character-entities-legacy@3.0.0: {}
+
+ comma-separated-tokens@2.0.3: {}
+
+ csstype@3.2.3: {}
+
+ dequal@2.0.3: {}
+
+ detect-libc@2.1.2: {}
+
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
+ entities@7.0.1: {}
+
+ estree-walker@2.0.2: {}
+
+ fdir@6.5.0(picomatch@4.0.5):
+ optionalDependencies:
+ picomatch: 4.0.5
+
+ focus-trap@8.2.2:
+ dependencies:
+ tabbable: 6.5.0
+
+ fsevents@2.3.3:
+ optional: true
+
+ hast-util-to-html@9.0.5:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ comma-separated-tokens: 2.0.3
+ hast-util-whitespace: 3.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.1
+ property-information: 7.2.0
+ space-separated-tokens: 2.0.2
+ stringify-entities: 4.0.4
+ zwitch: 2.0.4
+
+ hast-util-whitespace@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.5
+
+ hookable@5.5.3: {}
+
+ html-void-elements@3.0.0: {}
+
+ lightningcss-android-arm64@1.33.0:
+ optional: true
+
+ lightningcss-darwin-arm64@1.33.0:
+ optional: true
+
+ lightningcss-darwin-x64@1.33.0:
+ optional: true
+
+ lightningcss-freebsd-x64@1.33.0:
+ optional: true
+
+ lightningcss-linux-arm-gnueabihf@1.33.0:
+ optional: true
+
+ lightningcss-linux-arm64-gnu@1.33.0:
+ optional: true
+
+ lightningcss-linux-arm64-musl@1.33.0:
+ optional: true
+
+ lightningcss-linux-x64-gnu@1.33.0:
+ optional: true
+
+ lightningcss-linux-x64-musl@1.33.0:
+ optional: true
+
+ lightningcss-win32-arm64-msvc@1.33.0:
+ optional: true
+
+ lightningcss-win32-x64-msvc@1.33.0:
+ optional: true
+
+ lightningcss@1.33.0:
+ dependencies:
+ detect-libc: 2.1.2
+ optionalDependencies:
+ lightningcss-android-arm64: 1.33.0
+ lightningcss-darwin-arm64: 1.33.0
+ lightningcss-darwin-x64: 1.33.0
+ lightningcss-freebsd-x64: 1.33.0
+ lightningcss-linux-arm-gnueabihf: 1.33.0
+ lightningcss-linux-arm64-gnu: 1.33.0
+ lightningcss-linux-arm64-musl: 1.33.0
+ lightningcss-linux-x64-gnu: 1.33.0
+ lightningcss-linux-x64-musl: 1.33.0
+ lightningcss-win32-arm64-msvc: 1.33.0
+ lightningcss-win32-x64-msvc: 1.33.0
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ mark.js@8.11.1: {}
+
+ mdast-util-to-hast@13.2.1:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.3.3
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.1
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.1.0
+ vfile: 6.0.3
+
+ micromark-util-character@2.1.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-encode@2.0.1: {}
+
+ micromark-util-sanitize-uri@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-encode: 2.0.1
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-symbol@2.0.1: {}
+
+ micromark-util-types@2.0.2: {}
+
+ minisearch@7.2.0: {}
+
+ nanoid@3.3.16: {}
+
+ node@runtime:22.22.3: {}
+
+ oniguruma-parser@0.12.2: {}
+
+ oniguruma-to-es@4.3.6:
+ dependencies:
+ oniguruma-parser: 0.12.2
+ regex: 6.1.0
+ regex-recursion: 6.0.2
+
+ oxfmt@0.60.0:
+ dependencies:
+ tinypool: 2.1.0
+ optionalDependencies:
+ '@oxfmt/binding-android-arm-eabi': 0.60.0
+ '@oxfmt/binding-android-arm64': 0.60.0
+ '@oxfmt/binding-darwin-arm64': 0.60.0
+ '@oxfmt/binding-darwin-x64': 0.60.0
+ '@oxfmt/binding-freebsd-x64': 0.60.0
+ '@oxfmt/binding-linux-arm-gnueabihf': 0.60.0
+ '@oxfmt/binding-linux-arm-musleabihf': 0.60.0
+ '@oxfmt/binding-linux-arm64-gnu': 0.60.0
+ '@oxfmt/binding-linux-arm64-musl': 0.60.0
+ '@oxfmt/binding-linux-ppc64-gnu': 0.60.0
+ '@oxfmt/binding-linux-riscv64-gnu': 0.60.0
+ '@oxfmt/binding-linux-riscv64-musl': 0.60.0
+ '@oxfmt/binding-linux-s390x-gnu': 0.60.0
+ '@oxfmt/binding-linux-x64-gnu': 0.60.0
+ '@oxfmt/binding-linux-x64-musl': 0.60.0
+ '@oxfmt/binding-openharmony-arm64': 0.60.0
+ '@oxfmt/binding-win32-arm64-msvc': 0.60.0
+ '@oxfmt/binding-win32-ia32-msvc': 0.60.0
+ '@oxfmt/binding-win32-x64-msvc': 0.60.0
+
+ perfect-debounce@2.1.0: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@4.0.5: {}
+
+ postcss@8.5.23:
+ dependencies:
+ nanoid: 3.3.16
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ property-information@7.2.0: {}
+
+ regex-recursion@6.0.2:
+ dependencies:
+ regex-utilities: 2.3.0
+
+ regex-utilities@2.3.0: {}
+
+ regex@6.1.0:
+ dependencies:
+ regex-utilities: 2.3.0
+
+ rolldown@1.1.5:
+ dependencies:
+ '@oxc-project/types': 0.139.0
+ '@rolldown/pluginutils': 1.0.1
+ optionalDependencies:
+ '@rolldown/binding-android-arm64': 1.1.5
+ '@rolldown/binding-darwin-arm64': 1.1.5
+ '@rolldown/binding-darwin-x64': 1.1.5
+ '@rolldown/binding-freebsd-x64': 1.1.5
+ '@rolldown/binding-linux-arm-gnueabihf': 1.1.5
+ '@rolldown/binding-linux-arm64-gnu': 1.1.5
+ '@rolldown/binding-linux-arm64-musl': 1.1.5
+ '@rolldown/binding-linux-ppc64-gnu': 1.1.5
+ '@rolldown/binding-linux-s390x-gnu': 1.1.5
+ '@rolldown/binding-linux-x64-gnu': 1.1.5
+ '@rolldown/binding-linux-x64-musl': 1.1.5
+ '@rolldown/binding-openharmony-arm64': 1.1.5
+ '@rolldown/binding-wasm32-wasi': 1.1.5
+ '@rolldown/binding-win32-arm64-msvc': 1.1.5
+ '@rolldown/binding-win32-x64-msvc': 1.1.5
+
+ shiki@4.3.1:
+ dependencies:
+ '@shikijs/core': 4.3.1
+ '@shikijs/engine-javascript': 4.3.1
+ '@shikijs/engine-oniguruma': 4.3.1
+ '@shikijs/langs': 4.3.1
+ '@shikijs/themes': 4.3.1
+ '@shikijs/types': 4.3.1
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.5
+
+ source-map-js@1.2.1: {}
+
+ space-separated-tokens@2.0.2: {}
+
+ stringify-entities@4.0.4:
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
+
+ tabbable@6.5.0: {}
+
+ tinyglobby@0.2.17:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.5)
+ picomatch: 4.0.5
+
+ tinypool@2.1.0: {}
+
+ trim-lines@3.0.1: {}
+
+ tslib@2.8.1:
+ optional: true
+
+ unist-util-is@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.0.2:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-visit@5.1.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ vfile-message@4.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.3
+
+ vite@8.1.5:
+ dependencies:
+ lightningcss: 1.33.0
+ picomatch: 4.0.5
+ postcss: 8.5.23
+ rolldown: 1.1.5
+ tinyglobby: 0.2.17
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ vitepress@2.0.0-alpha.18(postcss@8.5.23):
+ dependencies:
+ '@docsearch/css': 4.6.3
+ '@docsearch/js': 4.6.3
+ '@docsearch/sidepanel-js': 4.6.3
+ '@iconify-json/simple-icons': 1.2.92
+ '@shikijs/core': 4.3.1
+ '@shikijs/transformers': 4.3.1
+ '@shikijs/types': 4.3.1
+ '@types/markdown-it': 14.1.2
+ '@vitejs/plugin-vue': 6.0.8(vite@8.1.5)(vue@3.5.40)
+ '@vue/devtools-api': 8.2.1
+ '@vue/shared': 3.5.40
+ '@vueuse/core': 14.3.0(vue@3.5.40)
+ '@vueuse/integrations': 14.3.0(focus-trap@8.2.2)(vue@3.5.40)
+ focus-trap: 8.2.2
+ mark.js: 8.11.1
+ minisearch: 7.2.0
+ shiki: 4.3.1
+ vite: 8.1.5
+ vue: 3.5.40
+ optionalDependencies:
+ postcss: 8.5.23
+ transitivePeerDependencies:
+ - '@types/node'
+ - '@vitejs/devtools'
+ - async-validator
+ - axios
+ - change-case
+ - drauu
+ - esbuild
+ - fuse.js
+ - idb-keyval
+ - jiti
+ - jwt-decode
+ - less
+ - nprogress
+ - qrcode
+ - sass
+ - sass-embedded
+ - sortablejs
+ - stylus
+ - sugarss
+ - terser
+ - tsx
+ - typescript
+ - universal-cookie
+ - yaml
+
+ vue@3.5.40:
+ dependencies:
+ '@vue/compiler-dom': 3.5.40
+ '@vue/compiler-sfc': 3.5.40
+ '@vue/runtime-dom': 3.5.40
+ '@vue/server-renderer': 3.5.40
+ '@vue/shared': 3.5.40
+
+ zwitch@2.0.4: {}
diff --git a/website/scripts/configure-pages.mjs b/website/scripts/configure-pages.mjs
new file mode 100644
index 0000000..c29eb74
--- /dev/null
+++ b/website/scripts/configure-pages.mjs
@@ -0,0 +1,123 @@
+import { appendFile } from 'node:fs/promises'
+
+const apiToken = process.env.CLOUDFLARE_API_TOKEN
+const accountId = process.env.CLOUDFLARE_ACCOUNT_ID
+const projectName = process.env.CLOUDFLARE_PAGES_PROJECT
+const domainName = process.env.CLOUDFLARE_PAGES_DOMAIN || 'inkcre.dev'
+const stage = process.argv[2] || 'all'
+
+if (!apiToken || !accountId || !projectName) {
+ throw new Error('Cloudflare Pages configuration requires token, account, and project inputs')
+}
+if (!['all', 'project', 'domain'].includes(stage)) {
+ throw new Error(`Unknown Cloudflare Pages configuration stage: ${stage}`)
+}
+
+const apiBase = `https://api.cloudflare.com/client/v4/accounts/${accountId}/pages`
+
+async function request(path, init = {}) {
+ let lastError
+
+ for (let attempt = 1; attempt <= 4; attempt += 1) {
+ try {
+ const response = await fetch(`${apiBase}${path}`, {
+ ...init,
+ headers: {
+ Authorization: `Bearer ${apiToken}`,
+ 'Content-Type': 'application/json',
+ ...init.headers,
+ },
+ signal: AbortSignal.timeout(15000),
+ })
+ const payload = await response.json()
+
+ if (response.status === 429 || response.status >= 500) {
+ throw new Error(`Cloudflare API returned retryable HTTP ${response.status}`)
+ }
+
+ return { response, payload }
+ } catch (error) {
+ lastError = error
+ if (attempt < 4) {
+ await new Promise((resolve) => setTimeout(resolve, attempt * 1000))
+ }
+ }
+ }
+
+ throw lastError
+}
+
+function assertSuccess(operation, response, payload) {
+ if (!response.ok || !payload.success) {
+ const details = payload.errors?.map((error) => error.message).join('; ') || 'unknown error'
+ throw new Error(`${operation} failed with HTTP ${response.status}: ${details}`)
+ }
+}
+
+const projectPath = `/projects/${encodeURIComponent(projectName)}`
+let projectResult = await request(projectPath)
+
+if (projectResult.response.status === 404) {
+ projectResult = await request('/projects', {
+ method: 'POST',
+ body: JSON.stringify({
+ name: projectName,
+ production_branch: 'main',
+ }),
+ })
+ assertSuccess('Create Pages project', projectResult.response, projectResult.payload)
+} else {
+ assertSuccess('Read Pages project', projectResult.response, projectResult.payload)
+}
+
+if (projectResult.payload.result?.source) {
+ throw new Error(`${projectName} is not a Direct Upload Pages project`)
+}
+
+if (projectResult.payload.result?.production_branch !== 'main') {
+ projectResult = await request(projectPath, {
+ method: 'PATCH',
+ body: JSON.stringify({ production_branch: 'main' }),
+ })
+ assertSuccess('Set Pages production branch', projectResult.response, projectResult.payload)
+}
+
+if (stage === 'project') {
+ console.log(`Cloudflare Pages project ${projectName} is configured.`)
+ process.exit(0)
+}
+
+const domainPath = `${projectPath}/domains/${encodeURIComponent(domainName)}`
+let domainResult = await request(domainPath)
+
+if (domainResult.response.status === 404) {
+ domainResult = await request(`${projectPath}/domains`, {
+ method: 'POST',
+ body: JSON.stringify({ name: domainName }),
+ })
+ assertSuccess('Attach Pages custom domain', domainResult.response, domainResult.payload)
+} else {
+ assertSuccess('Read Pages custom domain', domainResult.response, domainResult.payload)
+}
+
+const domainStatus = domainResult.payload.result?.status
+if (['blocked', 'deactivated', 'error'].includes(domainStatus)) {
+ throw new Error(`${domainName} entered unusable Cloudflare Pages status: ${domainStatus}`)
+}
+
+console.log(`Cloudflare Pages project ${projectName} and domain ${domainName} are configured.`)
+
+if (process.env.GITHUB_STEP_SUMMARY) {
+ await appendFile(
+ process.env.GITHUB_STEP_SUMMARY,
+ [
+ '## Cloudflare Pages configuration',
+ '',
+ `- Project: \`${projectName}\``,
+ `- Production branch: \`main\``,
+ `- Custom domain: \`${domainName}\``,
+ `- Domain status before delivery: \`${domainStatus}\``,
+ '',
+ ].join('\n')
+ )
+}
diff --git a/website/scripts/verify-build.mjs b/website/scripts/verify-build.mjs
new file mode 100644
index 0000000..81f49e3
--- /dev/null
+++ b/website/scripts/verify-build.mjs
@@ -0,0 +1,121 @@
+import { readdir, readFile } from 'node:fs/promises'
+import { relative } from 'node:path'
+import { fileURLToPath } from 'node:url'
+
+const distUrl = new URL('../.vitepress/dist/', import.meta.url)
+const indexUrl = new URL('index.html', distUrl)
+const canonicalOrigin = 'https://inkcre.dev'
+
+async function collectHtml(directoryUrl) {
+ const entries = await readdir(directoryUrl, { withFileTypes: true })
+ const files = []
+
+ for (const entry of entries) {
+ const entryUrl = new URL(entry.name + (entry.isDirectory() ? '/' : ''), directoryUrl)
+
+ if (entry.isDirectory()) {
+ files.push(...(await collectHtml(entryUrl)))
+ } else if (entry.name.endsWith('.html')) {
+ files.push(entryUrl)
+ }
+ }
+
+ return files
+}
+
+function fail(message) {
+ throw new Error(`Website build contract failed: ${message}`)
+}
+
+function publicPathForOutput(routePath) {
+ if (routePath === 'index.html') {
+ return '/'
+ }
+
+ if (routePath.endsWith('/index.html')) {
+ return `/${routePath.slice(0, -'index.html'.length)}`
+ }
+
+ return `/${routePath.slice(0, -'.html'.length)}`
+}
+
+const indexHtml = await readFile(indexUrl, 'utf8').catch(() => {
+ fail('the public root did not produce index.html')
+})
+
+if (!indexHtml.includes('`)) {
+ fail('the public root has no canonical production URL')
+}
+
+if (!indexHtml.includes(``)) {
+ fail('the public root has no Open Graph production URL')
+}
+
+const sitemap = await readFile(new URL('sitemap.xml', distUrl), 'utf8').catch(() => {
+ fail('the production build did not emit sitemap.xml')
+})
+
+if (!sitemap.includes(`${canonicalOrigin}/`)) {
+ fail('the sitemap does not contain the canonical public root')
+}
+
+const robots = await readFile(new URL('robots.txt', distUrl), 'utf8').catch(() => {
+ fail('the production build did not emit robots.txt')
+})
+
+if (!robots.includes(`Sitemap: ${canonicalOrigin}/sitemap.xml`)) {
+ fail('robots.txt does not advertise the canonical sitemap')
+}
+
+const headers = await readFile(new URL('_headers', distUrl), 'utf8').catch(() => {
+ fail('the production build did not emit Cloudflare Pages headers')
+})
+
+if (
+ !headers.includes('https://inkcre-website.pages.dev/*') ||
+ !headers.includes('https://:version.inkcre-website.pages.dev/*') ||
+ !headers.includes('X-Robots-Tag: noindex')
+) {
+ fail('Cloudflare Pages origins are not protected from indexing')
+}
+
+const htmlFiles = await collectHtml(distUrl)
+const distPath = fileURLToPath(distUrl)
+
+for (const fileUrl of htmlFiles) {
+ const filePath = fileURLToPath(fileUrl)
+ const routePath = relative(distPath, filePath)
+ const html = await readFile(fileUrl, 'utf8')
+
+ if (routePath === 'en/index.html' || routePath.startsWith('en/')) {
+ fail(`the default locale leaked into the public route: ${routePath}`)
+ }
+
+ const pageUrl = new URL(publicPathForOutput(routePath), 'https://website.invalid')
+
+ for (const match of html.matchAll(/\b(?:href|src)="([^"]+)"/g)) {
+ const generatedUrl = new URL(match[1], pageUrl)
+
+ if (generatedUrl.origin !== pageUrl.origin) {
+ continue
+ }
+
+ if (/^\/en(?:\/|$)/.test(generatedUrl.pathname)) {
+ fail(`the default locale leaked into a generated link in ${routePath}`)
+ }
+
+ if (/\.(?:html|md)$/.test(generatedUrl.pathname)) {
+ fail(`a generated internal link exposes a source or output extension in ${routePath}`)
+ }
+ }
+}
+
+console.log(`Verified ${htmlFiles.length} generated HTML files and the English root route.`)
diff --git a/website/scripts/verify-pages-deployment.mjs b/website/scripts/verify-pages-deployment.mjs
new file mode 100644
index 0000000..22e172b
--- /dev/null
+++ b/website/scripts/verify-pages-deployment.mjs
@@ -0,0 +1,114 @@
+import { appendFile } from 'node:fs/promises'
+
+const deploymentId = process.env.CLOUDFLARE_PAGES_DEPLOYMENT_ID
+const deploymentUrl = process.env.CLOUDFLARE_PAGES_DEPLOYMENT_URL
+const canonicalOrigin = new URL(process.env.INKCRE_WEBSITE_ORIGIN || 'https://inkcre.dev')
+
+if (!deploymentId) {
+ throw new Error('Wrangler did not report a Cloudflare Pages deployment ID')
+}
+if (!deploymentUrl) {
+ throw new Error('Wrangler did not report a Cloudflare Pages deployment URL')
+}
+
+const pagesOrigin = new URL(deploymentUrl)
+if (pagesOrigin.protocol !== 'https:' || !pagesOrigin.hostname.endsWith('.pages.dev')) {
+ throw new Error(`Unexpected Cloudflare Pages deployment URL: ${pagesOrigin.origin}`)
+}
+
+async function fetchPage(url) {
+ return fetch(url, {
+ redirect: 'error',
+ signal: AbortSignal.timeout(10000),
+ })
+}
+
+async function verifyOriginOnce(origin, expectNoindex) {
+ const rootResponse = await fetchPage(new URL('/', origin))
+ const rootBody = await rootResponse.text()
+
+ if (rootResponse.status !== 200) {
+ throw new Error(`${origin.origin}/ returned HTTP ${rootResponse.status}`)
+ }
+ if (!rootResponse.headers.get('content-type')?.startsWith('text/html')) {
+ throw new Error(`${origin.origin}/ did not return HTML`)
+ }
+ if (!rootBody.includes('`)) {
+ throw new Error(`${origin.origin}/ did not declare ${canonicalOrigin.href} as canonical`)
+ }
+
+ const robotsHeader = rootResponse.headers.get('x-robots-tag') || ''
+ if (expectNoindex !== robotsHeader.toLowerCase().includes('noindex')) {
+ throw new Error(`${origin.origin}/ returned an unexpected X-Robots-Tag: ${robotsHeader}`)
+ }
+
+ const missingResponse = await fetchPage(new URL('/__inkcre_pages_missing__', origin))
+ if (missingResponse.status !== 404) {
+ throw new Error(`${origin.origin} missing route returned HTTP ${missingResponse.status}`)
+ }
+
+ const sitemapResponse = await fetchPage(new URL('/sitemap.xml', origin))
+ const sitemap = await sitemapResponse.text()
+ if (sitemapResponse.status !== 200 || !sitemap.includes(`${canonicalOrigin.href}`)) {
+ throw new Error(`${origin.origin}/sitemap.xml does not expose the canonical root`)
+ }
+
+ const robotsResponse = await fetchPage(new URL('/robots.txt', origin))
+ const robots = await robotsResponse.text()
+ if (
+ robotsResponse.status !== 200 ||
+ !robots.includes(`Sitemap: ${canonicalOrigin.href}sitemap.xml`)
+ ) {
+ throw new Error(`${origin.origin}/robots.txt does not expose the canonical sitemap`)
+ }
+}
+
+async function verifyOrigin(origin, { attempts, delayMs, expectNoindex }) {
+ let lastError
+
+ for (let attempt = 1; attempt <= attempts; attempt += 1) {
+ try {
+ await verifyOriginOnce(origin, expectNoindex)
+ return
+ } catch (error) {
+ lastError = error
+ if (attempt < attempts) {
+ await new Promise((resolve) => setTimeout(resolve, delayMs))
+ }
+ }
+ }
+
+ throw lastError
+}
+
+await verifyOrigin(pagesOrigin, {
+ attempts: 5,
+ delayMs: 1000,
+ expectNoindex: true,
+})
+
+await verifyOrigin(canonicalOrigin, {
+ attempts: 60,
+ delayMs: 10000,
+ expectNoindex: false,
+})
+
+console.log(`Verified Pages deployment ${deploymentId} and ${canonicalOrigin.origin}.`)
+
+if (process.env.GITHUB_STEP_SUMMARY) {
+ await appendFile(
+ process.env.GITHUB_STEP_SUMMARY,
+ [
+ '## Cloudflare Pages deployment',
+ '',
+ `- Deployment ID: \`${deploymentId}\``,
+ `- Immutable URL: ${pagesOrigin.origin}`,
+ `- Canonical URL: ${canonicalOrigin.origin}`,
+ '- HTTPS, metadata, sitemap, robots, noindex, and 404 smoke: passed',
+ '',
+ ].join('\n')
+ )
+}