diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc18afd3..739358f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,4 +37,18 @@ jobs: - run: pnpm install --frozen-lockfile + - run: pnpm check:types + - run: pnpm build + + theme-sync: + name: Shared theme in sync with makeplane/developer-docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 24 + + - run: node docs/.vitepress/theme/plane/scripts/check-theme-sync.mjs --sibling makeplane/developer-docs diff --git a/AGENTS.md b/AGENTS.md index 7d0a65bd..5cb50498 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,17 +2,17 @@ ## Project overview -This is the [Plane](https://plane.so) product documentation site, built with [VitePress v1.6.3](https://vitepress.dev/) and hosted at [docs.plane.so](https://docs.plane.so). All content lives in the `docs/` directory as Markdown files. +This is the [Plane](https://plane.so) product documentation site, built with [VitePress](https://vitepress.dev/) (version in the table below) and hosted at [docs.plane.so](https://docs.plane.so). All content lives in the `docs/` directory as Markdown files. ## Stack -| Tool | Version/Notes | -| --------------- | --------------- | -| Framework | VitePress 1.6.3 | -| Package manager | pnpm 11.8.0 | -| Node | >=24.0.0 | -| Formatting | oxfmt | -| Styling | Tailwind CSS v4 | +| Tool | Version/Notes | +| --------------- | ------------------------------------------------------------------- | +| Framework | VitePress 2.0.0-alpha.16 (pinned; same as makeplane/developer-docs) | +| Package manager | pnpm 11.8.0 | +| Node | >=24.0.0 | +| Formatting | oxfmt | +| Styling | Tailwind CSS v4 | ## Common commands @@ -22,6 +22,8 @@ pnpm build # Build static output into docs/.vitepress/dist pnpm preview # Preview the production build locally pnpm fix:format # Auto-format all files with oxfmt pnpm check:format # Check formatting without writing +pnpm check:types # Type-check the VitePress config and theme +pnpm check:theme-sync # Verify docs/.vitepress/theme/plane/ is identical to makeplane/developer-docs (THEME_SIBLING_PATH=../developer-docs for a local checkout) ``` ## Repo structure @@ -30,7 +32,10 @@ pnpm check:format # Check formatting without writing docs/ # All content and VitePress config .vitepress/ config.ts # VitePress config — nav, sidebar, search, head tags - theme/ # Custom theme overrides + theme/ + index.ts # createPlaneTheme({ brand }) — this site's branding only + site.css # site-specific CSS (keep tiny; shared styles go in plane/) + plane/ # SHARED THEME — byte-identical with makeplane/developer-docs (see below) index.md # Home page (hero layout) introduction/ # Quickstart, tutorials, core-concepts overview core-concepts/ # Issues, projects, workspaces, pages, cycles, modules @@ -77,6 +82,18 @@ The sidebar and top nav are configured entirely in `docs/.vitepress/config.ts`. 2. Add an entry to the relevant sidebar section in `config.ts`. 3. If it needs a top-nav link, add it to `themeConfig.nav`. +## Shared theme (`docs/.vitepress/theme/plane/`) + +The visual identity (tokens, fonts, header, layout, `Card`/`CardGroup`/`Tags`, Copy page menu, cookie +consent) lives in `docs/.vitepress/theme/plane/` and is **byte-identical** with the same folder in +`makeplane/developer-docs`. Rules: + +- Edit shared files in one repo, copy the whole folder to the sibling repo, run `pnpm check:theme-sync` + in both (CI runs it too). Add new files to `plane/manifest.json`. +- Site-specific things (logo URLs, extra components, nav) go through `createPlaneTheme(...)` options in + `theme/index.ts` or into `theme/site.css` — never edit `plane/` for one site only. +- Header buttons come from `themeConfig.nav` items flagged `planeButton: "primary" | "secondary"`. + ## Formatting Run `pnpm fix:format` before committing. CI checks formatting via `pnpm check:format`. Never skip this step. diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index e6bb0b36..2a0264f1 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -31,7 +31,7 @@ const posthogHead: HeadConfig[] = posthogKey "script", {}, `!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys onSessionId".split(" "),n=0;n +/// +/// +/// diff --git a/docs/.vitepress/theme/Layout.vue b/docs/.vitepress/theme/Layout.vue deleted file mode 100644 index 0be3a6b6..00000000 --- a/docs/.vitepress/theme/Layout.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/docs/.vitepress/theme/components/Card.vue b/docs/.vitepress/theme/components/Card.vue deleted file mode 100644 index 2e952579..00000000 --- a/docs/.vitepress/theme/components/Card.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - diff --git a/docs/.vitepress/theme/components/CardGroup.vue b/docs/.vitepress/theme/components/CardGroup.vue deleted file mode 100644 index 335095f6..00000000 --- a/docs/.vitepress/theme/components/CardGroup.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/docs/.vitepress/theme/components/Tags.vue b/docs/.vitepress/theme/components/Tags.vue deleted file mode 100644 index bab1e6f9..00000000 --- a/docs/.vitepress/theme/components/Tags.vue +++ /dev/null @@ -1,27 +0,0 @@ - - - diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index 42de6831..5b961de3 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -1,314 +1,17 @@ -import type { Theme } from "vitepress"; -import type { ThemeContext } from "@voidzero-dev/vitepress-theme"; -import VoidZeroTheme from "@voidzero-dev/vitepress-theme"; -import { themeContextKey } from "@voidzero-dev/vitepress-theme"; -import { onMounted, onUnmounted, watch, nextTick } from "vue"; -import { useData, useRoute } from "vitepress"; -import { enhanceAppWithTabs } from "vitepress-plugin-tabs/client"; -import mediumZoom from "medium-zoom"; -import Card from "./components/Card.vue"; -import CardGroup from "./components/CardGroup.vue"; -import Tags from "./components/Tags.vue"; -import Layout from "./Layout.vue"; -import "./style.css"; - -/** - * OSSHeader (used on doc pages) injects this context for the bar logo — *not* `themeConfig.logo`. - * The `viteplus` entry in the package overwrites it with "Vite+" assets; we use the base - * `VoidZeroTheme` and provide Plane branding here. - */ -const planeThemeContext: ThemeContext = { - /* OSSHeader renders logoDark in light mode and logoLight in dark mode. */ - logoDark: "https://media.docs.plane.so/logo/new-logo-white.png", - logoLight: "https://media.docs.plane.so/logo/new-logo-dark.png", - logoAlt: "Plane", - footerBg: "https://media.docs.plane.so/logo/og-docs.webp", - monoIcon: "https://media.docs.plane.so/logo/favicon-32x32.png", -}; - -/** - * Handles tab activation based on URL hash - */ -function handleTabHash() { - if (typeof document === "undefined") return; - - const hash = window.location.hash.slice(1); // Remove the '#' - if (!hash) return; - - const tabButtons = document.querySelectorAll('[role="tab"]'); - - if (tabButtons.length === 0) { - return; - } - - tabButtons.forEach((button) => { - const labelText = button.textContent?.trim().toLowerCase().replace(/\s+/g, "-"); - - if (labelText === hash) { - const element = button as HTMLElement; - - // Dispatch a proper mouse event - const clickEvent = new MouseEvent("click", { - view: window, - bubbles: true, - cancelable: true, - }); - - element.dispatchEvent(clickEvent); - element.click(); - element.focus(); - } - }); -} - /** - * Adds click listeners to tabs to update URL hash + * docs.plane.so theme = shared Plane docs theme (./plane, byte-identical with + * makeplane/developer-docs) + this site's branding. */ -function setupTabHashUpdates() { - if (typeof document === "undefined") return; - - const tabButtons = document.querySelectorAll('[role="tab"]'); - - tabButtons.forEach((button) => { - const element = button as HTMLElement; - - // Remove existing listener if any - element.removeEventListener("click", updateHashOnTabClick); - - // Add new listener - element.addEventListener("click", updateHashOnTabClick); - }); -} - -function updateHashOnTabClick(event: Event) { - const button = event.currentTarget as HTMLElement; - const labelText = button.textContent?.trim().toLowerCase().replace(/\s+/g, "-"); - - if (labelText) { - // Update URL hash without triggering scroll - history.replaceState(null, "", `#${labelText}`); - } -} - -/** - * Move "Sign in" CTA to the right utility area (between search and theme toggle). - * The upstream OSSHeader renders nav links on the left; we remap only this CTA. - * Returns true if the link was found and moved (or already in the target region). - */ -function moveSignInToUtilityArea(): boolean { - if (typeof document === "undefined") return false; - - const signInLink = document.querySelector( - '.docs-layout header a.VPLink[href*="sign-in"]', - ) as HTMLAnchorElement | null; - if (!signInLink) return false; - - // Keep the CTA hidden while we're still deciding where it belongs. - signInLink.classList.add("sign-in-relocating"); - - const markRelocated = () => { - signInLink.classList.add("sign-in-relocated"); - signInLink.classList.remove("sign-in-relocating"); - }; - - if (signInLink.classList.contains("sign-in-relocated")) { - signInLink.classList.remove("sign-in-relocating"); - return true; - } - - const appearanceToggle = document.querySelector( - ".docs-layout header .VPNavBarAppearance", - ) as HTMLElement | null; - - if ( - appearanceToggle?.parentElement && - signInLink.parentElement === appearanceToggle.parentElement - ) { - markRelocated(); - return true; - } - - const extraMenu = document.querySelector( - ".docs-layout header .VPNavBarExtra", - ) as HTMLElement | null; - if (extraMenu?.parentElement && signInLink.parentElement === extraMenu.parentElement) { - markRelocated(); - return true; - } - - // Desktop (xl+): insert before theme toggle inside the utilities row. - if ( - appearanceToggle?.parentElement && - signInLink.parentElement !== appearanceToggle.parentElement - ) { - appearanceToggle.parentElement.insertBefore(signInLink, appearanceToggle); - markRelocated(); - return true; - } - - // Tablet fallback (lg-xl): keep it in right controls row before the extra menu. - if (extraMenu?.parentElement && signInLink.parentElement !== extraMenu.parentElement) { - extraMenu.parentElement.insertBefore(signInLink, extraMenu); - markRelocated(); - return true; - } - - return false; -} - -let signInRelocateWarned = false; - -function runSignInRelocationWithRetries() { - if (typeof document === "undefined" || !document.querySelector(".docs-layout")) { - return; - } - - const tryOnce = (attempt: number) => { - if (moveSignInToUtilityArea()) { - return; - } - if (attempt < 40) { - window.setTimeout(() => tryOnce(attempt + 1), 75); - } else if (!signInRelocateWarned) { - const link = document.querySelector('.docs-layout header a.VPLink[href*="sign-in"]'); - if (link) { - link.classList.remove("sign-in-relocating"); - } - if (link && !link.classList.contains("sign-in-relocated")) { - signInRelocateWarned = true; - console.warn( - "[plane-docs] Sign-in could not be relocated (header not ready or selectors changed).", - ); - } - } - }; - - tryOnce(0); -} - -function debounce(fn: () => void, ms: number) { - let t: ReturnType | undefined; - return () => { - if (t) clearTimeout(t); - t = setTimeout(fn, ms); - }; -} - -export default { - extends: VoidZeroTheme, - Layout, - enhanceApp(ctx) { - VoidZeroTheme.enhanceApp?.(ctx); - ctx.app.provide(themeContextKey, planeThemeContext); - enhanceAppWithTabs(ctx.app); - ctx.app.component("Card", Card); - ctx.app.component("CardGroup", CardGroup); - ctx.app.component("Tags", Tags); - }, - setup() { - if (typeof window === "undefined") return; - - const route = useRoute(); - const { isDark } = useData(); - - /** - * VitePress’s inline "check-dark-mode" script only adds the `dark` class and - * never removes it, so a stale `class="dark"` on (e.g. after SSG) can - * persist in light mode. That leaves `.dark …` global/navbar rules applied - * until a theme toggle re-syncs. Keep `documentElement` in lockstep with - * `isDark` (same source of truth as the toggle). - */ - const syncOssHeaderThemeAttr = (dark: boolean) => { - const header = document.querySelector(".docs-layout header") as HTMLElement | null; - const bar = header?.parentElement; - if (!bar) return; - if (dark) bar.setAttribute("data-theme", "dark"); - else bar.removeAttribute("data-theme"); - }; - - watch( - isDark, - (dark) => { - document.documentElement.classList.toggle("dark", dark); - syncOssHeaderThemeAttr(dark); - }, - { immediate: true }, - ); - - onMounted(() => { - syncOssHeaderThemeAttr(isDark.value); - }); - - const zoom = mediumZoom(".vp-doc img", { - background: "rgba(0, 0, 0, 0.8)", - }); - - let headerObserver: MutationObserver | null = null; - let onResize: (() => void) | null = null; - - onMounted(() => { - runSignInRelocationWithRetries(); - - // Delay tab hash handling to ensure tabs are rendered - setTimeout(() => { - handleTabHash(); - setupTabHashUpdates(); - }, 100); - - const onHeaderMutations = debounce(() => { - runSignInRelocationWithRetries(); - }, 100); - - const tryAttachHeaderObserver = () => { - if (headerObserver) return; - const h = document.querySelector(".docs-layout header"); - if (!h) return; - headerObserver = new MutationObserver(onHeaderMutations); - headerObserver.observe(h, { childList: true, subtree: true }); - }; - tryAttachHeaderObserver(); - if (!headerObserver) { - const id = window.setInterval(() => { - tryAttachHeaderObserver(); - if (headerObserver) { - clearInterval(id); - } - }, 120); - window.setTimeout(() => clearInterval(id), 5000); - } - - onResize = debounce(() => { - runSignInRelocationWithRetries(); - }, 150); - window.addEventListener("resize", onResize); - - // Listen for hash changes - window.addEventListener("hashchange", () => { - nextTick(handleTabHash); - }); - }); - - onUnmounted(() => { - headerObserver?.disconnect(); - headerObserver = null; - if (onResize) { - window.removeEventListener("resize", onResize); - onResize = null; - } - }); - - // Watch for route changes - watch( - () => route.path, - () => { - nextTick(() => { - zoom.detach(); - zoom.attach(":not(a) > img:not(.VPImage)"); - handleTabHash(); - setupTabHashUpdates(); - runSignInRelocationWithRetries(); - }); - }, - ); +import { createPlaneTheme } from "./plane"; +import "./site.css"; + +export default createPlaneTheme({ + brand: { + logoOnLight: "https://media.docs.plane.so/logo/new-logo-white.png", + logoOnDark: "https://media.docs.plane.so/logo/new-logo-dark.png", + logoAlt: "Plane", + menuTitle: "Plane Docs", + footerBg: "https://media.docs.plane.so/logo/og-docs.webp", + monoIcon: "https://media.docs.plane.so/logo/favicon-32x32.png", }, -} satisfies Theme; +}); diff --git a/docs/.vitepress/theme/plane/README.md b/docs/.vitepress/theme/plane/README.md new file mode 100644 index 00000000..e3351ae0 --- /dev/null +++ b/docs/.vitepress/theme/plane/README.md @@ -0,0 +1,16 @@ +# Plane docs theme (shared) + +This folder is **byte-identical** in [makeplane/docs](https://github.com/makeplane/docs) and +[makeplane/developer-docs](https://github.com/makeplane/developer-docs) — it is the single source of the +visual identity for docs.plane.so and developers.plane.so (tokens, fonts, header, layout, Card/CardGroup/Tags, +Copy page menu, cookie consent). + +- Each site's `docs/.vitepress/theme/index.ts` is a thin `createPlaneTheme({ brand, … })` call; anything + site-specific (logo URLs, extra components, `.api-page` toggling) is passed in as options or lives outside + this folder. +- **Editing:** change files here in one repo, copy the whole folder to the sibling repo, and run + `pnpm check:theme-sync` in both (locally: `THEME_SIBLING_PATH=../ pnpm check:theme-sync`). + CI runs the same check against the sibling's `master` (or a same-named PR branch). +- **Formatting:** files here are formatted so that oxfmt (docs) and prettier (developer-docs, via the + `.prettierrc` override for this folder) agree — keep `printWidth: 100`, `trailingComma: "all"`. +- Add new files to `manifest.json`. diff --git a/docs/.vitepress/theme/plane/components/Card.vue b/docs/.vitepress/theme/plane/components/Card.vue new file mode 100644 index 00000000..64b78b8f --- /dev/null +++ b/docs/.vitepress/theme/plane/components/Card.vue @@ -0,0 +1,81 @@ + + + diff --git a/docs/.vitepress/theme/plane/components/CardGroup.vue b/docs/.vitepress/theme/plane/components/CardGroup.vue new file mode 100644 index 00000000..16256d57 --- /dev/null +++ b/docs/.vitepress/theme/plane/components/CardGroup.vue @@ -0,0 +1,20 @@ + + + diff --git a/docs/.vitepress/theme/plane/components/CookieConsent.vue b/docs/.vitepress/theme/plane/components/CookieConsent.vue new file mode 100644 index 00000000..5687eb4d --- /dev/null +++ b/docs/.vitepress/theme/plane/components/CookieConsent.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/docs/.vitepress/theme/components/CopyPageMenu.vue b/docs/.vitepress/theme/plane/components/CopyPageMenu.vue similarity index 98% rename from docs/.vitepress/theme/components/CopyPageMenu.vue rename to docs/.vitepress/theme/plane/components/CopyPageMenu.vue index 75b5f168..762a91ec 100644 --- a/docs/.vitepress/theme/components/CopyPageMenu.vue +++ b/docs/.vitepress/theme/plane/components/CopyPageMenu.vue @@ -1,5 +1,3 @@ - - + + + + diff --git a/docs/.vitepress/theme/plane/components/Tags.vue b/docs/.vitepress/theme/plane/components/Tags.vue new file mode 100644 index 00000000..ddcdfb72 --- /dev/null +++ b/docs/.vitepress/theme/plane/components/Tags.vue @@ -0,0 +1,11 @@ + + + diff --git a/docs/.vitepress/theme/plane/components/card-brand-icons.ts b/docs/.vitepress/theme/plane/components/card-brand-icons.ts new file mode 100644 index 00000000..55d323a7 --- /dev/null +++ b/docs/.vitepress/theme/plane/components/card-brand-icons.ts @@ -0,0 +1,25 @@ +/** + * Brand SVG icons for (checked before Lucide). + * Brand marks keep their own colors; single-color glyphs use currentColor so they + * follow the card's icon surface (brand blue in light/dark). + */ +export const cardBrandIcons: Record = { + asana: ``, + clickup: ``, + confluence: ``, + csv: ``, + drawio: ``, + flatfile: ``, + github: ``, + gitlab: ``, + jira: ``, + linear: ``, + notion: ``, + sentry: ``, + slack: ``, + coolify: ``, + docker: ``, + kubernetes: ``, + podman: ``, + portainer: ``, +}; diff --git a/docs/.vitepress/theme/components/copy-page-icons.ts b/docs/.vitepress/theme/plane/components/copy-page-icons.ts similarity index 99% rename from docs/.vitepress/theme/components/copy-page-icons.ts rename to docs/.vitepress/theme/plane/components/copy-page-icons.ts index 9272c6f8..862db0d9 100644 --- a/docs/.vitepress/theme/components/copy-page-icons.ts +++ b/docs/.vitepress/theme/plane/components/copy-page-icons.ts @@ -1,5 +1,3 @@ -/** @format */ - /** * Inline SVG glyphs for the "Copy page" menu (rendered via v-html, sized by CSS). * All paths use fill="currentColor" so they follow the surrounding text color. diff --git a/docs/.vitepress/theme/plane/css/api.css b/docs/.vitepress/theme/plane/css/api.css new file mode 100644 index 00000000..ae49c709 --- /dev/null +++ b/docs/.vitepress/theme/plane/css/api.css @@ -0,0 +1,124 @@ +/* ================================================ + PLANE DOCS THEME — API reference layout + `.api-page` is toggled on `.VPDoc` by the site (developer docs) for + /api-reference/* pages; the two-column markup lives in the .md files. + ================================================ */ + +/* Hide the aside for API reference pages */ +.api-page .aside, +.api-page .aside-container, +.api-page .VPDocAside, +.api-page aside, +.api-page .VPDocAsideOutline { + display: none !important; + width: 0 !important; + min-width: 0 !important; + opacity: 0 !important; + visibility: hidden !important; +} + +.api-page.VPDoc > .container { + display: block !important; + max-width: 100% !important; +} + +.api-page .VPDoc > .container > .content { + max-width: 100% !important; + padding-right: 24px !important; +} + +.api-page .content-container, +.api-page .main, +.api-page .vp-doc { + max-width: 100% !important; +} + +/* Two-column API layout */ +.api-two-column { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + gap: 40px; + align-items: start; +} + +.api-left { + min-width: 0; +} + +.api-right { + position: sticky; + top: 100px; + min-width: 0; +} + +@media (max-width: 1100px) { + .api-two-column { + grid-template-columns: 1fr; + gap: 24px; + } + + .api-right { + position: static; + } +} + +/* API endpoint badge */ +.api-endpoint-badge { + display: inline-flex; + align-items: center; + gap: 12px; + margin-bottom: 20px; +} + +.api-endpoint-badge .method { + font-size: 12px; + font-weight: 700; + padding: 5px 12px; + border-radius: 6px; + font-family: var(--vp-font-family-mono); + text-transform: uppercase; +} + +.api-endpoint-badge .method.get { + background: var(--vp-custom-block-tip-bg); + color: var(--vp-custom-block-tip-text); +} + +.api-endpoint-badge .method.post { + background: var(--vp-custom-block-info-bg); + color: var(--vp-custom-block-info-text); +} + +.api-endpoint-badge .method.patch, +.api-endpoint-badge .method.put { + background: var(--vp-custom-block-warning-bg); + color: var(--vp-custom-block-warning-text); +} + +.api-endpoint-badge .method.delete { + background: var(--vp-custom-block-danger-bg); + color: var(--vp-custom-block-danger-text); +} + +.api-endpoint-badge .path { + font-family: var(--vp-font-family-mono); + font-size: 14px; + color: var(--vp-c-text-2); +} + +/* Section headers */ +.params-section h3, +.returns-section h3 { + font-size: 13px !important; + font-weight: 600 !important; + color: var(--vp-c-text-2) !important; + text-transform: uppercase; + letter-spacing: 0.05em; + margin: 0 0 12px 0 !important; + padding: 0 !important; + border: none !important; +} + +.params-list { + border-top: 1px solid var(--vp-c-divider); +} diff --git a/docs/.vitepress/theme/plane/css/base.css b/docs/.vitepress/theme/plane/css/base.css new file mode 100644 index 00000000..4a2cbf7e --- /dev/null +++ b/docs/.vitepress/theme/plane/css/base.css @@ -0,0 +1,123 @@ +/* ================================================ + PLANE DOCS THEME — base typography, code, misc doc content + ================================================ */ + +/* --- Font rendering --- */ +body, +.docs-layout { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; + font-feature-settings: + "cv01" on, + "cv02" on, + "zero" on; +} + +/* --- Doc prose --- */ +.vp-doc { + line-height: 1.7; + letter-spacing: -0.011em; +} + +.vp-doc h1 { + letter-spacing: -0.022em; + line-height: 1.2; +} + +.vp-doc h2 { + border-top: none !important; + margin-top: 32px; + letter-spacing: -0.017em; + line-height: 1.3; +} + +.vp-doc h3 { + border-top: none !important; + letter-spacing: -0.014em; + line-height: 1.4; +} + +/* --- Code blocks --- */ +div[class*="language-"] { + border-radius: 8px !important; + overflow: hidden; + border: 1px solid var(--vp-c-divider); + background: var(--vp-code-block-bg) !important; +} + +div[class*="language-"] pre { + background: transparent !important; +} + +:is(.dark:not([data-theme]), [data-theme="dark"]) .shiki, +:is(.dark:not([data-theme]), [data-theme="dark"]) .shiki span { + background: transparent !important; +} + +div[class*="language-"] > span.lang { + color: #9ca3af; + font-size: 12px; +} + +/* `[!code word]` highlight (VoidZero fork lacks it) */ +.highlighted-word { + background-color: var(--vp-code-line-highlight-color); + transition: background-color 0.5s; + display: inline-block; +} + +/* --- kbd --- */ +html:not(.dark) .VPContent kbd { + --kbd-color-background: #f7f7f7; + --kbd-color-border: #cbcccd; + --kbd-color-text: #222325; +} + +.VPContent kbd { + --kbd-color-background: #898b90; + --kbd-color-border: #3d3e42; + --kbd-color-text: #222325; + + background-color: var(--kbd-color-background); + color: var(--kbd-color-text); + border-radius: 0.25rem; + border: 1px solid var(--kbd-color-border); + box-shadow: 0 2px 0 1px var(--kbd-color-border); + font-family: var(--vp-font-family-base); + font-size: 0.75em; + line-height: 1; + min-width: 0.75rem; + text-align: center; + padding: 2px 5px; + position: relative; + top: -1px; +} + +/* --- Images: medium-zoom lightbox --- */ +.vp-doc img { + cursor: zoom-in; +} + +.medium-zoom-overlay { + z-index: 9999 !important; + background: rgba(0, 0, 0, 0.8) !important; +} + +.medium-zoom-image, +.medium-zoom-image--opened { + z-index: 10000 !important; +} + +.medium-zoom-image--opened { + cursor: zoom-out; +} + +/* --- Mobile screenshots side-by-side --- */ +.mobile-img-container { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + flex-wrap: wrap; +} diff --git a/docs/.vitepress/theme/plane/css/components.css b/docs/.vitepress/theme/plane/css/components.css new file mode 100644 index 00000000..54128040 --- /dev/null +++ b/docs/.vitepress/theme/plane/css/components.css @@ -0,0 +1,596 @@ +/* ================================================ + PLANE DOCS THEME — markdown components + Card / CardGroup / Tags, home-page pieces, hero-image frames + ================================================ */ + +/* ------------------------------------------------ + CardGroup grid + ------------------------------------------------ */ +.card-group { + display: grid; + gap: 16px; + margin: 24px 0; +} + +.card-group-2, +.card-group-3, +.card-group-4 { + grid-template-columns: 1fr; +} + +@media (min-width: 768px) { + .card-group-2, + .card-group-3, + .card-group-4 { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (min-width: 1024px) { + .card-group-3 { + grid-template-columns: repeat(3, 1fr); + } + + .card-group-4 { + grid-template-columns: repeat(4, 1fr); + } +} + +/* ------------------------------------------------ + Card + ------------------------------------------------ */ +.card-link, +.vp-doc a.card-link, +.vp-doc a.card-link:hover { + color: inherit; + text-decoration: none !important; +} + +.card-link { + display: block; + padding: 24px; + border-radius: 12px; + border: 1px solid var(--vp-c-divider); + background: #ffffff; + transition: all 0.2s ease; +} + +.card-link:hover { + border-color: var(--vp-c-brand-1); + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); +} + +:is(.dark:not([data-theme]), [data-theme="dark"]) .card-link { + background: rgba(20, 20, 20, 0.5); +} + +:is(.dark:not([data-theme]), [data-theme="dark"]) .card-link:hover { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.5); +} + +.card-link--static { + cursor: default; +} + +.card-head { + display: flex; + align-items: flex-start; + gap: 0.875rem; + margin-bottom: 0.75rem; +} + +.card-icon { + flex-shrink: 0; + margin: 0; + line-height: 0; +} + +.card-icon__surface { + display: flex; + align-items: center; + justify-content: center; + width: 2.5rem; + height: 2.5rem; + border-radius: 0.625rem; + background: color-mix(in srgb, var(--vp-c-brand-1) 10%, transparent); + color: var(--vp-c-brand-1); + transition: + background 0.2s ease, + color 0.2s ease; +} + +:is(.dark:not([data-theme]), [data-theme="dark"]) .card-icon__surface { + background: color-mix(in srgb, var(--vp-c-brand-1) 18%, transparent); +} + +.card-icon__lucide { + display: block; +} + +.card-icon__custom svg { + display: block; + width: 1.25rem; + height: 1.25rem; +} + +.card-link:hover .card-icon__surface { + background: color-mix(in srgb, var(--vp-c-brand-1) 16%, transparent); +} + +.card-link--static:hover .card-icon__surface { + background: color-mix(in srgb, var(--vp-c-brand-1) 10%, transparent); +} + +.card-link .card-title { + flex: 1; + min-width: 0; + align-self: center; + margin: 0 !important; + padding: 0.125rem 0 0 !important; + border: none !important; + font-size: 1.0625rem !important; + font-weight: 600 !important; + line-height: 1.35 !important; + letter-spacing: -0.01em; + color: #111827 !important; + transition: color 0.2s ease; +} + +.card-link:hover .card-title { + color: var(--vp-c-brand-1) !important; +} + +.card-link--static:hover .card-title { + color: #111827 !important; +} + +:is(.dark:not([data-theme]), [data-theme="dark"]) .card-link .card-title, +:is(.dark:not([data-theme]), [data-theme="dark"]) .card-link:hover .card-title { + color: #f9fafb !important; +} + +.card-description { + flex: 1; + margin: 0; + font-size: 14px; + line-height: 1.6; + color: var(--vp-c-text-2); +} + +/* Markdown slot content: paragraphs inherit the card's type scale */ +.card-description > p { + margin: 0; + font-size: inherit; + line-height: inherit; +} + +.card-description > p + p { + margin-top: 0.5em; +} + +.card-cta { + display: inline-flex; + align-items: center; + gap: 0.375rem; + margin-top: 1rem; + font-size: 0.875rem; + font-weight: 500; + color: var(--vp-c-brand-1); + transition: + color 0.2s ease, + gap 0.2s ease; +} + +.card-cta__arrow { + width: 1rem; + height: 1rem; + flex-shrink: 0; + transition: transform 0.2s ease; +} + +.card-link:hover .card-cta { + color: var(--plane-brand-hover); +} + +.card-link:hover .card-cta__arrow { + transform: translateX(2px); +} + +.card-link--static:hover .card-cta, +.card-link--static:hover .card-cta__arrow { + color: var(--vp-c-brand-1); + transform: none; +} + +/* Inline link list inside static cards (e.g. quick-start cards) */ +.card-links { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.375rem 0.625rem; + margin: 0; + padding-top: 1rem; +} + +.card-links a, +.vp-doc .card-links a { + display: inline-flex; + align-items: center; + gap: 0.25rem; + font-size: 0.875rem; + font-weight: 500; + color: var(--vp-c-brand-1); + cursor: pointer; + text-decoration: none; + transition: color 0.2s ease; +} + +.card-links a:hover, +.vp-doc .card-links a:hover { + color: var(--plane-brand-hover); + text-decoration: none; +} + +.card-links__sep { + color: var(--vp-c-text-3); + user-select: none; +} + +/* ------------------------------------------------ + Tags + ------------------------------------------------ */ +.plantag, +a.plantag { + display: inline-flex; + align-items: center; + padding: 2px 8px; + border-radius: 4px; + font-size: 12px; + font-weight: 500; + background: var(--vp-c-brand-soft); + color: var(--vp-c-brand-1); + text-decoration: none; + line-height: 1.4; +} + +a.plantag:hover { + color: var(--plane-brand-hover); +} + +/* ------------------------------------------------ + Home page (layout: doc) — action buttons + ------------------------------------------------ */ +.home-doc-actions { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin: 0 0 3rem; +} + +a.home-doc-actions__btn, +.home-doc-actions__btn { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 40px; + padding: 9px 18px; + border-radius: 8px; + border: 1px solid transparent; + font-size: 15px; + font-weight: 500; + line-height: 1.25; + text-decoration: none !important; + cursor: pointer; + transition: + background 0.2s ease, + color 0.2s ease, + border-color 0.2s ease, + box-shadow 0.2s ease, + transform 0.2s ease; +} + +/* Navbar — smaller variant */ +a.home-doc-actions__btn--nav, +.home-doc-actions__btn--nav { + min-height: auto; + padding: 4px 15px; + border-radius: 6px; + font-size: 14px; + margin: 0 !important; +} + +/* Primary */ +a.home-doc-actions__btn--primary, +a.home-doc-actions__btn--primary:is(:link, :visited, :focus, :active) { + background: var(--vp-button-brand-bg) !important; + border-color: var(--vp-button-brand-border) !important; + color: var(--vp-button-brand-text) !important; +} + +a.home-doc-actions__btn--primary:hover { + background: var(--vp-button-brand-hover-bg) !important; + border-color: var(--vp-button-brand-hover-border) !important; + color: var(--vp-button-brand-hover-text) !important; + box-shadow: 0 2px 8px color-mix(in srgb, var(--vp-c-brand-1) 25%, transparent); +} + +a.home-doc-actions__btn--primary.home-doc-actions__btn--nav:hover { + transform: translateY(-1px); +} + +/* Secondary */ +a.home-doc-actions__btn--secondary, +a.home-doc-actions__btn--secondary:is(:link, :visited, :focus, :active) { + background: var(--vp-button-alt-bg) !important; + border-color: var(--vp-button-alt-border) !important; + color: var(--vp-button-alt-text) !important; +} + +a.home-doc-actions__btn--secondary:hover { + background: var(--vp-button-alt-hover-bg) !important; + border-color: var(--vp-button-alt-hover-border) !important; + color: var(--vp-button-alt-hover-text) !important; +} + +:is(.dark:not([data-theme]), [data-theme="dark"]) a.home-doc-actions__btn--secondary, +:is(.dark:not([data-theme]), [data-theme="dark"]) + a.home-doc-actions__btn--secondary:is(:link, :visited, :focus, :active) { + background: #252829 !important; + border-color: #3f4244 !important; + color: #ffffff !important; +} + +:is(.dark:not([data-theme]), [data-theme="dark"]) a.home-doc-actions__btn--secondary:hover { + background: #2f3236 !important; + border-color: #4a4e52 !important; + color: #ffffff !important; +} + +/* ------------------------------------------------ + Home page — feature / quick-start card grids + Works for both markups: + (class on the grid) +
(wrapper around the grid) + ------------------------------------------------ */ +.home-feature-cards { + margin: 2rem 0 3rem; +} + +.home-quick-start { + margin: 1.5rem 0 3rem; +} + +.home-feature-cards.card-group, +.home-feature-cards .card-group, +.home-quick-start.card-group, +.home-quick-start .card-group { + display: grid; + gap: 1rem; + grid-template-columns: 1fr; +} + +@media (min-width: 640px) { + .home-feature-cards.card-group, + .home-feature-cards .card-group, + .home-quick-start.card-group, + .home-quick-start .card-group { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (min-width: 960px) { + .home-feature-cards.card-group, + .home-feature-cards .card-group, + .home-quick-start.card-group, + .home-quick-start .card-group { + grid-template-columns: repeat(3, 1fr); + } +} + +.home-feature-cards .card-link, +.home-quick-start .card-link { + display: flex; + flex-direction: column; + height: 100%; + min-height: 10rem; + border: 1px solid transparent; + background: #f7f8f9; + padding: 1.5rem; + border-radius: 0.875rem; + box-shadow: none; + transition: + background 0.2s ease, + border-color 0.2s ease, + transform 0.2s ease; +} + +.home-feature-cards .card-link:hover, +.home-quick-start .card-link:hover { + background: #eef0f2; + border-color: color-mix(in srgb, var(--vp-c-brand-1) 12%, transparent); + box-shadow: none; + transform: translateY(-1px); +} + +.home-quick-start .card-link--static:hover { + background: #f7f8f9; + border-color: transparent; + transform: none; +} + +:is(.dark:not([data-theme]), [data-theme="dark"]) .home-feature-cards .card-link, +:is(.dark:not([data-theme]), [data-theme="dark"]) .home-quick-start .card-link { + background: #181a1b; + border-color: transparent; +} + +:is(.dark:not([data-theme]), [data-theme="dark"]) .home-feature-cards .card-link:hover, +:is(.dark:not([data-theme]), [data-theme="dark"]) .home-quick-start .card-link:hover { + background: #1f2224; + border-color: color-mix(in srgb, var(--vp-c-brand-1) 22%, transparent); + box-shadow: none; +} + +:is(.dark:not([data-theme]), [data-theme="dark"]) .home-quick-start .card-link--static:hover { + background: #181a1b; + border-color: transparent; +} + +.home-feature-cards .card-head, +.home-quick-start .card-head { + margin-bottom: 0.625rem; +} + +.home-feature-cards .card-link .card-title, +.home-quick-start .card-link .card-title, +.home-feature-cards .card-link:hover .card-title, +.home-quick-start .card-link:hover .card-title { + color: #0a0a0a !important; + font-size: 1rem !important; +} + +:is(.dark:not([data-theme]), [data-theme="dark"]) .home-feature-cards .card-link .card-title, +:is(.dark:not([data-theme]), [data-theme="dark"]) .home-quick-start .card-link .card-title, +:is(.dark:not([data-theme]), [data-theme="dark"]) .home-feature-cards .card-link:hover .card-title, +:is(.dark:not([data-theme]), [data-theme="dark"]) .home-quick-start .card-link:hover .card-title { + color: #f4f4f4 !important; +} + +.home-feature-cards .card-description, +.home-quick-start .card-description { + font-size: 0.875rem; + line-height: 1.55; + color: #5c6570; +} + +:is(.dark:not([data-theme]), [data-theme="dark"]) .home-feature-cards .card-description, +:is(.dark:not([data-theme]), [data-theme="dark"]) .home-quick-start .card-description { + color: #9ca3af; +} + +.home-feature-cards .card-cta, +.home-quick-start .card-links { + margin-top: auto; + padding-top: 1rem; +} + +.home-feature-cards .card-icon__surface, +.home-quick-start .card-icon__surface { + width: 2.75rem; + height: 2.75rem; + border-radius: 0.6875rem; +} + +.home-feature-cards .card-icon__custom svg, +.home-quick-start .card-icon__custom svg { + width: 1.375rem; + height: 1.375rem; +} + +/* Hide footer prev/next on home when card grids are present */ +.Layout:has(.home-feature-cards) .VPDocFooter .prev, +.Layout:has(.home-feature-cards) .VPDocFooter .next, +.Layout:has(.home-feature-cards) .VPDocFooter .pager-link, +.Layout:has(.home-quick-start) .VPDocFooter .prev, +.Layout:has(.home-quick-start) .VPDocFooter .next, +.Layout:has(.home-quick-start) .VPDocFooter .pager-link { + display: none; +} + +/* ------------------------------------------------ + Hero image frames in markdown: ![](url#hero | #hero-tl | #hero-tr | #hero-bl | #hero-br) + The suffix picks which corner of the screenshot is anchored to the frame. + ------------------------------------------------ */ +.vp-doc p:has(> img[src$="#hero"]), +.vp-doc p:has(> img[src$="#hero-tl"]), +.vp-doc p:has(> img[src$="#hero-tr"]), +.vp-doc p:has(> img[src$="#hero-bl"]), +.vp-doc p:has(> img[src$="#hero-br"]), +article p:has(> img[src$="#hero"]), +article p:has(> img[src$="#hero-tl"]), +article p:has(> img[src$="#hero-tr"]), +article p:has(> img[src$="#hero-bl"]), +article p:has(> img[src$="#hero-br"]) { + max-width: 841px; + background: #f1f3f3; + border-radius: 12px; + box-sizing: border-box; + overflow: hidden; +} + +.vp-doc img[src$="#hero"], +.vp-doc img[src$="#hero-tl"], +.vp-doc img[src$="#hero-tr"], +.vp-doc img[src$="#hero-bl"], +.vp-doc img[src$="#hero-br"], +article img[src$="#hero"], +article img[src$="#hero-tl"], +article img[src$="#hero-tr"], +article img[src$="#hero-bl"], +article img[src$="#hero-br"] { + width: 100%; + height: auto; + display: block; + margin: 0; + border-style: solid; + border-color: #eaebeb; + object-fit: cover; + box-shadow: + 0px 2px 4px -1px rgba(41, 47, 61, 0.04), + 0px 4px 6px -1px rgba(41, 47, 61, 0.05); +} + +.vp-doc p:has(> img[src$="#hero"]), +article p:has(> img[src$="#hero"]) { + padding: 36px 56px 0; +} + +.vp-doc img[src$="#hero"], +article img[src$="#hero"] { + border-radius: 8px 8px 0 0; + border-width: 1px 1px 0 1px; +} + +.vp-doc p:has(> img[src$="#hero-tl"]), +article p:has(> img[src$="#hero-tl"]) { + padding: 36px 0 0 56px; +} + +.vp-doc img[src$="#hero-tl"], +article img[src$="#hero-tl"] { + border-radius: 8px 0 0 0; + border-width: 1px 0 0 1px; +} + +.vp-doc p:has(> img[src$="#hero-tr"]), +article p:has(> img[src$="#hero-tr"]) { + padding: 36px 56px 0 0; +} + +.vp-doc img[src$="#hero-tr"], +article img[src$="#hero-tr"] { + border-radius: 0 8px 0 0; + border-width: 1px 1px 0 0; +} + +.vp-doc p:has(> img[src$="#hero-bl"]), +article p:has(> img[src$="#hero-bl"]) { + padding: 0 0 36px 56px; +} + +.vp-doc img[src$="#hero-bl"], +article img[src$="#hero-bl"] { + border-radius: 0 0 0 8px; + border-width: 0 0 1px 1px; +} + +.vp-doc p:has(> img[src$="#hero-br"]), +article p:has(> img[src$="#hero-br"]) { + padding: 0 56px 36px 0; +} + +.vp-doc img[src$="#hero-br"], +article img[src$="#hero-br"] { + border-radius: 0 0 8px 0; + border-width: 0 1px 1px 0; +} diff --git a/docs/.vitepress/theme/plane/css/fonts.css b/docs/.vitepress/theme/plane/css/fonts.css new file mode 100644 index 00000000..a4bf5d5d --- /dev/null +++ b/docs/.vitepress/theme/plane/css/fonts.css @@ -0,0 +1,41 @@ +/* Self-hosted fonts (files live in docs/public/fonts/ in both repos). */ + +@font-face { + font-family: "Inter"; + src: url("/fonts/Inter/InterVariable.woff2") format("woff2"); + font-weight: 100 900; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "IBM Plex Mono"; + src: url("/fonts/IBMPlexMono/IBMPlexMono-Regular.ttf") format("truetype"); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "IBM Plex Mono"; + src: url("/fonts/IBMPlexMono/IBMPlexMono-Medium.ttf") format("truetype"); + font-weight: 500; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "IBM Plex Mono"; + src: url("/fonts/IBMPlexMono/IBMPlexMono-SemiBold.ttf") format("truetype"); + font-weight: 600; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "IBM Plex Mono"; + src: url("/fonts/IBMPlexMono/IBMPlexMono-Bold.ttf") format("truetype"); + font-weight: 700; + font-style: normal; + font-display: swap; +} diff --git a/docs/.vitepress/theme/plane/css/index.css b/docs/.vitepress/theme/plane/css/index.css new file mode 100644 index 00000000..3cbae5ce --- /dev/null +++ b/docs/.vitepress/theme/plane/css/index.css @@ -0,0 +1,21 @@ +/* ================================================ + PLANE DOCS THEME — shared stylesheet entry + Byte-identical in makeplane/docs and makeplane/developer-docs + (docs/.vitepress/theme/plane/). Edit in one repo, copy to the other, + run `pnpm check:theme-sync`. + ================================================ */ + +/* VoidZero design system (tokens → base → docs → marketing) — includes Tailwind v4 */ +@import "@voidzero-dev/vitepress-theme/src/styles/index.css"; + +/* Plane layer, in cascade order */ +@import "./fonts.css"; +@import "./tokens.css"; +@import "./base.css"; +@import "./layout.css"; +@import "./components.css"; +@import "./api.css"; + +/* Tailwind content sources: the shared theme's Vue components and every page/component under docs/ */ +@source "../**/*.vue"; +@source "../../../../**/*.{vue,md}"; diff --git a/docs/.vitepress/theme/plane/css/layout.css b/docs/.vitepress/theme/plane/css/layout.css new file mode 100644 index 00000000..f01a9d09 --- /dev/null +++ b/docs/.vitepress/theme/plane/css/layout.css @@ -0,0 +1,442 @@ +/* ================================================ + PLANE DOCS THEME — layout shell, header skin, sidebar / aside geometry + ================================================ */ + +/* ------------------------------------------------ + Layout borders & corner ticks + ------------------------------------------------ */ +@media (min-width: 768px) { + .docs-layout .content-wrapper, + .docs-layout .wrapper { + border-left-color: var(--docs-divider); + border-right-color: var(--docs-divider); + } +} + +.docs-layout .tick-left::before { + border-left-color: var(--docs-divider); +} + +.docs-layout .tick-right::after { + border-right-color: var(--docs-divider); +} + +.docs-layout .VPSidebar { + border-right: 1px solid var(--docs-divider); +} + +/* Hide local nav when the sidebar is present */ +@media (min-width: 1024px) { + .docs-layout .VPLocalNav { + display: none !important; + } +} + +/* ------------------------------------------------ + Sidebars: flush under the fixed header + ------------------------------------------------ */ +@media (min-width: 1024px) { + /* Both rails keep VitePress' 20px top inset so their first rows share a baseline. */ + .docs-layout .VPSidebar { + top: calc(var(--vp-nav-height) + var(--vp-banner-height, 0px) - 4px); + } + + .docs-layout .VPDoc .aside-container { + top: calc(var(--vp-nav-height) + var(--vp-banner-height, 0px) - 4px); + } +} + +/* --- Doc layout shell (1280px+): left nav + right outline share one baseline --- */ +@media (min-width: 1280px) { + .docs-layout .VPSidebar .nav { + padding-top: 0; + } + + .docs-layout .VPDoc .content { + padding-top: 32px; + } + + .docs-layout .VPDoc .aside { + max-width: 256px; + } + + .docs-layout .VPDoc .aside-container { + width: 256px; + padding-left: 24px; + border-left-color: var(--docs-divider); + } + + /* Outline: allow long headings to wrap, add air between siblings */ + .docs-layout .VPDocOutlineItem .outline-link { + white-space: normal; + text-overflow: unset; + overflow: visible; + line-height: 1.45; + padding: 2px 0 4px; + } + + .docs-layout .VPDocAsideOutline .VPDocOutlineItem li + li { + margin-top: 6px; + } + + .docs-layout .VPDocAsideOutline .VPDocOutlineItem li > .VPDocOutlineItem.nested { + margin-top: 4px; + } +} + +/* --- No right outline (aside: false, or the page has no headings): widen main column --- */ +.docs-layout .VPDoc:not(.has-aside) .content-container { + max-width: 960px; + padding-left: 24px; + padding-right: 24px; +} + +@media (min-width: 1280px) { + .docs-layout .VPDoc:not(.has-aside) .content-container { + max-width: 1104px; + padding-left: 48px; + padding-right: 48px; + } + + .docs-layout + .VPDoc.has-aside:has(.VPDocAsideOutline:not(.has-outline)):not(:has(.VPDocAsideCarbonAds)) + .aside { + display: none !important; + flex: 0 0 0 !important; + width: 0 !important; + min-width: 0 !important; + max-width: 0 !important; + margin: 0 !important; + padding: 0 !important; + overflow: hidden !important; + } + + .docs-layout + .VPDoc.has-aside:has(.VPDocAsideOutline:not(.has-outline)):not(:has(.VPDocAsideCarbonAds)) + .content { + flex: 1 1 auto; + max-width: none !important; + } + + .docs-layout + .VPDoc.has-aside:has(.VPDocAsideOutline:not(.has-outline)):not(:has(.VPDocAsideCarbonAds)) + .content-container { + max-width: 1104px; + padding-left: 48px; + padding-right: 48px; + } +} + +/* ------------------------------------------------ + Copy page menu (components/CopyPageMenu.vue) — placement + The control is server-rendered in the `doc-before` slot (first child of + `.VPDoc .content-container`, above
) and, once mounted, teleported into a + `.copy-page-slot` host inserted right after the page H1 inside `.vp-doc`. Both + positions are styled here; visual styles are scoped in the component. + ------------------------------------------------ */ +.docs-layout .VPDoc .content-container { + position: relative; /* anchor for the pre-teleport position */ +} + +/* < 768px: below the title, left-aligned, in flow */ +@media (max-width: 767px) { + /* Pre-teleport position would sit above the title — keep it hidden to avoid a jump. */ + .docs-layout .VPDoc .content-container > .copy-page { + display: none; + } + + .docs-layout .vp-doc > div > .copy-page-slot { + margin: 14px 0 16px; + } +} + +/* ≥ 768px: on the title row, flush with the right edge of the text column */ +@media (min-width: 768px) { + .docs-layout .VPDoc .content-container > .copy-page, + .docs-layout .vp-doc > div > .copy-page-slot > .copy-page { + position: absolute; /* relative to .content-container / .vp-doc — same top edge */ + top: 2px; /* (h1 line box ~38px − 34px button) / 2 */ + right: 0; + margin: 0; + z-index: 10; /* below --vp-z-index-local-nav (20) and the image lightbox */ + } + + /* Reserve the control's footprint on the H1 only when it actually rendered + (so `copyPage: false` pages keep the full width). */ + .docs-layout .vp-doc > div > h1:has(+ .copy-page-slot > .copy-page), + .docs-layout .VPDoc .content-container > .copy-page ~ .main .vp-doc > div > h1 { + padding-right: 156px; /* ≈ 132px control + 24px gap — re-measure if the label changes */ + } +} + +/* ------------------------------------------------ + Header (components/PlaneHeader.vue) — shell, search, nav, actions + ------------------------------------------------ */ +header.plane-header.wrapper, +.plane-header-shell { + font-family: var(--vp-font-family-base); + background-color: var(--plane-header-bg) !important; + border-bottom-color: var(--plane-header-border) !important; +} + +@media (min-width: 768px) { + .docs-layout header.plane-header.wrapper, + .docs-layout .plane-header-shell .wrapper { + border-left-color: var(--docs-divider) !important; + border-right-color: var(--docs-divider) !important; + } +} + +.docs-layout .border-stroke { + border-color: var(--docs-divider) !important; +} + +/* Match content-wrapper width (centered when fixed) */ +@media (min-width: 768px) { + .docs-layout .plane-header-shell { + width: calc(100vw - 2rem); + max-width: calc(100vw - 2rem); + margin-left: auto; + margin-right: auto; + box-sizing: border-box; + } +} + +@media (min-width: 90rem) { + .docs-layout .plane-header-shell { + width: 90rem; + max-width: 90rem; + } +} + +@media (min-width: 1024px) { + .docs-layout .plane-header-shell--docs { + left: 50%; + right: auto; + transform: translateX(-50%); + width: calc(100vw - 2rem); + max-width: calc(100vw - 2rem); + } + + .docs-layout .plane-header-shell--docs.plane-header-shell { + overflow-x: clip; + } +} + +@media (min-width: 90rem) { + .docs-layout .plane-header-shell--docs { + width: 90rem; + max-width: 90rem; + } +} + +@media (min-width: 768px) { + .plane-header .VPNavBarSearchButton, + .plane-header .search-bar { + background-color: var(--plane-header-search-bg) !important; + border: 1px solid var(--plane-header-search-border) !important; + border-radius: 12px; + color: var(--plane-header-search-text) !important; + } +} + +@media (min-width: 1024px) { + .plane-header-shell { + overflow-x: clip; + } + + .docs-layout .plane-header.wrapper { + width: 100%; + max-width: 100%; + margin-left: auto; + margin-right: auto; + box-sizing: border-box; + overflow-x: clip; + } + + .plane-header .plane-header__start, + .plane-header .plane-header__actions { + min-width: 0; + overflow: hidden; + } + + .plane-header .plane-header__search { + width: 240px; + max-width: 240px; + } + + .plane-header .VPNavBarSearch { + width: 100%; + min-width: 0; + max-width: 240px; + } + + .plane-header .VPNavBarSearchButton, + .plane-header .DocSearch.DocSearch-Button { + width: 100% !important; + max-width: 240px !important; + min-width: 0 !important; + } + + .plane-header .DocSearch.DocSearch-Button, + .plane-header .VPNavBarSearchButton, + .plane-header .search-bar { + height: 36px; + border-radius: 12px; + background: var(--plane-header-search-bg) !important; + border: 1px solid var(--plane-header-search-border) !important; + color: var(--plane-header-search-text) !important; + justify-content: flex-start !important; + text-align: left !important; + gap: 8px; + } + + .plane-header .DocSearch-Button-Container { + justify-content: flex-start !important; + flex: 1; + min-width: 0; + gap: 0.5rem; + } + + .plane-header .DocSearch-Search-Icon { + color: var(--plane-header-search-text) !important; + } + + .plane-header .DocSearch-Button-Placeholder, + .plane-header .VPNavBarSearchButton .text, + .plane-header .search-bar__text { + color: var(--plane-header-search-text) !important; + text-align: left !important; + flex: 0 1 auto; + font-size: 13px; + } + + .plane-header .DocSearch-Button-Keys, + .plane-header .VPNavBarSearchButton .keys, + .plane-header .search-bar__keys { + color: var(--plane-header-search-text) !important; + border: 1px solid var(--plane-header-search-keys-border) !important; + margin-left: auto !important; + flex-shrink: 0; + font-size: 12px; + font-weight: 500; + } + + .plane-header__nav .VPLink.link, + .plane-header__nav .VPLink.text-base, + .plane-header .VPNavBarMenuLink:not(.home-doc-actions__btn), + .plane-header .VPNavBarMenuGroup .button { + color: var(--plane-header-text) !important; + font-size: 14px !important; + font-weight: 400; + padding: 0.375rem 0.5rem; + min-width: 0; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + transition: color 0.2s ease; + } + + .plane-header__nav .VPLink.link:hover, + .plane-header .VPNavBarMenuLink:not(.home-doc-actions__btn):hover, + .plane-header .VPNavBarMenuGroup .button:hover { + color: var(--vp-c-brand-1) !important; + opacity: 1; + } + + .plane-header a.home-doc-actions__btn--secondary.VPNavBarMenuLink, + .plane-header a.home-doc-actions__btn--secondary.VPNavBarMenuLink:hover { + color: inherit !important; + opacity: 1 !important; + } + + .plane-header .VPNavBarMenuLink.active, + .plane-header__nav .VPLink.link.active { + color: var(--vp-c-brand-1) !important; + } + + .plane-header .VPNavBarAppearance, + .plane-header .VPNavBarSocialLinks { + display: flex !important; + align-items: center; + flex-shrink: 0; + } + + .plane-header .VPNavBarSocialLinks { + gap: 0.25rem; + } + + .plane-header .VPNavBarSocialLinks .VPSocialLink { + color: var(--plane-header-text); + transition: color 0.2s ease; + } + + .plane-header .VPNavBarSocialLinks .VPSocialLink:hover { + color: var(--vp-c-brand-1); + } + + .plane-header .VPSwitchAppearance { + --vp-c-bg: var(--plane-header-search-bg); + } +} + +/* Theme switcher border follows the layout hairlines */ +.docs-layout .VPSwitchAppearance { + --vp-c-border: var(--docs-divider); + --vp-input-border-color: var(--vp-c-border); +} + +@media (min-width: 1024px) and (max-width: 1279px) { + .plane-header__title { + display: none; + } +} + +@media (min-width: 1280px) { + .plane-header { + gap: 0.5rem 1.25rem; + --plane-header-padding-x: 1.5rem; + } + + .plane-header__nav .VPLink.link, + .plane-header__nav .VPLink.text-base, + .plane-header .VPNavBarMenuLink:not(.home-doc-actions__btn), + .plane-header .VPNavBarMenuGroup .button { + font-size: 14px !important; + padding: 0.375rem 0.75rem; + } +} + +/* Navbar buttons — hide external-link ↗ icon */ +.plane-header a.home-doc-actions__btn.vp-external-link-icon::after, +.plane-header .VPLink.home-doc-actions__btn.vp-external-link-icon::after, +.plane-header a.home-doc-actions__btn.no-icon::after, +.plane-header .VPLink.home-doc-actions__btn.no-icon::after { + display: none !important; + content: none !important; +} + +.plane-header a.home-doc-actions__btn .vp-external-link-icon, +.plane-header a.home-doc-actions__btn svg { + display: none !important; +} + +/* Navbar primary & secondary buttons */ +.plane-header a.home-doc-actions__btn--primary.VPNavBarMenuLink, +.plane-header a.home-doc-actions__btn--secondary.VPNavBarMenuLink, +.plane-header .VPLink.home-doc-actions__btn--primary, +.plane-header .VPLink.home-doc-actions__btn--secondary { + padding: 4px 15px !important; + font-size: 14px !important; + border-radius: 6px !important; + min-height: auto !important; + line-height: 1.25 !important; + font-weight: 500 !important; + white-space: nowrap; +} + +/* Don't apply nav text-link hover to the button variants */ +.plane-header .VPNavBarMenuLink.home-doc-actions__btn:hover { + opacity: 1 !important; +} diff --git a/docs/.vitepress/theme/plane/css/tokens.css b/docs/.vitepress/theme/plane/css/tokens.css new file mode 100644 index 00000000..e5bb735a --- /dev/null +++ b/docs/.vitepress/theme/plane/css/tokens.css @@ -0,0 +1,202 @@ +/* ================================================ + PLANE DOCS THEME — design tokens + Loaded after @voidzero-dev/vitepress-theme/src/styles/index.css. + + Selector contract + - Light values live on `:root`. + - Dark values live on `.dark:not([data-theme]), [data-theme="dark"]` — the + exact pair VoidZero uses, so our declarations win by source order with the + same specificity and no `!important`. Never use bare `html.dark` here. + ================================================ */ + +:root { + /* --- Fonts (VoidZero maps --font-* → --vp-font-family-*; headings read --font-heading) --- */ + --vp-font-family-base: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + --vp-font-family-mono: + "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", + monospace; + --font-sans: var(--vp-font-family-base); + --font-mono: var(--vp-font-family-mono); + --font-heading: var(--vp-font-family-base); + + /* --- Layout --- */ + --vp-nav-height: 84px; /* PlaneHeader height (VoidZero default 82px) */ + --docs-divider: #ececec; /* header / sidebar / wrapper hairlines */ + --color-stroke: var(--docs-divider); /* VoidZero .content-wrapper / ticks / border-stroke */ + + /* --- Brand --- */ + --color-brand: #006399; + --vp-c-brand-1: #006399; + --vp-c-brand-2: #0078b8; /* hover (VoidZero uses brand-2 for hover states) */ + --vp-c-brand-3: #006399; + --vp-c-brand-soft: rgba(0, 99, 153, 0.14); + --plane-brand-hover: #0078b8; + --plane-link-hover: #0078b8; + + /* --- Text / backgrounds / borders --- */ + --color-primary: #0a0a0a; /* Tailwind text-primary utility (VoidZero #16171d) */ + --vp-c-text-1: #0a0a0a; + --vp-c-text-2: #6b7280; + --vp-c-text-3: #9ca3af; + --vp-c-bg: #ffffff; + --vp-c-bg-alt: #f6f6f7; + --vp-c-bg-soft: #f6f6f7; + --vp-c-bg-elv: #ffffff; + --vp-c-divider: #e5e7eb; + --vp-c-border: #e5e7eb; + --vp-c-gutter: #e5e7eb; + + /* --- Code --- */ + /* Inline code in neutral body-text color (VitePress default is brand blue, + hard to read on the pill background). Linked code keeps the brand color. */ + --vp-code-color: var(--vp-c-text-1); + --vp-code-block-bg: #fafafa; + + /* --- Buttons (VPButton / hero actions) --- */ + --vp-button-brand-border: #006399; + --vp-button-brand-bg: #006399; + --vp-button-brand-text: #ffffff; + --vp-button-brand-hover-border: #0078b8; + --vp-button-brand-hover-bg: #0078b8; + --vp-button-brand-hover-text: #ffffff; + --vp-button-alt-border: #e5e7eb; + --vp-button-alt-text: #0a0a0a; + --vp-button-alt-bg: transparent; + --vp-button-alt-hover-border: #d1d5db; + --vp-button-alt-hover-text: #0a0a0a; + --vp-button-alt-hover-bg: #f7f8f9; + + /* --- Callouts (tip / info / warning / danger / caution / details) --- */ + --vp-c-tip-1: #166534; + --vp-c-tip-2: #14532d; + --vp-c-tip-3: #166534; + --vp-c-tip-soft: #dcfce7; + --vp-custom-block-tip-text: #166534; + --vp-custom-block-tip-bg: #dcfce7; + --vp-custom-block-tip-code-bg: #dcfce7; + + --vp-custom-block-info-text: #1e40af; + --vp-custom-block-info-bg: #dbeafe; + --vp-custom-block-info-code-bg: #dbeafe; + + --vp-c-warning-1: #92400e; + --vp-c-warning-2: #78350f; + --vp-c-warning-3: #92400e; + --vp-c-warning-soft: #fef3c7; + --vp-custom-block-warning-text: #92400e; + --vp-custom-block-warning-bg: #fef3c7; + --vp-custom-block-warning-code-bg: #fef3c7; + + --vp-c-danger-1: #991b1b; + --vp-c-danger-2: #7f1d1d; + --vp-c-danger-3: #991b1b; + --vp-c-danger-soft: #fee2e2; + --vp-custom-block-danger-text: #991b1b; + --vp-custom-block-danger-bg: #fee2e2; + --vp-custom-block-danger-code-bg: #fee2e2; + + --vp-c-caution-1: var(--vp-c-danger-1); + --vp-c-caution-2: var(--vp-c-danger-2); + --vp-c-caution-3: var(--vp-c-danger-3); + --vp-c-caution-soft: var(--vp-c-danger-soft); + --vp-custom-block-caution-text: var(--vp-custom-block-danger-text); + --vp-custom-block-caution-bg: var(--vp-custom-block-danger-bg); + --vp-custom-block-caution-code-bg: var(--vp-custom-block-danger-code-bg); + + /* `::: details` stays neutral (VoidZero aliases it to info → blue). */ + --vp-custom-block-details-text: var(--vp-c-text-1); + --vp-custom-block-details-bg: var(--vp-c-default-soft); + --vp-custom-block-details-code-bg: var(--vp-c-default-soft); + + /* --- Header (components/PlaneHeader.vue) --- */ + --plane-header-padding-y: 1.125rem; + --plane-header-padding-x: 1.375rem; + --plane-header-logo-height: 1.6875rem; + --plane-header-bg: #ffffff; + --plane-header-border: var(--docs-divider); + --plane-header-text: var(--color-primary); + --plane-header-muted: var(--vp-c-text-2); + --plane-header-divider: var(--docs-divider); + --plane-header-search-bg: #ffffff; + --plane-header-search-border: #e7e7e7; + --plane-header-search-text: #867e8e; + --plane-header-search-keys-border: #e5e4e7; +} + +.dark:not([data-theme]), +[data-theme="dark"] { + --docs-divider: #2a2a2a; + --color-nickel: var(--docs-divider); /* VoidZero dark:border-nickel / .content-wrapper */ + + --color-brand: #2893cc; + --vp-c-brand-1: #2893cc; + --vp-c-brand-2: #3aa5d4; + --vp-c-brand-3: #2893cc; + --vp-c-brand-soft: rgba(40, 147, 204, 0.14); + --plane-brand-hover: #3aa5d4; + --plane-link-hover: #3aa5d4; + + --color-primary: #141415; + --vp-c-text-1: rgba(255, 255, 255, 0.9); + --vp-c-text-2: #9ca3af; + --vp-c-text-3: #6b7280; + --vp-c-bg: #141415; + --vp-c-bg-alt: #141618; + --vp-c-bg-soft: #1f2122; + --vp-c-bg-mute: #252829; + --vp-c-bg-elv: #141618; + --vp-c-divider: #2a2a2a; + --vp-c-border: #2a2a2a; + --vp-c-gutter: #2a2a2a; + + --vp-code-block-bg: #0f0f0f; + + --vp-button-brand-border: #2893cc; + --vp-button-brand-bg: #2893cc; + --vp-button-brand-text: #ffffff; + --vp-button-brand-hover-border: #3aa5d4; + --vp-button-brand-hover-bg: #3aa5d4; + --vp-button-brand-hover-text: #ffffff; + --vp-button-alt-border: #3f4244; + --vp-button-alt-text: #ffffff; + --vp-button-alt-bg: transparent; + --vp-button-alt-hover-border: #4a4e52; + --vp-button-alt-hover-text: #ffffff; + --vp-button-alt-hover-bg: #252829; + --vp-button-alt-active-bg: #2f3236; + + --vp-c-tip-1: #4ade80; + --vp-c-tip-2: #86efac; + --vp-c-tip-3: #4ade80; + --vp-c-tip-soft: rgba(34, 197, 94, 0.15); + --vp-custom-block-tip-text: #4ade80; + --vp-custom-block-tip-bg: rgba(34, 197, 94, 0.15); + --vp-custom-block-tip-code-bg: rgba(34, 197, 94, 0.15); + + --vp-custom-block-info-text: #60a5fa; + --vp-custom-block-info-bg: rgba(59, 130, 246, 0.15); + --vp-custom-block-info-code-bg: rgba(59, 130, 246, 0.15); + + --vp-c-warning-1: #fbbf24; + --vp-c-warning-2: #fcd34d; + --vp-c-warning-3: #fbbf24; + --vp-c-warning-soft: rgba(251, 191, 36, 0.15); + --vp-custom-block-warning-text: #fbbf24; + --vp-custom-block-warning-bg: rgba(251, 191, 36, 0.15); + --vp-custom-block-warning-code-bg: rgba(251, 191, 36, 0.15); + + --vp-c-danger-1: #f87171; + --vp-c-danger-2: #fca5a5; + --vp-c-danger-3: #f87171; + --vp-c-danger-soft: rgba(239, 68, 68, 0.15); + --vp-custom-block-danger-text: #f87171; + --vp-custom-block-danger-bg: rgba(239, 68, 68, 0.15); + --vp-custom-block-danger-code-bg: rgba(239, 68, 68, 0.15); + + --plane-header-bg: var(--color-primary); + --plane-header-text: #ffffff; + --plane-header-search-bg: #111111; + --plane-header-search-border: #323232; + --plane-header-search-text: #867e8e; + --plane-header-search-keys-border: #323232; +} diff --git a/docs/.vitepress/theme/plane/index.ts b/docs/.vitepress/theme/plane/index.ts new file mode 100644 index 00000000..ad4c2c9a --- /dev/null +++ b/docs/.vitepress/theme/plane/index.ts @@ -0,0 +1,203 @@ +/** + * Plane docs theme — shared between makeplane/docs and makeplane/developer-docs. + * + * `docs/.vitepress/theme/plane/` is byte-identical in both repos; each site's + * `theme/index.ts` is a thin `createPlaneTheme({...})` call. Edit here in one repo, + * copy to the other, and run `pnpm check:theme-sync`. + */ +import type { Theme } from "vitepress"; +import { useData, useRoute } from "vitepress"; +import { h, nextTick, onMounted, onUnmounted, watch } from "vue"; +import { enhanceAppWithTabs } from "vitepress-plugin-tabs/client"; +import mediumZoom from "medium-zoom"; +import { themeContextKey } from "@voidzero-dev/vitepress-theme"; +import VPBadge from "@vp-default/VPBadge.vue"; + +import "./css/index.css"; + +import PlaneLayout from "./layout/Layout.vue"; +import Card from "./components/Card.vue"; +import CardGroup from "./components/CardGroup.vue"; +import Tags from "./components/Tags.vue"; +import CookieConsent from "./components/CookieConsent.vue"; +import { planeOptionsKey, type PlaneThemeOptions } from "./options"; + +export type { PlaneThemeOptions } from "./options"; +export { planeOptionsKey } from "./options"; +export { Card, CardGroup, Tags, CookieConsent, PlaneLayout }; + +/* --------------------------------------------------------------------------- + * Client-side helpers + * ------------------------------------------------------------------------- */ + +/** Mirror `html.dark` onto the header shell (`data-theme`), which is SSR-rendered light. */ +function syncHeaderTheme() { + if (typeof document === "undefined") return; + const isDark = document.documentElement.classList.contains("dark"); + document.querySelectorAll("header.plane-header, header.wrapper").forEach((header) => { + if (isDark) header.setAttribute("data-theme", "dark"); + else header.removeAttribute("data-theme"); + }); +} + +/** Deep links to tabs (`vitepress-plugin-tabs`): `#label` activates the matching tab. */ +function handleTabHash() { + if (typeof document === "undefined") return; + const hash = window.location.hash.slice(1); + if (!hash) return; + document.querySelectorAll('[role="tab"]').forEach((button) => { + const labelText = button.textContent?.trim().toLowerCase().replace(/\s+/g, "-"); + if (labelText === hash) { + button.click(); + button.focus(); + } + }); +} + +function handleHashChange() { + nextTick(handleTabHash); +} + +function updateHashOnTabClick(event: Event) { + const button = event.currentTarget as HTMLElement; + const labelText = button.textContent?.trim().toLowerCase().replace(/\s+/g, "-"); + if (labelText) history.replaceState(null, "", `#${labelText}`); +} + +function setupTabHashUpdates() { + if (typeof document === "undefined") return; + document.querySelectorAll('[role="tab"]').forEach((button) => { + button.removeEventListener("click", updateHashOnTabClick); + button.addEventListener("click", updateHashOnTabClick); + }); +} + +/* --------------------------------------------------------------------------- + * Theme factory + * ------------------------------------------------------------------------- */ + +export function createPlaneTheme(options: PlaneThemeOptions): Theme { + const cookieConsent = options.cookieConsent ?? true; + + return { + Layout() { + return h(PlaneLayout, null, cookieConsent ? { "layout-bottom": () => h(CookieConsent) } : {}); + }, + + enhanceApp(ctx) { + const { app, router, siteData } = ctx; + + // What VoidZeroTheme.enhanceApp does, minus its "default to dark when the visitor + // has no stored preference" behaviour — both sites follow the system setting. + const variant = siteData.value.themeConfig?.variant || "voidzero"; + if (typeof document !== "undefined") { + document.documentElement.setAttribute("data-variant", variant); + watch( + () => router.route.data.frontmatter?.theme, + (theme) => { + if (theme) document.documentElement.setAttribute("data-theme", theme); + else document.documentElement.removeAttribute("data-theme"); + }, + { immediate: true }, + ); + } + app.component("Badge", VPBadge); + + app.provide(themeContextKey, { + /* VoidZero naming: logoDark = dark mark (light bg), logoLight = light mark (dark bg) */ + logoDark: options.brand.logoOnLight, + logoLight: options.brand.logoOnDark, + logoAlt: options.brand.logoAlt ?? "Plane", + footerBg: options.brand.footerBg, + monoIcon: options.brand.monoIcon, + }); + app.provide(planeOptionsKey, options); + + enhanceAppWithTabs(app); + + app.component("Card", Card); + app.component("CardGroup", CardGroup); + app.component("Tags", Tags); + for (const [name, component] of Object.entries(options.components ?? {})) { + app.component(name, component); + } + + options.enhanceApp?.(ctx); + }, + + setup() { + if (typeof window === "undefined") return; + + const route = useRoute(); + const { isDark } = useData(); + let zoom: ReturnType | null = null; + let htmlClassObserver: MutationObserver | null = null; + + // Keep `html.dark` in lock-step with VitePress' `isDark` (VitePress' inline + // check-dark-mode script only ever *adds* the class). + watch( + isDark, + (dark) => { + document.documentElement.classList.toggle("dark", dark); + syncHeaderTheme(); + }, + { immediate: true }, + ); + + const initZoom = () => { + zoom?.detach(); + zoom = mediumZoom(".vp-doc :not(a) > img:not(.VPImage)", { + background: "rgba(0, 0, 0, 0.8)", + }); + }; + + const scheduleHeaderSync = () => { + nextTick(() => { + syncHeaderTheme(); + requestAnimationFrame(syncHeaderTheme); + }); + }; + + onMounted(() => { + nextTick(() => { + initZoom(); + scheduleHeaderSync(); + }); + + setTimeout(() => { + handleTabHash(); + setupTabHashUpdates(); + syncHeaderTheme(); + }, 100); + + window.addEventListener("hashchange", handleHashChange); + + htmlClassObserver = new MutationObserver(syncHeaderTheme); + htmlClassObserver.observe(document.documentElement, { + attributes: true, + attributeFilter: ["class"], + }); + }); + + onUnmounted(() => { + window.removeEventListener("hashchange", handleHashChange); + htmlClassObserver?.disconnect(); + zoom?.detach(); + }); + + watch( + () => route.path, + () => { + nextTick(() => { + initZoom(); + handleTabHash(); + setupTabHashUpdates(); + scheduleHeaderSync(); + }); + }, + ); + + options.setup?.(); + }, + }; +} diff --git a/docs/.vitepress/theme/plane/layout/Layout.vue b/docs/.vitepress/theme/plane/layout/Layout.vue new file mode 100644 index 00000000..d23a5cae --- /dev/null +++ b/docs/.vitepress/theme/plane/layout/Layout.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/docs/.vitepress/theme/plane/layout/default-layout.ts b/docs/.vitepress/theme/plane/layout/default-layout.ts new file mode 100644 index 00000000..41b63b86 --- /dev/null +++ b/docs/.vitepress/theme/plane/layout/default-layout.ts @@ -0,0 +1,10 @@ +import { defineComponent, h } from "vue"; +import Layout from "./doc-layout.vue"; +import { slotsToChildren } from "./slots"; + +export default defineComponent({ + name: "PlaneVoidzeroDefaultLayout", + setup(_, { slots }) { + return () => h(Layout, null, slotsToChildren(slots)); + }, +}); diff --git a/docs/.vitepress/theme/plane/layout/doc-layout.vue b/docs/.vitepress/theme/plane/layout/doc-layout.vue new file mode 100644 index 00000000..2ff8c45b --- /dev/null +++ b/docs/.vitepress/theme/plane/layout/doc-layout.vue @@ -0,0 +1,179 @@ + + + + + + + diff --git a/docs/.vitepress/theme/plane/layout/header.ts b/docs/.vitepress/theme/plane/layout/header.ts new file mode 100644 index 00000000..600b3d49 --- /dev/null +++ b/docs/.vitepress/theme/plane/layout/header.ts @@ -0,0 +1,10 @@ +import { defineComponent, h } from "vue"; +import Header from "../components/PlaneHeader.vue"; +import { slotsToChildren } from "./slots"; + +export default defineComponent({ + name: "PlaneVoidzeroHeader", + setup(_, { slots }) { + return () => h(Header, null, slotsToChildren(slots)); + }, +}); diff --git a/docs/.vitepress/theme/plane/layout/slots.ts b/docs/.vitepress/theme/plane/layout/slots.ts new file mode 100644 index 00000000..eb223fb9 --- /dev/null +++ b/docs/.vitepress/theme/plane/layout/slots.ts @@ -0,0 +1,13 @@ +import type { Slots, VNode } from "vue"; + +/** Normalize Vue 3 slots for use with `h(Component, props, children)` */ +export function slotsToChildren(slots: Slots): Record VNode[]> { + const children: Record VNode[]> = {}; + for (const name of Object.keys(slots)) { + const slot = slots[name]; + if (slot) { + children[name] = () => slot() as VNode[]; + } + } + return children; +} diff --git a/docs/.vitepress/theme/plane/layout/top-banner.ts b/docs/.vitepress/theme/plane/layout/top-banner.ts new file mode 100644 index 00000000..02492af3 --- /dev/null +++ b/docs/.vitepress/theme/plane/layout/top-banner.ts @@ -0,0 +1,9 @@ +import { defineComponent, h } from "vue"; +import Banner from "@voidzero-dev/vitepress-theme/src/components/oss/TopBanner.vue"; + +export default defineComponent({ + name: "PlaneVoidzeroTopBanner", + setup() { + return () => h(Banner); + }, +}); diff --git a/docs/.vitepress/theme/plane/manifest.json b/docs/.vitepress/theme/plane/manifest.json new file mode 100644 index 00000000..9af2f540 --- /dev/null +++ b/docs/.vitepress/theme/plane/manifest.json @@ -0,0 +1,36 @@ +{ + "root": "docs/.vitepress/theme/plane", + "files": [ + "manifest.json", + "README.md", + "components/Card.vue", + "components/CardGroup.vue", + "components/CookieConsent.vue", + "components/CopyPageMenu.vue", + "components/PlaneHeader.vue", + "components/Tags.vue", + "components/card-brand-icons.ts", + "components/copy-page-icons.ts", + "css/api.css", + "css/base.css", + "css/components.css", + "css/fonts.css", + "css/index.css", + "css/layout.css", + "css/tokens.css", + "index.ts", + "layout/Layout.vue", + "layout/default-layout.ts", + "layout/doc-layout.vue", + "layout/header.ts", + "layout/slots.ts", + "layout/top-banner.ts", + "options.ts", + "scripts/check-theme-sync.mjs", + "scripts/check-vue-types.mjs", + "types/shims.d.ts", + "types/vitepress-augment.d.ts", + "types/voidzero-theme.ts", + "types/vp-theme-modules.d.ts" + ] +} diff --git a/docs/.vitepress/theme/plane/options.ts b/docs/.vitepress/theme/plane/options.ts new file mode 100644 index 00000000..e33b624a --- /dev/null +++ b/docs/.vitepress/theme/plane/options.ts @@ -0,0 +1,30 @@ +import type { Component, InjectionKey } from "vue"; +import type { EnhanceAppContext } from "vitepress"; + +/** Per-site branding + hooks for the shared Plane docs theme. */ +export interface PlaneThemeOptions { + brand: { + /** Logo shown on light backgrounds (dark mark). */ + logoOnLight: string; + /** Logo shown on dark backgrounds (light mark). */ + logoOnDark: string; + /** Alt text for the logo. Default: "Plane". */ + logoAlt?: string; + /** Wordmark next to the logo in the mobile menu, e.g. "Plane Docs". */ + menuTitle: string; + /** Footer background image (consumed by the VoidZero footer). */ + footerBg: string; + /** Monochrome icon (consumed by the VoidZero top banner). */ + monoIcon: string; + }; + /** Render the cookie-consent banner. Default: true. */ + cookieConsent?: boolean; + /** Extra globally-registered components (site-specific markdown components). */ + components?: Record; + /** Extra `enhanceApp` work, run after the shared setup. */ + enhanceApp?: (ctx: EnhanceAppContext) => void; + /** Extra client-side `setup()` work, run inside the shared theme's `setup()`. */ + setup?: () => void; +} + +export const planeOptionsKey: InjectionKey = Symbol.for("plane-theme-options"); diff --git a/docs/.vitepress/theme/plane/scripts/check-theme-sync.mjs b/docs/.vitepress/theme/plane/scripts/check-theme-sync.mjs new file mode 100644 index 00000000..a3b33133 --- /dev/null +++ b/docs/.vitepress/theme/plane/scripts/check-theme-sync.mjs @@ -0,0 +1,158 @@ +#!/usr/bin/env node +/** + * check-theme-sync — verify that docs/.vitepress/theme/plane/ is byte-identical to the + * sibling repo's copy (makeplane/docs ⇄ makeplane/developer-docs). + * + * node docs/.vitepress/theme/plane/scripts/check-theme-sync.mjs --sibling makeplane/developer-docs + * + * Sibling source, in order of preference: + * 1. THEME_SIBLING_PATH — local checkout root (e.g. ../developer-docs) + * 2. https://raw.githubusercontent.com///… — ref from THEME_SIBLING_REF, + * then GITHUB_HEAD_REF (same-named PR branch), then master. + * + * While only one repo has adopted the shared theme the sibling has no `plane/` folder yet. + * That is reported and skipped (exit 0) rather than failing, so unrelated PRs in the repo + * that merged first are not blocked; the check becomes binding as soon as both sides have it. + * + * Exit codes: 0 identical (or sibling not adopted yet) · 1 drift (or manifest out of date) + * · 2 sibling unreachable / bad args + */ +import { createHash } from "node:crypto"; +import { readdir, readFile } from "node:fs/promises"; +import { dirname, join, relative, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const THEME_DIR = resolve(dirname(fileURLToPath(import.meta.url)), ".."); +const THEME_REL = "docs/.vitepress/theme/plane"; + +const args = process.argv.slice(2); +const siblingArg = args[args.indexOf("--sibling") + 1]; +if (!args.includes("--sibling") || !siblingArg || !siblingArg.includes("/")) { + console.error("usage: check-theme-sync.mjs --sibling "); + process.exit(2); +} + +const sha = (buf) => createHash("sha256").update(buf).digest("hex"); + +async function walk(dir, base = dir) { + const out = []; + for (const entry of await readdir(dir, { withFileTypes: true })) { + if (entry.name.startsWith(".")) continue; + const full = join(dir, entry.name); + if (entry.isDirectory()) out.push(...(await walk(full, base))); + else out.push(relative(base, full).split("\\").join("/")); + } + return out.sort(); +} + +async function readLocal(file) { + return readFile(join(THEME_DIR, file)); +} + +/** Present on every ref of both repos — tells "ref exists" apart from "ref has no plane/". */ +const ROOT_PROBE = "package.json"; + +async function makeSiblingReader() { + const localPath = process.env.THEME_SIBLING_PATH; + if (localPath) { + const checkout = resolve(process.cwd(), localPath); + const root = join(checkout, THEME_REL); + const exists = (file) => + readFile(file).then( + () => true, + () => false, + ); + if (await exists(join(root, "manifest.json"))) { + return { + status: "ok", + label: root, + read: (file) => readFile(join(root, file)).catch(() => null), + }; + } + return (await exists(join(checkout, ROOT_PROBE))) + ? { status: "not-adopted", label: checkout } + : null; + } + + const refs = [process.env.THEME_SIBLING_REF, process.env.GITHUB_HEAD_REF, "master"].filter( + Boolean, + ); + let reachable = null; + for (const ref of refs) { + const root = `https://raw.githubusercontent.com/${siblingArg}/${ref}/`; + const base = `${root}${THEME_REL}/`; + const probe = await fetch(base + "manifest.json").catch(() => null); + if (probe?.ok) { + return { + status: "ok", + label: base, + read: async (file) => { + const res = await fetch(base + file).catch(() => null); + return res?.ok ? Buffer.from(await res.arrayBuffer()) : null; + }, + }; + } + if (!reachable) { + const rootProbe = await fetch(root + ROOT_PROBE).catch(() => null); + if (rootProbe?.ok) reachable = `${siblingArg}@${ref}`; + } + } + return reachable ? { status: "not-adopted", label: reachable } : null; +} + +const manifest = JSON.parse(await readLocal("manifest.json")); +const listed = [...manifest.files].sort(); +const onDisk = await walk(THEME_DIR); + +let failed = false; +const missingFromManifest = onDisk.filter((f) => !listed.includes(f)); +const missingFromDisk = listed.filter((f) => !onDisk.includes(f)); +if (missingFromManifest.length || missingFromDisk.length) { + failed = true; + console.error("manifest.json is out of date:"); + for (const f of missingFromManifest) console.error(` not listed: ${f}`); + for (const f of missingFromDisk) console.error(` not on disk: ${f}`); +} + +const sibling = await makeSiblingReader(); +if (!sibling) { + console.error( + `Could not reach the sibling repo (${siblingArg}). Set THEME_SIBLING_PATH=../ for a local checkout.`, + ); + process.exit(2); +} + +if (sibling.status === "not-adopted") { + console.log( + `${sibling.label} has no ${THEME_REL} yet — skipping the cross-repo comparison.\n` + + `This is expected only until the companion PR lands; the check binds once both repos have the folder.`, + ); + process.exit(failed ? 1 : 0); +} + +console.log(`Comparing ${THEME_REL} against ${sibling.label}`); + +const siblingManifestRaw = await sibling.read("manifest.json"); +const siblingFiles = siblingManifestRaw ? JSON.parse(siblingManifestRaw.toString()).files : []; +const all = [...new Set([...listed, ...siblingFiles])].sort(); + +for (const file of all) { + const [local, remote] = await Promise.all([ + readLocal(file).catch(() => null), + sibling.read(file), + ]); + let status; + if (!local) status = "MISSING (local)"; + else if (!remote) status = "MISSING (sibling)"; + else status = sha(local) === sha(remote) ? "OK" : "DIFF"; + if (status !== "OK") failed = true; + console.log(`${status.padEnd(18)} ${file}`); +} + +if (failed) { + console.error( + "\nTheme drift detected. Copy the folder to/from the sibling repo so both are identical.", + ); + process.exit(1); +} +console.log("\nShared theme is in sync."); diff --git a/docs/.vitepress/theme/plane/scripts/check-vue-types.mjs b/docs/.vitepress/theme/plane/scripts/check-vue-types.mjs new file mode 100644 index 00000000..5f757678 --- /dev/null +++ b/docs/.vitepress/theme/plane/scripts/check-vue-types.mjs @@ -0,0 +1,62 @@ +#!/usr/bin/env node +/** + * check-vue-types — type-check the VitePress config and theme, SFCs included. + * + * node docs/.vitepress/theme/plane/scripts/check-vue-types.mjs [tsconfig] + * + * Plain `tsc` cannot parse `.vue`, so it silently skips every component in the + * `include` globs — `tsc --noEmit` stays green with an outright type error in an + * SFC. `vue-tsc` reads them, but it also surfaces errors from the vendored + * `@voidzero-dev/vitepress-theme` sources our components import (unlisted optional + * peer deps, loose types), which we cannot fix from here and `skipLibCheck` does + * not cover because they are `.vue`, not `.d.ts`. + * + * So: everything is type-checked, node_modules diagnostics are summarised as a + * note, and only first-party files decide the exit code. + * + * Exit codes: 0 clean · 1 type errors in first-party files · 2 vue-tsc failed to run + */ +import { spawnSync } from "node:child_process"; + +const project = process.argv[2] ?? "docs/.vitepress/tsconfig.json"; + +const run = spawnSync("vue-tsc", ["--noEmit", "-p", project], { + encoding: "utf8", + shell: process.platform === "win32", +}); + +if (run.error) { + console.error(`Could not run vue-tsc: ${run.error.message}`); + process.exit(2); +} + +const lines = `${run.stdout ?? ""}${run.stderr ?? ""}`.split("\n").filter(Boolean); +const isDiagnostic = (line) => /\(\d+,\d+\): error TS\d+:/.test(line); +const isVendored = (line) => line.startsWith("node_modules/") || line.includes("/node_modules/"); + +const ours = lines.filter((line) => isDiagnostic(line) && !isVendored(line)); +const vendored = lines.filter((line) => isDiagnostic(line) && isVendored(line)); +const other = lines.filter((line) => !isDiagnostic(line)); + +for (const line of ours) console.error(line); + +if (vendored.length) { + console.log( + `\nnote: ignored ${vendored.length} diagnostic(s) from node_modules ` + + `(vendored @voidzero-dev/vitepress-theme sources — not ours to fix).`, + ); +} + +if (ours.length) { + console.error(`\n${ours.length} type error(s) in first-party files.`); + process.exit(1); +} + +// vue-tsc can fail for reasons other than type errors (bad tsconfig, crash). +if (run.status !== 0 && !vendored.length) { + for (const line of other) console.error(line); + console.error(`\nvue-tsc exited with status ${run.status}.`); + process.exit(2); +} + +console.log("Types are clean (config, theme and .vue components)."); diff --git a/docs/.vitepress/theme/plane/types/shims.d.ts b/docs/.vitepress/theme/plane/types/shims.d.ts new file mode 100644 index 00000000..87efbe0e --- /dev/null +++ b/docs/.vitepress/theme/plane/types/shims.d.ts @@ -0,0 +1,40 @@ +/* + * Ambient module shims (this file must stay a script: no top-level import/export). + */ + +declare module "*.vue" { + import type { DefineComponent } from "vue"; + const component: DefineComponent; + export default component; +} + +/** Deep imports from @voidzero-dev/vitepress-theme (the package does not ship .vue types) */ +declare module "@voidzero-dev/vitepress-theme/src/components/vitepress-default/Layout.vue" { + import type { DefineComponent } from "vue"; + const component: DefineComponent; + export default component; +} + +declare module "@voidzero-dev/vitepress-theme/src/components/oss/Header.vue" { + import type { DefineComponent } from "vue"; + const component: DefineComponent; + export default component; +} + +declare module "@voidzero-dev/vitepress-theme/src/components/oss/TopBanner.vue" { + import type { DefineComponent } from "vue"; + const component: DefineComponent; + export default component; +} + +declare module "@voidzero-dev/vitepress-theme/src/types/theme-context" { + import type { InjectionKey } from "vue"; + export interface ThemeContext { + logoDark: string; + logoLight: string; + logoAlt: string; + footerBg: string; + monoIcon: string; + } + export const themeContextKey: InjectionKey; +} diff --git a/docs/.vitepress/theme/plane/types/vitepress-augment.d.ts b/docs/.vitepress/theme/plane/types/vitepress-augment.d.ts new file mode 100644 index 00000000..48231188 --- /dev/null +++ b/docs/.vitepress/theme/plane/types/vitepress-augment.d.ts @@ -0,0 +1,20 @@ +/* + * VitePress config augmentations used by the shared theme (module file on purpose). + */ +import type {} from "vitepress"; + +declare module "vitepress" { + namespace DefaultTheme { + interface Config { + /** VoidZero theme variant (both Plane sites use "voidzero"). */ + variant?: "voidzero" | "viteplus" | "vite" | "vitest" | "rolldown" | "oxc"; + } + interface NavItemWithLink { + /** + * Render this nav item as a header button instead of a nav link: + * "primary" = filled (Sign in), "secondary" = outlined (link to the sibling docs site). + */ + planeButton?: "primary" | "secondary"; + } + } +} diff --git a/docs/.vitepress/theme/plane/types/voidzero-theme.ts b/docs/.vitepress/theme/plane/types/voidzero-theme.ts new file mode 100644 index 00000000..a77d72c7 --- /dev/null +++ b/docs/.vitepress/theme/plane/types/voidzero-theme.ts @@ -0,0 +1,14 @@ +import type { Component } from "vue"; +import type { Theme } from "vitepress"; + +export { + themeContextKey, + type ThemeContext, +} from "@voidzero-dev/vitepress-theme/src/types/theme-context"; + +export const VPHomeHero = {} as Component; +export const VPHomeFeatures = {} as Component; + +declare const VoidZeroTheme: Theme; +export { VoidZeroTheme }; +export default VoidZeroTheme; diff --git a/docs/.vitepress/theme/plane/types/vp-theme-modules.d.ts b/docs/.vitepress/theme/plane/types/vp-theme-modules.d.ts new file mode 100644 index 00000000..564d5e05 --- /dev/null +++ b/docs/.vitepress/theme/plane/types/vp-theme-modules.d.ts @@ -0,0 +1,115 @@ +/** + * Explicit module declarations for VoidZero VitePress theme aliases. + * Wildcard patterns are unreliable in Vetur / some IDE resolvers; list each import path. + */ +import type { DefineComponent } from "vue"; + +type VueModule = DefineComponent; + +declare module "@vp-default/VPNavBarSearch.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPNavBarMenuLink.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPNavBarMenuGroup.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPNavBarAppearance.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPSwitchAppearance.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPNavBarSocialLinks.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPSocialLinks.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPBadge.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPBackdrop.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPContent.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPFooter.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPLocalNav.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPSidebar.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-default/VPSkipLink.vue" { + const component: VueModule; + export default component; +} + +declare module "@components/oss/TopBanner.vue" { + const component: VueModule; + export default component; +} + +declare module "@vp-composables/langs" { + export function useLangs(options?: { correspondingLink?: boolean }): { + localeLinks: { link: string; text: string }[]; + currentLang: { label?: string }; + }; +} + +declare module "@vp-composables/data" { + export function useData(): ReturnType; +} + +declare module "@vp-composables/layout" { + export const layoutInfoInjectionKey: symbol; + export function registerWatchers(options: { closeSidebar: () => void }): void; + export function useLayout(): { hasSidebar: import("vue").ComputedRef }; +} + +declare module "@vp-composables/sidebar" { + export function useSidebarControl(): { + isOpen: import("vue").Ref; + open: () => void; + close: () => void; + }; +} + +declare module "@vp-support/utils" { + export function normalizeLink(path: string): string; +} + +declare module "@vp-support/search-config" { + export function getSearchProvider(theme: unknown): "local" | "algolia" | undefined; +} diff --git a/docs/.vitepress/theme/site.css b/docs/.vitepress/theme/site.css new file mode 100644 index 00000000..1729a2d9 --- /dev/null +++ b/docs/.vitepress/theme/site.css @@ -0,0 +1 @@ +/* docs.plane.so — site-specific styles (everything shared lives in ./plane/css) */ diff --git a/docs/.vitepress/theme/style.css b/docs/.vitepress/theme/style.css deleted file mode 100644 index 314ffbd1..00000000 --- a/docs/.vitepress/theme/style.css +++ /dev/null @@ -1,1416 +0,0 @@ -/** @format */ - -@import "@voidzero-dev/vitepress-theme/src/styles/index.css"; - -@source "../../**/*.{vue,md}"; -@source "../**/*.{vue,md}"; - -@theme { - --color-plane-400: #0088cc; - --color-plane-500: #006399; - --color-plane-600: #005280; - --font-heading: "Inter", sans-serif; - --font-sans: "Inter", sans-serif; - --font-mono: "IBM Plex Mono", monospace; -} - -/* ================================================ - THEME VARIANTS - ================================================ */ - -@custom-variant light (&:where([data-theme*="light"], [data-theme*="light"] *)); -@custom-variant dark (&:where([data-theme*="dark"], [data-theme*="dark"] *)); - -/* ================================================ - COLOR SYSTEM - ================================================ */ - -@layer base { - :root { - /* Alpha colors - for transparency effects */ - --alpha-white-0: oklch(1 0 0 / 0%); - --alpha-white-200: oklch(1 0 0 / 10%); - --alpha-white-500: oklch(1 0 0 / 30%); - --alpha-white-700: oklch(1 0 0 / 50%); - --alpha-black-0: oklch(0.1482 0.0034 196.79 / 0%); - --alpha-black-200: oklch(0.1482 0.0034 196.79 / 10%); - --alpha-black-500: oklch(0.1482 0.0034 196.79 / 30%); - --alpha-black-700: oklch(0.1482 0.0034 196.79 / 50%); - - /* Neutral colors - for text and backgrounds */ - --neutral-white: oklch(1 0 0); - --neutral-100: oklch(0.9848 0.0003 230.66); - --neutral-200: oklch(0.9696 0.0007 230.67); - --neutral-300: oklch(0.9543 0.001 230.67); - --neutral-500: oklch(0.9235 0.001733 230.6853); - --neutral-700: oklch(0.8612 0.0032 230.71); - --neutral-800: oklch(0.6668 0.0079 230.82); - --neutral-1000: oklch(0.5288 0.0083 230.88); - --neutral-1100: oklch(0.4377 0.0066 230.87); - --neutral-1200: oklch(0.2378 0.0029 230.83); - --neutral-black: oklch(0.1472 0.0034 230.83); - - /* Brand colors */ - --brand-100: oklch(0.9847 0.0083 236.56); - --brand-300: oklch(0.9428 0.0341 230.22); - --brand-500: oklch(0.8414 0.0947 233.08); - --brand-700: oklch(0.6766 0.1665 243.91); - --brand-900: oklch(0.4347 0.104093 242.4823); - --brand-default: oklch(0.4799 0.1158 242.91); - - /* Semantic colors */ - --green-100: oklch(0.9819 0.0181 155.83); - --green-500: oklch(0.7914 0.2091 151.66); - --green-700: oklch(0.632 0.185972 147.3695); - --amber-100: oklch(0.9869 0.0214 95.28); - --amber-500: oklch(0.829 0.1712 81.04); - --amber-700: oklch(0.6671 0.1685 53.38); - --red-100: oklch(0.9705 0.0129 17.38); - --red-500: oklch(0.7022 0.1892 22.23); - --red-700: oklch(0.583 0.238666 28.4765); - - /* Font sizes */ - --text-xs: 0.75rem; /* 12px */ - --text-sm: 0.875rem; /* 14px */ - --text-base: 1rem; /* 16px */ - --text-lg: 1.125rem; /* 18px */ - --text-xl: 1.25rem; /* 20px */ - --text-2xl: 1.5rem; /* 24px */ - --text-3xl: 1.875rem; /* 30px */ - --text-4xl: 2.25rem; /* 36px */ - - /* Font weights */ - --font-weight-light: 300; - --font-weight-normal: 400; - --font-weight-medium: 500; - --font-weight-semibold: 600; - --font-weight-bold: 700; - } -} - -/* ================================================ - INTER VARIABLE FONT - ================================================ */ - -@font-face { - font-family: "Inter"; - src: url("/fonts/Inter/InterVariable.woff2") format("woff2"); - font-weight: 100 900; - font-style: normal; - font-display: swap; -} - -/* ================================================ - IBM PLEX MONO FONT (FOR CODE BLOCKS) - ================================================ */ - -@font-face { - font-family: "IBM Plex Mono"; - src: url("/fonts/IBMPlexMono/IBMPlexMono-Regular.ttf") format("truetype"); - font-weight: 400; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: "IBM Plex Mono"; - src: url("/fonts/IBMPlexMono/IBMPlexMono-Medium.ttf") format("truetype"); - font-weight: 500; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: "IBM Plex Mono"; - src: url("/fonts/IBMPlexMono/IBMPlexMono-SemiBold.ttf") format("truetype"); - font-weight: 600; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: "IBM Plex Mono"; - src: url("/fonts/IBMPlexMono/IBMPlexMono-Bold.ttf") format("truetype"); - font-weight: 700; - font-style: normal; - font-display: swap; -} - -/* ================================================ - PLANE DEVELOPER DOCS - CUSTOM STYLES - ================================================ */ - -/* Brand colors and fonts */ -:root, -[data-theme="light"], -[data-theme="dark"], -html.dark { - /* Brand colors */ - --vp-c-brand-1: #006399; - --vp-c-brand-2: #006399; - --vp-c-brand-3: #006399; - --vp-c-brand-soft: rgba(0, 99, 153, 0.14); - --plane-500: #006399; - - /* Inline code — neutral body-text color instead of the VitePress default - (brand blue), which is hard to read on the dark pill background. - Linked code keeps --vp-code-link-color (brand) so links stay visible. */ - --vp-code-color: var(--vp-c-text-1); - - /* Fonts — Inter for body and headings (override VoidZero APK Protocol) */ - --font-heading: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; - --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; - --font-mono: - "IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, - "Liberation Mono", "Courier New", monospace; - --vp-font-family-base: - "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, - sans-serif; - --vp-font-family-mono: - "IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, - "Liberation Mono", "Courier New", monospace; -} - -/* Font rendering optimizations */ -body, -.docs-layout { - font-family: var(--vp-font-family-base); -} - -.docs-layout h1, -.docs-layout h2, -.docs-layout h3, -.docs-layout h4, -.docs-layout h5, -.docs-layout h6, -.vp-doc h1, -.vp-doc h2, -.vp-doc h3, -.vp-doc h4, -.vp-doc h5, -.vp-doc h6, -.font-heading { - font-family: var(--vp-font-family-base) !important; -} - -body { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - text-rendering: optimizeLegibility; - font-feature-settings: "cv01", "cv02", "zero"; -} - -/* Typography tuning */ -.vp-doc { - line-height: 1.7; - letter-spacing: -0.011em; -} - -.vp-doc h1 { - letter-spacing: -0.022em; - line-height: 1.2; -} - -.vp-doc h2 { - letter-spacing: -0.017em; - line-height: 1.3; -} - -.vp-doc h3 { - letter-spacing: -0.014em; - line-height: 1.4; -} - -/* Inline doc links (lists, paragraphs, etc.) — match primary button brand per theme */ -.vp-doc a:not(.card-link):not(.home-doc-actions__btn):not(.header-anchor):not(.copy-page__item) { - color: var(--vp-c-brand-1); -} - -.vp-doc - a:not(.card-link):not(.home-doc-actions__btn):not(.header-anchor):not(.copy-page__item):hover { - color: #0078b8; -} - -.dark - .vp-doc - a:not(.card-link):not(.home-doc-actions__btn):not(.header-anchor):not(.copy-page__item):hover, -[data-theme="dark"] - .vp-doc - a:not(.card-link):not(.home-doc-actions__btn):not(.header-anchor):not(.copy-page__item):hover, -html.dark - .vp-doc - a:not(.card-link):not(.home-doc-actions__btn):not(.header-anchor):not(.copy-page__item):hover { - color: #3aa5d4; -} - -/* Dark mode — override @voidzero-dev/vitepress-theme (docs set data-theme="dark" on the layout wrapper) */ -.dark:not([data-theme]), -[data-theme="dark"], -html.dark { - /* VoidZero maps page bg to --color-primary, not only --vp-c-bg */ - --color-primary: #141415; - --vp-c-bg: #141415; - --vp-c-bg-soft: #1f2122; - --vp-c-bg-alt: #141618; - --vp-c-bg-mute: #252829; - - /* Brand colors */ - --vp-c-brand-1: #2893cc; - --vp-c-brand-2: #2893cc; - --vp-c-brand-3: #2893cc; - --vp-c-brand-soft: rgba(40, 147, 204, 0.14); - --plane-500: #2893cc; -} - -/* Ensure page shell picks up Plane dark background (theme sets bg on [data-theme="dark"] and .docs-layout) */ -html.dark body, -html.dark:not([data-theme]) .docs-layout, -[data-theme="dark"], -[data-theme="dark"] .docs-layout { - background-color: #141415; -} - -/* ================================================ - HIDE ASIDE FOR API PAGES - ================================================ */ - -/* Hide ALL aside elements when .api-page is present */ -.api-page .aside, -.api-page .aside-container, -.api-page .VPDocAside, -.api-page aside, -.api-page .VPDocAsideOutline { - display: none !important; - width: 0 !important; - min-width: 0 !important; - opacity: 0 !important; - visibility: hidden !important; -} - -/* Remove the aside column entirely */ -.api-page.VPDoc > .container { - display: block !important; - max-width: 100% !important; -} - -.api-page .VPDoc > .container > .content { - max-width: 100% !important; - padding-right: 24px !important; -} - -/* Target specific VitePress structure */ -.api-page .content-container { - max-width: 100% !important; -} - -.api-page .main { - max-width: 100% !important; -} - -/* Force full width on content */ -.api-page .vp-doc { - max-width: 100% !important; -} - -/* ================================================ - TWO-COLUMN API LAYOUT - ================================================ */ - -.api-two-column { - display: grid; - grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); - gap: 40px; - align-items: start; -} - -@media (max-width: 1100px) { - .api-two-column { - grid-template-columns: 1fr; - gap: 24px; - } -} - -.api-left { - min-width: 0; -} - -.api-right { - position: sticky; - top: 100px; - min-width: 0; -} - -@media (max-width: 1100px) { - .api-right { - position: static; - } -} - -/* ================================================ - API ENDPOINT BADGE - ================================================ */ - -.api-endpoint-badge { - display: inline-flex; - align-items: center; - gap: 12px; - margin-bottom: 20px; -} - -.api-endpoint-badge .method { - font-size: 12px; - font-weight: 700; - padding: 5px 12px; - border-radius: 6px; - font-family: var(--vp-font-family-mono); - text-transform: uppercase; -} - -.api-endpoint-badge .method.get { - background: #dcfce7; - color: #166534; -} - -.api-endpoint-badge .method.post { - background: #dbeafe; - color: #1e40af; -} - -.api-endpoint-badge .method.patch, -.api-endpoint-badge .method.put { - background: #fef3c7; - color: #92400e; -} - -.api-endpoint-badge .method.delete { - background: #fee2e2; - color: #991b1b; -} - -.dark .api-endpoint-badge .method.get { - background: rgba(34, 197, 94, 0.15); - color: #4ade80; -} - -.dark .api-endpoint-badge .method.post { - background: rgba(59, 130, 246, 0.15); - color: #60a5fa; -} - -.dark .api-endpoint-badge .method.patch, -.dark .api-endpoint-badge .method.put { - background: rgba(251, 191, 36, 0.15); - color: #fbbf24; -} - -.dark .api-endpoint-badge .method.delete { - background: rgba(239, 68, 68, 0.15); - color: #f87171; -} - -.api-endpoint-badge .path { - font-family: var(--vp-font-family-mono); - font-size: 14px; - color: #6b7280; -} - -.dark .api-endpoint-badge .path { - color: #9ca3af; -} - -/* ================================================ - SECTION HEADERS - ================================================ */ - -.params-section { - margin: 24px 0; -} - -.params-section h3 { - font-size: 13px !important; - font-weight: 600 !important; - color: #6b7280 !important; - text-transform: uppercase; - letter-spacing: 0.05em; - margin: 0 0 12px 0 !important; - padding: 0 !important; - border: none !important; -} - -.dark .params-section h3 { - color: #9ca3af !important; -} - -.params-list { - border-top: 1px solid #e5e7eb; -} - -.dark .params-list { - border-top-color: #2a2a2a; -} - -.returns-section { - margin: 24px 0; -} - -.returns-section h3 { - font-size: 13px !important; - font-weight: 600 !important; - color: #6b7280 !important; - text-transform: uppercase; - letter-spacing: 0.05em; - margin: 0 0 12px 0 !important; - padding: 0 !important; - border: none !important; -} - -.dark .returns-section h3 { - color: #9ca3af !important; -} - -/* ================================================ - CODE BLOCKS - DARK MODE FIX - ================================================ */ - -div[class*="language-"] { - border-radius: 8px !important; - overflow: hidden; - border: 1px solid #e5e7eb; - background: #fafafa !important; -} - -.dark div[class*="language-"] { - background: #0f0f0f !important; - border-color: #2a2a2a !important; -} - -div[class*="language-"] pre { - background: transparent !important; -} - -.dark div[class*="language-"] pre { - background: transparent !important; -} - -.dark .shiki, -.dark .shiki span { - background: transparent !important; -} - -/* Language label */ -div[class*="language-"] > span.lang { - color: #9ca3af; - font-size: 12px; -} - -/* ================================================ - UTILITY CLASSES - ================================================ */ - -/* Keep markdown helper class, but don't override Tailwind's global `.hidden` utility. */ -.vp-doc .hidden { - display: none !important; -} - -/* Remove default VitePress h2/h3 borders */ -.vp-doc h2 { - border-top: none !important; - margin-top: 32px; -} - -.vp-doc h3 { - border-top: none !important; -} - -/* ================================================ - CARD GROUP COMPONENT STYLES - ================================================ */ - -.card-group { - display: grid; - gap: 16px; - margin: 24px 0; -} - -.card-group-2 { - grid-template-columns: 1fr; -} - -@media (min-width: 768px) { - .card-group-2 { - grid-template-columns: repeat(2, 1fr); - } -} - -.card-group-3 { - grid-template-columns: 1fr; -} - -@media (min-width: 768px) { - .card-group-3 { - grid-template-columns: repeat(2, 1fr); - } -} - -@media (min-width: 1024px) { - .card-group-3 { - grid-template-columns: repeat(3, 1fr); - } -} - -.card-group-4 { - grid-template-columns: 1fr; -} - -@media (min-width: 768px) { - .card-group-4 { - grid-template-columns: repeat(2, 1fr); - } -} - -@media (min-width: 1024px) { - .card-group-4 { - grid-template-columns: repeat(4, 1fr); - } -} - -/* ================================================ - CARD COMPONENT STYLES - ================================================ */ - -.vp-doc a.card-link { - color: inherit; - text-decoration: none !important; -} - -.card-link { - display: block; - padding: 24px; - border-radius: 12px; - border: 1px solid #e5e7eb; - background: #ffffff; - transition: all 0.2s ease; - text-decoration: none !important; - color: inherit; -} - -.card-link:hover { - border-color: #006399; - box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); - text-decoration: none !important; -} - -.dark .card-link { - border-color: #2a2a2a; - background: rgba(20, 20, 20, 0.5); -} - -.dark .card-link:hover { - border-color: #2893cc; - box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.5); -} - -.card-icon { - font-size: 32px; - margin-bottom: 16px; - line-height: 1; -} - -.card-title { - font-size: 16px !important; - font-weight: 600 !important; - color: #111827 !important; - margin: 0 0 12px 0 !important; - padding: 0 !important; - border: none !important; - transition: color 0.2s ease; -} - -.card-link:hover .card-title { - color: #006399 !important; -} - -.dark .card-title { - color: #f9fafb !important; -} - -.dark .card-link:hover .card-title { - color: #f9fafb !important; -} - -.card-description { - font-size: 14px; - color: #6b7280; - line-height: 1.6; - margin: 0; -} - -.dark .card-description { - color: #9ca3af; -} - -/* Home (index) hero actions */ -.vp-doc .home-doc-actions { - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 12px; - margin: 20px 0 36px; - padding: 0; -} - -.vp-doc .home-doc-actions__btn { - display: inline-flex; - align-items: center; - justify-content: center; - min-height: 40px; - padding: 9px 18px; - border-radius: 8px; - font-size: 15px; - font-weight: 500; - line-height: 1.25; - text-decoration: none !important; - transition: - background 0.2s ease, - color 0.2s ease, - border-color 0.2s ease, - box-shadow 0.2s ease; -} - -.vp-doc .home-doc-actions__btn--primary { - background: #006399; - color: #ffffff !important; - border: 1px solid #006399; -} - -.vp-doc .home-doc-actions__btn--primary:hover { - background: #0078b8; - border-color: #0078b8; - color: #ffffff !important; - box-shadow: 0 2px 8px rgba(0, 99, 153, 0.25); -} - -.vp-doc .home-doc-actions__btn--secondary { - background: transparent; - color: #0a0a0a !important; - border: 1px solid #e5e7eb; -} - -.vp-doc .home-doc-actions__btn--secondary:hover { - background: #f7f8f9; - border-color: #d1d5db; - color: #0a0a0a !important; -} - -.dark .vp-doc .home-doc-actions__btn--primary { - background: #2893cc; - border-color: #2893cc; - color: #ffffff !important; -} - -.dark .vp-doc .home-doc-actions__btn--primary:hover { - background: #3aa5d4; - border-color: #3aa5d4; -} - -.dark .vp-doc .home-doc-actions__btn--secondary { - background: #252829; - color: #ffffff !important; - border-color: #3f4244; -} - -.dark .vp-doc .home-doc-actions__btn--secondary:hover { - background: #2f3236; - border-color: #4a4e52; - color: #ffffff !important; -} - -/* Index page: hide prev/next doc footer and its top margin */ -.docs-layout .content-container:has(.home-feature-cards) .VPDocFooter { - display: none !important; - margin: 0 !important; -} - -/* Home (index) feature cards — light panels, CTA line, 3×2 grid (see design ref) */ -.vp-doc .home-feature-cards { - gap: 22px; - margin: 0 0 40px; -} - -.vp-doc .home-feature-cards .card-link { - display: flex; - flex-direction: column; - align-items: flex-start; - height: 100%; - padding: 28px; - border-radius: 14px; - border: none; - background: #f7f8f9; - box-shadow: none; - transition: background 0.2s ease; -} - -.vp-doc .home-feature-cards .card-link:hover { - border: none; - box-shadow: none; - background: #eef0f2; -} - -.vp-doc .home-feature-cards .card-link:hover .card-title { - color: #111827 !important; -} - -.vp-doc .home-feature-cards .card-icon { - display: flex; - align-items: center; - justify-content: center; - margin: 0 0 10px 0; - color: #0a0a0a; -} - -.vp-doc .home-feature-cards .card-icon svg { - width: 24px; - height: 24px; - flex-shrink: 0; -} - -.vp-doc .home-feature-cards .card-title { - font-size: 1.125rem !important; - line-height: 1.3 !important; - font-weight: 600 !important; - color: #0a0a0a !important; - margin: 0 0 8px 0 !important; -} - -.vp-doc .home-feature-cards .card-description { - font-size: 15px; - line-height: 1.6; - color: #4a5568; - margin: 0 0 0 0; - flex: 1 1 auto; -} - -/* Card CTA layout (colors live in Card.vue to beat voidzero .vp-doc a { color: inherit }) */ -.vp-doc .home-feature-cards .card-cta { - display: block; - margin-top: 20px; - padding-top: 0; - font-size: 15px; - line-height: 1.3; -} - -.vp-doc .home-feature-cards .card-link--with-cta .card-cta { - margin-top: auto; - padding-top: 16px; -} - -.dark .vp-doc .home-feature-cards .card-link { - background: #181a1b; -} - -.dark .vp-doc .home-feature-cards .card-link:hover { - background: #1d1f20; -} - -.dark .vp-doc .home-feature-cards .card-icon { - color: #f4f4f4; -} - -.dark .vp-doc .home-feature-cards .card-title { - color: #f4f4f4 !important; -} - -.dark .vp-doc .home-feature-cards .card-link:hover .card-title { - color: #f4f4f4 !important; -} - -.dark .vp-doc .home-feature-cards .card-description { - color: #a1a1aa; -} - -/* ================================================ - NAVBAR — PLANE (logo + title, search, sign-in, theme, socials) - Doc pages use OSSHeader (not VitePress default .VPNavBar), but reuse VPNav* pieces. -================================================ */ - -/* Remove any inherited top layout offset beneath fixed header */ -.docs-layout { - --vp-layout-top-height: 0px !important; - --docs-divider: #ececec; -} - -html.dark .docs-layout, -[data-theme="dark"] .docs-layout { - --docs-divider: #2a2a2a; -} - -.docs-layout header.wrapper { - border-bottom-color: var(--docs-divider) !important; -} - -/* Navbar utility dividers — fixed height, centered (border-left on wrappers varied with switch vs social icon size) */ -@media (min-width: 1280px) { - .docs-layout header div:has(> .VPNavBarAppearance):has(> .VPNavBarSocialLinks) { - gap: 8px !important; - align-items: center; - } - - .docs-layout header .VPNavBarAppearance, - .docs-layout header .VPNavBarSocialLinks { - display: flex; - align-items: center; - border-left: none !important; - padding-left: 0 !important; - margin-left: 0 !important; - } - - .docs-layout header .VPNavBarAppearance::before, - .docs-layout header .VPNavBarSocialLinks::before { - content: ""; - flex-shrink: 0; - width: 1px; - height: 20px; - margin-right: 8px; - background-color: var(--docs-divider); - } -} - -/* Navbar side borders + corner triangles (tick row is a sibling of header, not inside it) */ -@media (min-width: 768px) { - .docs-layout header.wrapper { - border-left-color: var(--docs-divider) !important; - border-right-color: var(--docs-divider) !important; - } - - .docs-layout header.wrapper + .wrapper { - border-left-color: var(--docs-divider) !important; - border-right-color: var(--docs-divider) !important; - } - - .docs-layout .tick-left::before { - border-left-color: var(--docs-divider) !important; - } - - .docs-layout .tick-right::after { - border-right-color: var(--docs-divider) !important; - } - - html.dark .docs-layout .tick-left::before, - [data-theme="dark"] .docs-layout .tick-left::before { - border-left-color: var(--docs-divider) !important; - } - - html.dark .docs-layout .tick-right::after, - [data-theme="dark"] .docs-layout .tick-right::after { - border-right-color: var(--docs-divider) !important; - } -} - -/* OSSHeader stacks the logo link as flex-col; we want mark + "Plane" in a row. */ -.docs-layout header a[href="/"].flex.flex-col { - flex-direction: row; - align-items: center; - gap: 0.5rem; -} - -.docs-layout header a[href="/"] img.h-4 { - height: 1.3rem; - width: auto; -} - -/* Search control sizing/shape */ -@media (min-width: 768px) { - .docs-layout header .VPNavBarSearchButton { - min-width: min(300px, 28vw); - height: 36px; - padding: 0 12px; - justify-content: flex-start; - gap: 8px; - border-radius: 12px !important; - border: 1px solid #e7e7e7; - background: #fff; - } - - .docs-layout header .VPNavBarSearchButton .text { - flex: 0 1 auto; - text-align: left; - } - - .docs-layout header .VPNavBarSearchButton .keys { - margin-left: auto; - } - - .dark .docs-layout header .VPNavBarSearchButton { - border-color: #323232; - background: #111; - } -} - -/* Sign in — primary CTA (works before/after relocation) */ -.docs-layout header a.VPLink[href*="sign-in"] { - background: #006399 !important; - color: #ffffff !important; - padding: 5px 14px !important; - border-radius: 6px !important; - font-weight: 500 !important; - font-size: 14px !important; - line-height: 1.25 !important; - text-decoration: none !important; - display: inline-flex !important; - align-items: center !important; - margin: 0 !important; - opacity: 1 !important; - transition: - background 0.2s ease, - box-shadow 0.2s ease, - transform 0.2s ease !important; -} - -.docs-layout header a.VPLink[href*="sign-in"].sign-in-relocating { - visibility: hidden !important; -} - -.docs-layout header a.VPLink[href*="sign-in"] .vp-external-link-icon { - display: none !important; -} - -.docs-layout header a.VPLink[href*="sign-in"]:hover { - background: #0078b8 !important; - box-shadow: 0 2px 8px rgba(0, 99, 153, 0.25) !important; - transform: translateY(-1px); - opacity: 1 !important; -} - -.dark .docs-layout header a.VPLink[href*="sign-in"] { - background: #2893cc !important; -} - -.dark .docs-layout header a.VPLink[href*="sign-in"]:hover { - background: #3aa5d4 !important; - box-shadow: 0 2px 8px rgba(40, 147, 204, 0.25) !important; -} - -/* Remove extra desktop strip between navbar and docs content/sidebar. */ -@media (min-width: 768px) { - .docs-layout .content-wrapper { - border-left-color: var(--docs-divider) !important; - border-right-color: var(--docs-divider) !important; - } - - .docs-layout .VPSidebar { - border-right-color: var(--docs-divider) !important; - } - - .docs-layout .VPDoc .aside-container { - border-left-color: var(--docs-divider) !important; - } -} - -@media (min-width: 1024px) { - /* Extend side borders upward so they visually touch the navbar edge. */ - .docs-layout .content-wrapper::before, - .docs-layout .content-wrapper::after { - content: ""; - position: absolute; - top: -5px; - width: 1px; - height: 5px; - background: var(--docs-divider); - pointer-events: none; - } - - .docs-layout .content-wrapper::before { - left: 0; - } - - .docs-layout .content-wrapper::after { - right: 0; - } - - .docs-layout .VPLocalNav.has-sidebar { - display: none !important; - } - - /* Do not zero VPContent padding-top: the OSS header is `lg:fixed`, and the theme - uses padding-top: var(--vp-nav-height) here so the main column starts below the bar. - Removing it makes the center doc sit under the navbar while sidebars are sticky. */ -} - -/* 3-column doc: left nav + right outline share one baseline; body copy sits slightly lower */ -@media (min-width: 1280px) { - .docs-layout .VPSidebar .nav { - /* .VPSidebar already has top padding; extra padding here was stacking—omit so nav links sit 20px higher. */ - padding-top: 0 !important; - } - - /* Theme VPDoc uses `padding: 0 32px` which adds 32px to the *right* of the whole - three-column row — empty gap past the "On this page" rail. */ - .docs-layout .VPDoc.has-aside { - padding-right: 0 !important; - padding-left: 0 !important; - } - - .docs-layout .VPDoc.has-aside .aside .aside-container { - padding-top: 20px !important; - } - - .docs-layout .VPDoc.has-aside .content { - /* Theme default adds large top padding here; use 32px so the body copy sits slightly - lower than both side columns. Kept on `.content` (not `.main`) so the `doc-before` - slot — which hosts the "Copy page" control — shares the H1's vertical origin. */ - padding: 32px 32px 128px !important; - } - - /* Right "On this page" rail: the theme’s `.aside-container` is 224px, so the flex - item `.aside` often shrink-wraps to ~224px. That makes inner `width: 100%` only - fill 224 of the 256px max. Lock the rail to the design width so outline uses it. */ - .docs-layout .VPDoc.has-aside .aside { - flex: 0 0 256px; - width: 256px; - max-width: 256px; - min-width: 0; - padding-left: 0; - box-sizing: border-box; - } - - .docs-layout .VPDoc.has-aside .aside .aside-container { - display: block; - width: 100% !important; - min-width: 0 !important; - max-width: none !important; - padding-left: 4px; - padding-right: 4px; - box-sizing: border-box; - } - - .docs-layout .VPDoc.has-aside .aside .aside-content { - width: 100%; - min-width: 0; - box-sizing: border-box; - } - - .docs-layout .VPDoc.has-aside .aside .VPDocAside { - width: 100%; - min-width: 0; - } - - .docs-layout .VPDoc.has-aside .VPDocAsideOutline, - .docs-layout .VPDoc.has-aside .VPDocAsideOutline .content { - width: 100%; - min-width: 0; - box-sizing: border-box; - } - - .docs-layout .VPDoc.has-aside .VPDocAsideOutline .outline-title { - width: 100%; - min-width: 0; - box-sizing: border-box; - } - - .docs-layout .VPDocAsideOutline .VPDocOutlineItem { - width: 100%; - list-style: none; - box-sizing: border-box; - } - - .docs-layout .VPDocAsideOutline .VPDocOutlineItem.root { - margin: 0; - padding: 0; - } - - .docs-layout .VPDocAsideOutline .VPDocOutlineItem li { - width: 100%; - min-width: 0; - box-sizing: border-box; - } - - /* VPDocOutlineItem uses nowrap + ellipsis; allow long headings to wrap. */ - .docs-layout .VPDocAsideOutline a.outline-link { - white-space: normal; - overflow: visible; - text-overflow: unset; - line-height: 1.45; - padding: 2px 0 4px; - width: 100%; - box-sizing: border-box; - } - - /* Air between sibling items in the right-rail outline. */ - .docs-layout .VPDocAsideOutline .VPDocOutlineItem li + li { - margin-top: 6px; - } - - .docs-layout .VPDocAsideOutline .VPDocOutlineItem li > .VPDocOutlineItem.nested { - margin-top: 4px; - } - - .docs-layout .VPDocOutlineItem.nested { - padding-left: 4px; - padding-right: 4px; - } -} - -/* No right rail (outline empty): collapse the aside, let the main column use that - width, and keep the same 32px inset on both sides as the default left padding. */ -@media (min-width: 1280px) { - .docs-layout - .VPDoc.has-aside:has(.VPDocAsideOutline:not(.has-outline)):not(:has(.VPDocAsideCarbonAds)) - .aside { - display: none !important; - flex: 0 0 0 !important; - width: 0 !important; - min-width: 0 !important; - max-width: 0 !important; - margin: 0 !important; - padding: 0 !important; - overflow: hidden !important; - } - - .docs-layout - .VPDoc.has-aside:has(.VPDocAsideOutline:not(.has-outline)):not(:has(.VPDocAsideCarbonAds)) - .content { - flex: 1 1 auto; - max-width: none !important; - padding-right: 104px !important; - padding-left: 110px !important; - } - - .docs-layout - .VPDoc.has-aside:has(.VPDocAsideOutline:not(.has-outline)):not(:has(.VPDocAsideCarbonAds)) - .content-container { - max-width: none !important; - width: 100%; - margin: 0; - box-sizing: border-box; - } -} - -/* ================================================ - COPY PAGE MENU — placement of components/CopyPageMenu.vue - The control is server-rendered in the `doc-before` slot (first child of - `.VPDoc .content-container`, above
) and, once mounted, teleported into a - `.copy-page-slot` host inserted right after the page H1 inside `.vp-doc`. Both - positions are styled here; visual styles are scoped in the component. - ================================================ */ -.docs-layout .VPDoc .content-container { - position: relative; /* anchor for the pre-teleport position */ -} - -/* < 768px: below the title, left-aligned, in flow */ -@media (max-width: 767px) { - /* Pre-teleport position would sit above the title — keep it hidden to avoid a jump. */ - .docs-layout .VPDoc .content-container > .copy-page { - display: none; - } - - .docs-layout .vp-doc > div > .copy-page-slot { - margin: 14px 0 16px; - } -} - -/* ≥ 768px: on the title row, flush with the right edge of the text column */ -@media (min-width: 768px) { - .docs-layout .VPDoc .content-container > .copy-page, - .docs-layout .vp-doc > div > .copy-page-slot > .copy-page { - position: absolute; /* relative to .content-container / .vp-doc — same top edge */ - top: 2px; /* (h1 line box ~38px − 34px button) / 2 */ - right: 0; - margin: 0; - z-index: 10; /* below --vp-z-index-local-nav (20) and the image lightbox */ - } - - /* Reserve the control's footprint on the H1 only when it actually rendered - (so `copyPage: false` pages keep the full width). */ - .docs-layout .vp-doc > div > h1:has(+ .copy-page-slot > .copy-page), - .docs-layout .VPDoc .content-container > .copy-page ~ .main .vp-doc > div > h1 { - padding-right: 156px; /* ≈ 132px control + 24px gap — re-measure if the label changes */ - } -} - -/* ================================================ - HERO IMAGE STYLES - ================================================ */ - -.vp-doc p:has(> img[src$="#hero"]), -article p:has(> img[src$="#hero"]) { - max-width: 841px; - padding: 36px 56px 0px 56px; - background: #f1f3f3; - border-radius: 12px; - box-sizing: border-box; - overflow: hidden; -} - -.vp-doc img[src$="#hero"], -article img[src$="#hero"] { - width: 100%; - height: auto; - display: block; - margin: 0; - border-radius: 8px 8px 0px 0px; - border-width: 1px 1px 0px 1px; - border-style: solid; - border-color: #eaebeb; - object-fit: cover; - box-shadow: - 0px 2px 4px -1px rgba(41, 47, 61, 0.04), - 0px 4px 6px -1px rgba(41, 47, 61, 0.05); -} - -.vp-doc p:has(> img[src$="#hero-tl"]), -article p:has(> img[src$="#hero-tl"]) { - max-width: 841px; - padding: 36px 0px 0px 56px; - background: #f1f3f3; - border-radius: 12px; - box-sizing: border-box; - overflow: hidden; -} - -.vp-doc img[src$="#hero-tl"], -article img[src$="#hero-tl"] { - width: 100%; - height: auto; - display: block; - margin: 0; - border-radius: 8px 0px 0px 0px; - border-width: 1px 0px 0px 1px; - border-style: solid; - border-color: #eaebeb; - object-fit: cover; - box-shadow: - 0px 2px 4px -1px rgba(41, 47, 61, 0.04), - 0px 4px 6px -1px rgba(41, 47, 61, 0.05); -} - -.vp-doc p:has(> img[src$="#hero-tr"]), -article p:has(> img[src$="#hero-tr"]) { - max-width: 841px; - padding: 36px 56px 0px 0px; - background: #f1f3f3; - border-radius: 12px; - box-sizing: border-box; - overflow: hidden; -} - -.vp-doc img[src$="#hero-tr"], -article img[src$="#hero-tr"] { - width: 100%; - height: auto; - display: block; - margin: 0; - border-radius: 0px 8px 0px 0px; - border-width: 1px 1px 0px 0px; - border-style: solid; - border-color: #eaebeb; - object-fit: cover; - box-shadow: - 0px 2px 4px -1px rgba(41, 47, 61, 0.04), - 0px 4px 6px -1px rgba(41, 47, 61, 0.05); -} - -.vp-doc p:has(> img[src$="#hero-bl"]), -article p:has(> img[src$="#hero-bl"]) { - max-width: 841px; - padding: 0px 0px 36px 56px; - background: #f1f3f3; - border-radius: 12px; - box-sizing: border-box; - overflow: hidden; -} - -.vp-doc img[src$="#hero-bl"], -article img[src$="#hero-bl"] { - width: 100%; - height: auto; - display: block; - margin: 0; - border-radius: 0px 0px 0px 8px; - border-width: 0px 0px 1px 1px; - border-style: solid; - border-color: #eaebeb; - object-fit: cover; - box-shadow: - 0px 2px 4px -1px rgba(41, 47, 61, 0.04), - 0px 4px 6px -1px rgba(41, 47, 61, 0.05); -} - -.vp-doc p:has(> img[src$="#hero-br"]), -article p:has(> img[src$="#hero-br"]) { - max-width: 841px; - padding: 0px 56px 36px 0px; - background: #f1f3f3; - border-radius: 12px; - box-sizing: border-box; - overflow: hidden; -} - -.vp-doc img[src$="#hero-br"], -article img[src$="#hero-br"] { - width: 100%; - height: auto; - display: block; - margin: 0; - border-radius: 0px 0px 8px 0px; - border-width: 0px 1px 1px 0px; - border-style: solid; - border-color: #eaebeb; - object-fit: cover; - box-shadow: - 0px 2px 4px -1px rgba(41, 47, 61, 0.04), - 0px 4px 6px -1px rgba(41, 47, 61, 0.05); -} - -/* ================================================ - MOBILE IMAGE LAYOUT - ================================================ */ - -.mobile-img-container { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - flex-wrap: wrap; -} - -.mobile-img-box { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - max-width: 25rem; - min-width: 15rem; - text-align: center; - margin: 10px; -} - -/* ================================================ - HOMEPAGE FEATURE ICONS - DARK MODE - ================================================ */ - -/* Feature card icons use currentColor in SVG, but since they're - loaded as tags, currentColor defaults to black. This filter - inverts them for visibility in dark mode. */ -.dark .VPFeature .VPImage { - filter: invert(1) hue-rotate(180deg); -} - -.dark .VPFeatures .VPFeature .icon img { - filter: invert(1) hue-rotate(180deg); -} - -/* ================================================ - MEDIUM ZOOM - IMAGE LIGHTBOX - ================================================ */ - -.vp-doc img { - cursor: zoom-in; -} - -.medium-zoom-overlay { - z-index: 999; -} - -.medium-zoom-image--opened { - z-index: 1000; -} diff --git a/docs/.vitepress/tsconfig.json b/docs/.vitepress/tsconfig.json new file mode 100644 index 00000000..a50764fd --- /dev/null +++ b/docs/.vitepress/tsconfig.json @@ -0,0 +1,50 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "jsx": "preserve", + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "skipLibCheck": true, + "ignoreDeprecations": "6.0", + "allowArbitraryExtensions": true, + "noEmit": true, + "lib": ["ESNext", "DOM"], + "types": ["vitepress/client", "node", "vue"], + "paths": { + "@voidzero-dev/vitepress-theme": ["./theme/plane/types/voidzero-theme.ts"], + "@voidzero-dev/vitepress-theme/src/components/vitepress-default/Layout.vue": [ + "../../node_modules/@voidzero-dev/vitepress-theme/src/components/vitepress-default/Layout.vue" + ], + "@voidzero-dev/vitepress-theme/src/components/oss/Header.vue": [ + "../../node_modules/@voidzero-dev/vitepress-theme/src/components/oss/Header.vue" + ], + "@voidzero-dev/vitepress-theme/src/components/oss/TopBanner.vue": [ + "../../node_modules/@voidzero-dev/vitepress-theme/src/components/oss/TopBanner.vue" + ], + "@voidzero-dev/vitepress-theme/src/types/theme-context": [ + "../../node_modules/@voidzero-dev/vitepress-theme/src/types/theme-context.ts" + ], + "@vp-default/*": [ + "../../node_modules/@voidzero-dev/vitepress-theme/src/components/vitepress-default/*" + ], + "@vp-composables/*": [ + "../../node_modules/@voidzero-dev/vitepress-theme/src/composables/vitepress-default/*" + ], + "@vp-support/*": [ + "../../node_modules/@voidzero-dev/vitepress-theme/src/support/vitepress-default/*" + ], + "@components/*": ["../../node_modules/@voidzero-dev/vitepress-theme/src/components/*"] + } + }, + "include": [ + "./config.ts", + "./env.d.ts", + "./theme/**/*.ts", + "./theme/**/*.vue", + "./theme/**/*.d.ts" + ] +} diff --git a/docs/.vitepress/types/modules.d.ts b/docs/.vitepress/types/modules.d.ts deleted file mode 100644 index 32843240..00000000 --- a/docs/.vitepress/types/modules.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -declare module "*.vue" { - import type { DefineComponent } from "vue"; - - const component: DefineComponent, Record, unknown>; - export default component; -} - -declare module "vitepress-plugin-tabs/client" { - export function enhanceAppWithTabs(app: unknown): void; -} diff --git a/docs/index.md b/docs/index.md index ca6d8d73..4256910b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,6 +2,7 @@ layout: doc title: Plane Docs description: Everything you need to learn Plane, manage projects, and build powerful workflows. +aside: false prev: false next: false copyPage: false diff --git a/package.json b/package.json index 209c71f5..0f6c5a21 100644 --- a/package.json +++ b/package.json @@ -15,22 +15,24 @@ "build": "vitepress build docs", "preview": "vitepress preview docs", "fix:format": "oxfmt --write .", - "check:format": "oxfmt --check ." + "check:format": "oxfmt --check .", + "check:types": "node docs/.vitepress/theme/plane/scripts/check-vue-types.mjs docs/.vitepress/tsconfig.json", + "check:theme-sync": "node docs/.vitepress/theme/plane/scripts/check-theme-sync.mjs --sibling makeplane/developer-docs" }, "dependencies": { - "@tailwindcss/vite": "^4.2.1", - "@voidzero-dev/vitepress-theme": "^4.8.4", "lucide-vue-next": "^0.577.0", - "medium-zoom": "^1.1.0", - "tailwindcss": "^4.2.1", - "vitepress": "^1.6.3", - "vitepress-plugin-tabs": "^0.8.0", - "vue": "^3.5.13" + "medium-zoom": "^1.1.0" }, "devDependencies": { - "@types/node": "^25.6.0", + "@types/node": "^25.9.5", + "@voidzero-dev/vitepress-theme": "^4.8.4", "oxfmt": "^0.36.0", - "vitepress-plugin-llms": "^1.13.1" + "typescript": "^6.0.3", + "vitepress": "2.0.0-alpha.16", + "vitepress-plugin-llms": "^1.13.1", + "vitepress-plugin-tabs": "^0.8.0", + "vue": "^3.5.41", + "vue-tsc": "^3.3.10" }, "engines": { "node": ">=24.0.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c4ea8ffd..480b2776 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,329 +5,226 @@ settings: excludeLinksFromLockfile: false overrides: - esbuild: ^0.25.0 + rollup: 4.59.0 + lodash-es: 4.18.1 + esbuild: 0.25.0 vite: 6.4.3 - postcss: ^8.5.10 + postcss: 8.5.15 js-yaml@<3.15.0: 3.15.0 importers: .: dependencies: - '@tailwindcss/vite': - specifier: ^4.2.1 - version: 4.2.1(vite@6.4.3(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1)) - '@voidzero-dev/vitepress-theme': - specifier: ^4.8.4 - version: 4.8.4(focus-trap@7.8.0)(vite@6.4.3(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1))(vitepress@1.6.4(@algolia/client-search@5.49.2)(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(search-insights@2.17.3))(vue@3.5.30) lucide-vue-next: specifier: ^0.577.0 - version: 0.577.0(vue@3.5.30) + version: 0.577.0(vue@3.5.41(typescript@6.0.3)) medium-zoom: specifier: ^1.1.0 version: 1.1.0 - tailwindcss: - specifier: ^4.2.1 - version: 4.2.1 - vitepress: - specifier: ^1.6.3 - version: 1.6.4(@algolia/client-search@5.49.2)(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(search-insights@2.17.3) - vitepress-plugin-tabs: - specifier: ^0.8.0 - version: 0.8.0(vitepress@1.6.4(@algolia/client-search@5.49.2)(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(search-insights@2.17.3))(vue@3.5.30) - vue: - specifier: ^3.5.13 - version: 3.5.30 devDependencies: '@types/node': - specifier: ^25.6.0 - version: 25.6.0 + specifier: ^25.9.5 + version: 25.9.5 + '@voidzero-dev/vitepress-theme': + specifier: ^4.8.4 + version: 4.8.4(focus-trap@7.8.0)(vite@6.4.3(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1))(vitepress@2.0.0-alpha.16(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(typescript@6.0.3))(vue@3.5.41(typescript@6.0.3)) oxfmt: specifier: ^0.36.0 version: 0.36.0 + typescript: + specifier: ^6.0.3 + version: 6.0.3 + vitepress: + specifier: 2.0.0-alpha.16 + version: 2.0.0-alpha.16(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(typescript@6.0.3) vitepress-plugin-llms: specifier: ^1.13.1 version: 1.13.1 + vitepress-plugin-tabs: + specifier: ^0.8.0 + version: 0.8.0(vitepress@2.0.0-alpha.16(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(typescript@6.0.3))(vue@3.5.41(typescript@6.0.3)) + vue: + specifier: ^3.5.41 + version: 3.5.41(typescript@6.0.3) + vue-tsc: + specifier: ^3.3.10 + version: 3.3.10(typescript@6.0.3) packages: - '@algolia/abtesting@1.15.2': - resolution: {integrity: sha512-rF7vRVE61E0QORw8e2NNdnttcl3jmFMWS9B4hhdga12COe+lMa26bQLfcBn/Nbp9/AF/8gXdaRCPsVns3CnjsA==} - engines: {node: '>= 14.0.0'} - - '@algolia/autocomplete-core@1.17.7': - resolution: {integrity: sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==} - - '@algolia/autocomplete-plugin-algolia-insights@1.17.7': - resolution: {integrity: sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==} - peerDependencies: - search-insights: '>= 1 < 3' - - '@algolia/autocomplete-preset-algolia@1.17.7': - resolution: {integrity: sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==} - peerDependencies: - '@algolia/client-search': '>= 4.9.1 < 6' - algoliasearch: '>= 4.9.1 < 6' - - '@algolia/autocomplete-shared@1.17.7': - resolution: {integrity: sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==} - peerDependencies: - '@algolia/client-search': '>= 4.9.1 < 6' - algoliasearch: '>= 4.9.1 < 6' - - '@algolia/client-abtesting@5.49.2': - resolution: {integrity: sha512-XyvKCm0RRmovMI/ChaAVjTwpZhXdbgt3iZofK914HeEHLqD1MUFFVLz7M0+Ou7F56UkHXwRbpHwb9xBDNopprQ==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-analytics@5.49.2': - resolution: {integrity: sha512-jq/3qvtmj3NijZlhq7A1B0Cl41GfaBpjJxcwukGsYds6aMSCWrEAJ9pUqw/C9B3hAmILYKl7Ljz3N9SFvekD3Q==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-common@5.49.2': - resolution: {integrity: sha512-bn0biLequn3epobCfjUqCxlIlurLr4RHu7RaE4trgN+RDcUq6HCVC3/yqq1hwbNYpVtulnTOJzcaxYlSr1fnuw==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-insights@5.49.2': - resolution: {integrity: sha512-z14wfFs1T3eeYbCArC8pvntAWsPo9f6hnUGoj8IoRUJTwgJiiySECkm8bmmV47/x0oGHfsVn3kBdjMX0yq0sNA==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-personalization@5.49.2': - resolution: {integrity: sha512-GpRf7yuuAX93+Qt0JGEJZwgtL0MFdjFO9n7dn8s2pA9mTjzl0Sc5+uTk1VPbIAuf7xhCP9Mve+URGb6J+EYxgA==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-query-suggestions@5.49.2': - resolution: {integrity: sha512-HZwApmNkp0DiAjZcLYdQLddcG4Agb88OkojiAHGgcm5DVXobT5uSZ9lmyrbw/tmQBJwgu2CNw4zTyXoIB7YbPA==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-search@5.49.2': - resolution: {integrity: sha512-y1IOpG6OSmTpGg/CT0YBb/EAhR2nsC18QWp9Jy8HO9iGySpcwaTvs5kHa17daP3BMTwWyaX9/1tDTDQshZzXdg==} - engines: {node: '>= 14.0.0'} - - '@algolia/ingestion@1.49.2': - resolution: {integrity: sha512-YYJRjaZ2bqk923HxE4um7j/Cm3/xoSkF2HC2ZweOF8cXL3sqnlndSUYmCaxHFjNPWLaSHk2IfssX6J/tdKTULw==} - engines: {node: '>= 14.0.0'} - - '@algolia/monitoring@1.49.2': - resolution: {integrity: sha512-9WgH+Dha39EQQyGKCHlGYnxW/7W19DIrEbCEbnzwAMpGAv1yTWCHMPXHxYa+LcL3eCp2V/5idD1zHNlIKmHRHg==} - engines: {node: '>= 14.0.0'} - - '@algolia/recommend@5.49.2': - resolution: {integrity: sha512-K7Gp5u+JtVYgaVpBxF5rGiM+Ia8SsMdcAJMTDV93rwh00DKNllC19o1g+PwrDjDvyXNrnTEbofzbTs2GLfFyKA==} - engines: {node: '>= 14.0.0'} - - '@algolia/requester-browser-xhr@5.49.2': - resolution: {integrity: sha512-3UhYCcWX6fbtN8ABcxZlhaQEwXFh3CsFtARyyadQShHMPe3mJV9Wel4FpJTa+seugRkbezFz0tt6aPTZSYTBuA==} - engines: {node: '>= 14.0.0'} - - '@algolia/requester-fetch@5.49.2': - resolution: {integrity: sha512-G94VKSGbsr+WjsDDOBe5QDQ82QYgxvpxRGJfCHZBnYKYsy/jv9qGIDb93biza+LJWizQBUtDj7bZzp3QZyzhPQ==} - engines: {node: '>= 14.0.0'} - - '@algolia/requester-node-http@5.49.2': - resolution: {integrity: sha512-UuihBGHafG/ENsrcTGAn5rsOffrCIRuHMOsD85fZGLEY92ate+BMTUqxz60dv5zerh8ZumN4bRm8eW2z9L11jA==} - engines: {node: '>= 14.0.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} - '@babel/parser@7.29.0': - resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + '@babel/parser@7.29.8': + resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} - '@docsearch/css@3.8.2': - resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==} - '@docsearch/css@4.6.2': resolution: {integrity: sha512-fH/cn8BjEEdM2nJdjNMHIvOVYupG6AIDtFVDgIZrNzdCSj4KXr9kd+hsehqsNGYjpUjObeKYKvgy/IwCb1jZYQ==} - '@docsearch/js@3.8.2': - resolution: {integrity: sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==} - '@docsearch/js@4.6.2': resolution: {integrity: sha512-qj1yoxl3y4GKoK7+VM6fq/rQqPnvUmg3IKzJ9x0VzN14QVzdB/SG/J6VfV1BWT5RcPUFxIcVwoY1fwHM2fSRRw==} - '@docsearch/react@3.8.2': - resolution: {integrity: sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==} - peerDependencies: - '@types/react': '>= 16.8.0 < 19.0.0' - react: '>= 16.8.0 < 19.0.0' - react-dom: '>= 16.8.0 < 19.0.0' - search-insights: '>= 1 < 3' - peerDependenciesMeta: - '@types/react': - optional: true - react: - optional: true - react-dom: - optional: true - search-insights: - optional: true - '@docsearch/sidepanel-js@4.6.2': resolution: {integrity: sha512-Pni85AP/GwRj7fFg8cBJp0U04tzbueBvWSd3gysgnOsVnQVSZwSYncfErUScLE1CAtR+qocPDFjmYR9AMRNJtQ==} - '@esbuild/aix-ppc64@0.25.12': - resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + '@esbuild/aix-ppc64@0.25.0': + resolution: {integrity: sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.12': - resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + '@esbuild/android-arm64@0.25.0': + resolution: {integrity: sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.12': - resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + '@esbuild/android-arm@0.25.0': + resolution: {integrity: sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.12': - resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + '@esbuild/android-x64@0.25.0': + resolution: {integrity: sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.12': - resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + '@esbuild/darwin-arm64@0.25.0': + resolution: {integrity: sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.12': - resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + '@esbuild/darwin-x64@0.25.0': + resolution: {integrity: sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.12': - resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + '@esbuild/freebsd-arm64@0.25.0': + resolution: {integrity: sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.12': - resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + '@esbuild/freebsd-x64@0.25.0': + resolution: {integrity: sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.12': - resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + '@esbuild/linux-arm64@0.25.0': + resolution: {integrity: sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.12': - resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + '@esbuild/linux-arm@0.25.0': + resolution: {integrity: sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.12': - resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + '@esbuild/linux-ia32@0.25.0': + resolution: {integrity: sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.12': - resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + '@esbuild/linux-loong64@0.25.0': + resolution: {integrity: sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.12': - resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + '@esbuild/linux-mips64el@0.25.0': + resolution: {integrity: sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.12': - resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + '@esbuild/linux-ppc64@0.25.0': + resolution: {integrity: sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.12': - resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + '@esbuild/linux-riscv64@0.25.0': + resolution: {integrity: sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.12': - resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + '@esbuild/linux-s390x@0.25.0': + resolution: {integrity: sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.12': - resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + '@esbuild/linux-x64@0.25.0': + resolution: {integrity: sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.12': - resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + '@esbuild/netbsd-arm64@0.25.0': + resolution: {integrity: sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.12': - resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + '@esbuild/netbsd-x64@0.25.0': + resolution: {integrity: sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.12': - resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + '@esbuild/openbsd-arm64@0.25.0': + resolution: {integrity: sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.12': - resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + '@esbuild/openbsd-x64@0.25.0': + resolution: {integrity: sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.12': - resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.25.12': - resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + '@esbuild/sunos-x64@0.25.0': + resolution: {integrity: sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.12': - resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + '@esbuild/win32-arm64@0.25.0': + resolution: {integrity: sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.12': - resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + '@esbuild/win32-ia32@0.25.0': + resolution: {integrity: sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.12': - resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + '@esbuild/win32-x64@0.25.0': + resolution: {integrity: sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -502,6 +399,9 @@ packages: '@rive-app/canvas-lite@2.37.3': resolution: {integrity: sha512-lw4M13Yu1VZSlys/4yW3O4IGMXqSsZCdwPTEkspR9PkphJW+WWjxT99F946eXAVV6aNg5gE3XuW3PQaoDciiYg==} + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + '@rollup/rollup-android-arm-eabi@4.59.0': resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} cpu: [arm] @@ -640,26 +540,26 @@ packages: cpu: [x64] os: [win32] - '@shikijs/core@2.5.0': - resolution: {integrity: sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==} + '@shikijs/core@3.23.0': + resolution: {integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==} - '@shikijs/engine-javascript@2.5.0': - resolution: {integrity: sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==} + '@shikijs/engine-javascript@3.23.0': + resolution: {integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==} - '@shikijs/engine-oniguruma@2.5.0': - resolution: {integrity: sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==} + '@shikijs/engine-oniguruma@3.23.0': + resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} - '@shikijs/langs@2.5.0': - resolution: {integrity: sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==} + '@shikijs/langs@3.23.0': + resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} - '@shikijs/themes@2.5.0': - resolution: {integrity: sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==} + '@shikijs/themes@3.23.0': + resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} - '@shikijs/transformers@2.5.0': - resolution: {integrity: sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==} + '@shikijs/transformers@3.23.0': + resolution: {integrity: sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==} - '@shikijs/types@2.5.0': - resolution: {integrity: sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==} + '@shikijs/types@3.23.0': + resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} @@ -798,8 +698,8 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@25.6.0': - resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} + '@types/node@25.9.5': + resolution: {integrity: sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg==} '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -811,9 +711,9 @@ packages: resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} deprecated: Potential CWE-502 - Update to 1.3.1 or higher - '@vitejs/plugin-vue@5.2.4': - resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} - engines: {node: ^18.0.0 || >=20.0.0} + '@vitejs/plugin-vue@6.0.8': + resolution: {integrity: sha512-0ZjgOg7oO6farnNGup7yvoM/YXZV84OZxHAwtflItNa/6zzQyVb5LNxyea3FEKEX2XlagIKzrlH7wwxkKgtiew==} + engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: 6.4.3 vue: ^3.2.25 @@ -824,93 +724,62 @@ packages: vitepress: ^2.0.0-alpha.16 vue: ^3.5.0 - '@vue/compiler-core@3.5.30': - resolution: {integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==} + '@volar/language-core@2.4.28': + resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} - '@vue/compiler-dom@3.5.30': - resolution: {integrity: sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==} + '@volar/source-map@2.4.28': + resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} - '@vue/compiler-sfc@3.5.30': - resolution: {integrity: sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==} + '@volar/typescript@2.4.28': + resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} - '@vue/compiler-ssr@3.5.30': - resolution: {integrity: sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==} + '@vue/compiler-core@3.5.41': + resolution: {integrity: sha512-q0Xtv/F9w2YO/7htQhtiL+Ev2WCJbe5N2hc+XfgyKkEKqWpSxknmT8QOuGdEKNdjPq0c3F7rNpFkTo3Kfrm7pg==} - '@vue/devtools-api@7.7.9': - resolution: {integrity: sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==} + '@vue/compiler-dom@3.5.41': + resolution: {integrity: sha512-oKacVfNglLvGjnS6BXOlGL7EyG2h8X03pqXCjzotRZUaXGjbrTJUnVAQjrCqUnS+lyu31nwQjZY/d817GmCnfw==} - '@vue/devtools-kit@7.7.9': - resolution: {integrity: sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==} + '@vue/compiler-sfc@3.5.41': + resolution: {integrity: sha512-XJhip7R2wy6vX3knCxdZN4KracFaZUef58s1KYewqluedHIJaPIVfXoYT7MF1F8nCvv6k8bWWxDC8opMkg1VTQ==} - '@vue/devtools-shared@7.7.9': - resolution: {integrity: sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==} + '@vue/compiler-ssr@3.5.41': + resolution: {integrity: sha512-U3v5OejKEGqOI0Wy0+Sz7hGuIFZHA4LSXzrNM3IMIeDyJEBBfTpX26n3SDgToRpP2bLc9FfI2j/kSgcJ8Emq5A==} - '@vue/reactivity@3.5.30': - resolution: {integrity: sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==} + '@vue/devtools-api@8.2.1': + resolution: {integrity: sha512-6u4vXBlIBAC1wMplIZgpyPn7uh/s4Bf6F5bMzvLv+EdJ0aHs/+4B7Ygv864EStQSjRbsRzTko/kUG1A1IejQ3A==} - '@vue/runtime-core@3.5.30': - resolution: {integrity: sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==} + '@vue/devtools-kit@8.2.1': + resolution: {integrity: sha512-FIGIuq3AWReEpbAHY/cRGeHDfI0qOb8OCQ3YjbEAX04uaxIDbGc9rhkbVcG7rnfHPXE3RsU5KrWOu9V/okd8AQ==} - '@vue/runtime-dom@3.5.30': - resolution: {integrity: sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==} + '@vue/devtools-shared@8.2.1': + resolution: {integrity: sha512-Fkac7lUdGReh6pVOi3AYPRGe82LQqRmAfThW7RRligOAP0ZA/Z1z9XLHDM9dv34pV2HRc79DK8uKPeG2fLnA/g==} - '@vue/server-renderer@3.5.30': - resolution: {integrity: sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==} - peerDependencies: - vue: 3.5.30 + '@vue/language-core@3.3.10': + resolution: {integrity: sha512-CR7ByBbgPHqhxrioKPOcZBqttaozzLNwtkCzXQ+uF8gLPHnUe03srPnGpdtHD3zp+bq5iyVkZ1WNx7W564RPwg==} + + '@vue/reactivity@3.5.41': + resolution: {integrity: sha512-rznsqKM0np0x18EjzF8x88MpEhdNsffbvFbckLL5+oUKz1BxAImEmO7J1ArRYSyo6aQaVoBDp7jEkT91OOxydA==} + + '@vue/runtime-core@3.5.41': + resolution: {integrity: sha512-Vcry58hiAKwGen9Z1jUZE0feFsNArPCMOImYI8el48A9Idf6DuQYD0U05zZIF2Iad1hGhPSvcbBbAOhNr55fhg==} + + '@vue/runtime-dom@3.5.41': + resolution: {integrity: sha512-3vVBahVBS9+U6cmXBLyb8nE6/yYo4J/CGI9eVFs3KiMc0YHuudwKyShTD65jtJy/L9PUUxNAFu4cj4LiJ0UFbw==} + + '@vue/server-renderer@3.5.41': + resolution: {integrity: sha512-n6hx/pNFfbD6SuyeuMVkvqox8bwf/ET9JlA/kAz/imw8sw++wkqKe2mHX5KutjPpbKE4Z56yTHszoOjGMI9igQ==} '@vue/shared@3.5.30': resolution: {integrity: sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==} - '@vueuse/core@12.8.2': - resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==} + '@vue/shared@3.5.41': + resolution: {integrity: sha512-IOnwSCma8j+9xJT6b8H0dEYidC80NsYmNMlZxRsukYcSoGaDBohog5hDxzeUXdFeGWFA++vWvxqOmrr96VlqMA==} '@vueuse/core@14.2.1': resolution: {integrity: sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ==} peerDependencies: vue: ^3.5.0 - '@vueuse/integrations@12.8.2': - resolution: {integrity: sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==} - peerDependencies: - async-validator: ^4 - axios: ^1 - change-case: ^5 - drauu: ^0.4 - focus-trap: ^7 - fuse.js: ^7 - idb-keyval: ^6 - jwt-decode: ^4 - nprogress: ^0.2 - qrcode: ^1.5 - sortablejs: ^1 - universal-cookie: ^7 - 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/integrations@14.2.1': resolution: {integrity: sha512-2LIUpBi/67PoXJGqSDQUF0pgQWpNHh7beiA+KG2AbybcNm+pTGWT6oPGlBgUoDWmYwfeQqM/uzOHqcILpKL7nA==} peerDependencies: @@ -953,23 +822,16 @@ packages: universal-cookie: optional: true - '@vueuse/metadata@12.8.2': - resolution: {integrity: sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==} - '@vueuse/metadata@14.2.1': resolution: {integrity: sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw==} - '@vueuse/shared@12.8.2': - resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==} - '@vueuse/shared@14.2.1': resolution: {integrity: sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw==} peerDependencies: vue: ^3.5.0 - algoliasearch@5.49.2: - resolution: {integrity: sha512-1K0wtDaRONwfhL4h8bbJ9qTjmY6rhGgRvvagXkMBsAOMNr+3Q2SffHECh9DIuNVrMA1JwA0zCwhyepgBZVakng==} - engines: {node: '>= 14.0.0'} + alien-signals@3.2.1: + resolution: {integrity: sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -1029,10 +891,6 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - copy-anything@4.0.5: - resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==} - engines: {node: '>=18'} - cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -1067,9 +925,6 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - emoji-regex-xs@1.0.0: - resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} - emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1085,8 +940,8 @@ packages: resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} engines: {node: '>=0.12'} - esbuild@0.25.12: - resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + esbuild@0.25.0: + resolution: {integrity: sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==} engines: {node: '>=18'} hasBin: true @@ -1172,10 +1027,6 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} - is-what@5.5.0: - resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==} - engines: {node: '>=18'} - jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -1389,39 +1240,45 @@ packages: minisearch@7.2.0: resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} - mitt@3.0.1: - resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.12: - resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + nanoid@3.3.18: + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true ohash@2.0.11: resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} - oniguruma-to-es@3.1.1: - resolution: {integrity: sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==} + 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.36.0: resolution: {integrity: sha512-/ejJ+KoSW6J9bcNT9a9UtJSJNWhJ3yOLSBLbkoFHJs/8CZjmaZVZAJe4YgO1KMJlKpNQasrn/G9JQUEZI3p0EQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - perfect-debounce@1.0.0: - resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + 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.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} postcss-selector-parser@6.0.10: @@ -1432,9 +1289,6 @@ packages: resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} - preact@10.29.0: - resolution: {integrity: sha512-wSAGyk2bYR1c7t3SZ3jHcM6xy0lcBcDel6lODcs9ME6Th++Dx2KU+6D3HD8wMMKGA8Wpw7OMd3/4RGzYRpzwRg==} - pretty-bytes@7.1.0: resolution: {integrity: sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw==} engines: {node: '>=20'} @@ -1476,23 +1330,17 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - rfdc@1.4.1: - resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - rollup@4.59.0: resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - search-insights@2.17.3: - resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==} - section-matter@1.0.0: resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} engines: {node: '>=4'} - shiki@2.5.0: - resolution: {integrity: sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==} + shiki@3.23.0: + resolution: {integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==} source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} @@ -1501,10 +1349,6 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - speakingurl@14.0.1: - resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} - engines: {node: '>=0.10.0'} - sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -1523,12 +1367,8 @@ packages: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} engines: {node: '>=0.10.0'} - superjson@2.2.6: - resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==} - engines: {node: '>=16'} - - tabbable@6.4.0: - resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} + tabbable@6.5.0: + resolution: {integrity: sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA==} tailwindcss@4.2.1: resolution: {integrity: sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==} @@ -1537,8 +1377,8 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} - tinyglobby@0.2.16: - resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} tinypool@2.1.0: @@ -1557,11 +1397,16 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - undici-types@7.19.2: - resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + undici-types@7.24.6: + resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -1643,18 +1488,24 @@ packages: vitepress: ^1.0.0 vue: ^3.5.0 - vitepress@1.6.4: - resolution: {integrity: sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==} + vitepress@2.0.0-alpha.16: + resolution: {integrity: sha512-w1nwsefDVIsje7BZr2tsKxkZutDGjG0YoQ2yxO7+a9tvYVqfljYbwj5LMYkPy8Tb7YbPwa22HtIhk62jbrvuEQ==} hasBin: true peerDependencies: markdown-it-mathjax3: ^4 - postcss: ^8.5.10 + oxc-minify: '*' + postcss: 8.5.15 peerDependenciesMeta: markdown-it-mathjax3: optional: true + oxc-minify: + optional: true postcss: optional: true + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + vue-demi@0.14.10: resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} engines: {node: '>=12'} @@ -1666,8 +1517,14 @@ packages: '@vue/composition-api': optional: true - vue@3.5.30: - resolution: {integrity: sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==} + vue-tsc@3.3.10: + resolution: {integrity: sha512-YaDVxcW+CGtaOt3pZahMG5jYPx0hsUTxyEoPOTSMebcGUXP9lIBabQ14vfKMORb2CqqK5CxsNo/d1d+4IQwiKg==} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + + vue@3.5.41: + resolution: {integrity: sha512-2laE0p+aK+/AOPG/XL/WepOs/GlK755LJ1XECi9kDUrz1FKNw8rb2Xzlw9JS1rqEV55nb0ttsKxVlTCcd+R5cg==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -1695,237 +1552,98 @@ packages: snapshots: - '@algolia/abtesting@1.15.2': - dependencies: - '@algolia/client-common': 5.49.2 - '@algolia/requester-browser-xhr': 5.49.2 - '@algolia/requester-fetch': 5.49.2 - '@algolia/requester-node-http': 5.49.2 - - '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.49.2)(algoliasearch@5.49.2)(search-insights@2.17.3)': - dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.49.2)(algoliasearch@5.49.2)(search-insights@2.17.3) - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.49.2)(algoliasearch@5.49.2) - transitivePeerDependencies: - - '@algolia/client-search' - - algoliasearch - - search-insights - - '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.49.2)(algoliasearch@5.49.2)(search-insights@2.17.3)': - dependencies: - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.49.2)(algoliasearch@5.49.2) - search-insights: 2.17.3 - transitivePeerDependencies: - - '@algolia/client-search' - - algoliasearch - - '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.49.2)(algoliasearch@5.49.2)': - dependencies: - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.49.2)(algoliasearch@5.49.2) - '@algolia/client-search': 5.49.2 - algoliasearch: 5.49.2 - - '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.49.2)(algoliasearch@5.49.2)': - dependencies: - '@algolia/client-search': 5.49.2 - algoliasearch: 5.49.2 - - '@algolia/client-abtesting@5.49.2': - dependencies: - '@algolia/client-common': 5.49.2 - '@algolia/requester-browser-xhr': 5.49.2 - '@algolia/requester-fetch': 5.49.2 - '@algolia/requester-node-http': 5.49.2 - - '@algolia/client-analytics@5.49.2': - dependencies: - '@algolia/client-common': 5.49.2 - '@algolia/requester-browser-xhr': 5.49.2 - '@algolia/requester-fetch': 5.49.2 - '@algolia/requester-node-http': 5.49.2 - - '@algolia/client-common@5.49.2': {} - - '@algolia/client-insights@5.49.2': - dependencies: - '@algolia/client-common': 5.49.2 - '@algolia/requester-browser-xhr': 5.49.2 - '@algolia/requester-fetch': 5.49.2 - '@algolia/requester-node-http': 5.49.2 - - '@algolia/client-personalization@5.49.2': - dependencies: - '@algolia/client-common': 5.49.2 - '@algolia/requester-browser-xhr': 5.49.2 - '@algolia/requester-fetch': 5.49.2 - '@algolia/requester-node-http': 5.49.2 - - '@algolia/client-query-suggestions@5.49.2': - dependencies: - '@algolia/client-common': 5.49.2 - '@algolia/requester-browser-xhr': 5.49.2 - '@algolia/requester-fetch': 5.49.2 - '@algolia/requester-node-http': 5.49.2 - - '@algolia/client-search@5.49.2': - dependencies: - '@algolia/client-common': 5.49.2 - '@algolia/requester-browser-xhr': 5.49.2 - '@algolia/requester-fetch': 5.49.2 - '@algolia/requester-node-http': 5.49.2 - - '@algolia/ingestion@1.49.2': - dependencies: - '@algolia/client-common': 5.49.2 - '@algolia/requester-browser-xhr': 5.49.2 - '@algolia/requester-fetch': 5.49.2 - '@algolia/requester-node-http': 5.49.2 - - '@algolia/monitoring@1.49.2': - dependencies: - '@algolia/client-common': 5.49.2 - '@algolia/requester-browser-xhr': 5.49.2 - '@algolia/requester-fetch': 5.49.2 - '@algolia/requester-node-http': 5.49.2 - - '@algolia/recommend@5.49.2': - dependencies: - '@algolia/client-common': 5.49.2 - '@algolia/requester-browser-xhr': 5.49.2 - '@algolia/requester-fetch': 5.49.2 - '@algolia/requester-node-http': 5.49.2 + '@babel/helper-string-parser@7.29.7': {} - '@algolia/requester-browser-xhr@5.49.2': - dependencies: - '@algolia/client-common': 5.49.2 + '@babel/helper-validator-identifier@7.29.7': {} - '@algolia/requester-fetch@5.49.2': + '@babel/parser@7.29.8': dependencies: - '@algolia/client-common': 5.49.2 + '@babel/types': 7.29.8 - '@algolia/requester-node-http@5.49.2': + '@babel/types@7.29.8': dependencies: - '@algolia/client-common': 5.49.2 - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.28.5': {} - - '@babel/parser@7.29.0': - dependencies: - '@babel/types': 7.29.0 - - '@babel/types@7.29.0': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - - '@docsearch/css@3.8.2': {} + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 '@docsearch/css@4.6.2': {} - '@docsearch/js@3.8.2(@algolia/client-search@5.49.2)(search-insights@2.17.3)': - dependencies: - '@docsearch/react': 3.8.2(@algolia/client-search@5.49.2)(search-insights@2.17.3) - preact: 10.29.0 - transitivePeerDependencies: - - '@algolia/client-search' - - '@types/react' - - react - - react-dom - - search-insights - '@docsearch/js@4.6.2': {} - '@docsearch/react@3.8.2(@algolia/client-search@5.49.2)(search-insights@2.17.3)': - dependencies: - '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.49.2)(algoliasearch@5.49.2)(search-insights@2.17.3) - '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.49.2)(algoliasearch@5.49.2) - '@docsearch/css': 3.8.2 - algoliasearch: 5.49.2 - optionalDependencies: - search-insights: 2.17.3 - transitivePeerDependencies: - - '@algolia/client-search' - '@docsearch/sidepanel-js@4.6.2': {} - '@esbuild/aix-ppc64@0.25.12': - optional: true - - '@esbuild/android-arm64@0.25.12': + '@esbuild/aix-ppc64@0.25.0': optional: true - '@esbuild/android-arm@0.25.12': + '@esbuild/android-arm64@0.25.0': optional: true - '@esbuild/android-x64@0.25.12': + '@esbuild/android-arm@0.25.0': optional: true - '@esbuild/darwin-arm64@0.25.12': + '@esbuild/android-x64@0.25.0': optional: true - '@esbuild/darwin-x64@0.25.12': + '@esbuild/darwin-arm64@0.25.0': optional: true - '@esbuild/freebsd-arm64@0.25.12': + '@esbuild/darwin-x64@0.25.0': optional: true - '@esbuild/freebsd-x64@0.25.12': + '@esbuild/freebsd-arm64@0.25.0': optional: true - '@esbuild/linux-arm64@0.25.12': + '@esbuild/freebsd-x64@0.25.0': optional: true - '@esbuild/linux-arm@0.25.12': + '@esbuild/linux-arm64@0.25.0': optional: true - '@esbuild/linux-ia32@0.25.12': + '@esbuild/linux-arm@0.25.0': optional: true - '@esbuild/linux-loong64@0.25.12': + '@esbuild/linux-ia32@0.25.0': optional: true - '@esbuild/linux-mips64el@0.25.12': + '@esbuild/linux-loong64@0.25.0': optional: true - '@esbuild/linux-ppc64@0.25.12': + '@esbuild/linux-mips64el@0.25.0': optional: true - '@esbuild/linux-riscv64@0.25.12': + '@esbuild/linux-ppc64@0.25.0': optional: true - '@esbuild/linux-s390x@0.25.12': + '@esbuild/linux-riscv64@0.25.0': optional: true - '@esbuild/linux-x64@0.25.12': + '@esbuild/linux-s390x@0.25.0': optional: true - '@esbuild/netbsd-arm64@0.25.12': + '@esbuild/linux-x64@0.25.0': optional: true - '@esbuild/netbsd-x64@0.25.12': + '@esbuild/netbsd-arm64@0.25.0': optional: true - '@esbuild/openbsd-arm64@0.25.12': + '@esbuild/netbsd-x64@0.25.0': optional: true - '@esbuild/openbsd-x64@0.25.12': + '@esbuild/openbsd-arm64@0.25.0': optional: true - '@esbuild/openharmony-arm64@0.25.12': + '@esbuild/openbsd-x64@0.25.0': optional: true - '@esbuild/sunos-x64@0.25.12': + '@esbuild/sunos-x64@0.25.0': optional: true - '@esbuild/win32-arm64@0.25.12': + '@esbuild/win32-arm64@0.25.0': optional: true - '@esbuild/win32-ia32@0.25.12': + '@esbuild/win32-ia32@0.25.0': optional: true - '@esbuild/win32-x64@0.25.12': + '@esbuild/win32-x64@0.25.0': optional: true '@floating-ui/core@1.7.5': @@ -1939,11 +1657,11 @@ snapshots: '@floating-ui/utils@0.2.11': {} - '@floating-ui/vue@1.1.11(vue@3.5.30)': + '@floating-ui/vue@1.1.11(vue@3.5.41(typescript@6.0.3))': dependencies: '@floating-ui/dom': 1.7.6 '@floating-ui/utils': 0.2.11 - vue-demi: 0.14.10(vue@3.5.30) + vue-demi: 0.14.10(vue@3.5.41(typescript@6.0.3)) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -1954,10 +1672,10 @@ snapshots: '@iconify/types@2.0.0': {} - '@iconify/vue@5.0.0(vue@3.5.30)': + '@iconify/vue@5.0.0(vue@3.5.41(typescript@6.0.3))': dependencies: '@iconify/types': 2.0.0 - vue: 3.5.30 + vue: 3.5.41(typescript@6.0.3) '@internationalized/date@3.12.1': dependencies: @@ -2045,6 +1763,8 @@ snapshots: '@rive-app/canvas-lite@2.37.3': {} + '@rolldown/pluginutils@1.0.1': {} + '@rollup/rollup-android-arm-eabi@4.59.0': optional: true @@ -2120,40 +1840,38 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true - '@shikijs/core@2.5.0': + '@shikijs/core@3.23.0': dependencies: - '@shikijs/engine-javascript': 2.5.0 - '@shikijs/engine-oniguruma': 2.5.0 - '@shikijs/types': 2.5.0 + '@shikijs/types': 3.23.0 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 hast-util-to-html: 9.0.5 - '@shikijs/engine-javascript@2.5.0': + '@shikijs/engine-javascript@3.23.0': dependencies: - '@shikijs/types': 2.5.0 + '@shikijs/types': 3.23.0 '@shikijs/vscode-textmate': 10.0.2 - oniguruma-to-es: 3.1.1 + oniguruma-to-es: 4.3.6 - '@shikijs/engine-oniguruma@2.5.0': + '@shikijs/engine-oniguruma@3.23.0': dependencies: - '@shikijs/types': 2.5.0 + '@shikijs/types': 3.23.0 '@shikijs/vscode-textmate': 10.0.2 - '@shikijs/langs@2.5.0': + '@shikijs/langs@3.23.0': dependencies: - '@shikijs/types': 2.5.0 + '@shikijs/types': 3.23.0 - '@shikijs/themes@2.5.0': + '@shikijs/themes@3.23.0': dependencies: - '@shikijs/types': 2.5.0 + '@shikijs/types': 3.23.0 - '@shikijs/transformers@2.5.0': + '@shikijs/transformers@3.23.0': dependencies: - '@shikijs/core': 2.5.0 - '@shikijs/types': 2.5.0 + '@shikijs/core': 3.23.0 + '@shikijs/types': 3.23.0 - '@shikijs/types@2.5.0': + '@shikijs/types@3.23.0': dependencies: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -2230,19 +1948,19 @@ snapshots: postcss-selector-parser: 6.0.10 tailwindcss: 4.2.1 - '@tailwindcss/vite@4.2.1(vite@6.4.3(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1))': + '@tailwindcss/vite@4.2.1(vite@6.4.3(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1))': dependencies: '@tailwindcss/node': 4.2.1 '@tailwindcss/oxide': 4.2.1 tailwindcss: 4.2.1 - vite: 6.4.3(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1) + vite: 6.4.3(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1) '@tanstack/virtual-core@3.14.0': {} - '@tanstack/vue-virtual@3.13.24(vue@3.5.30)': + '@tanstack/vue-virtual@3.13.24(vue@3.5.41(typescript@6.0.3))': dependencies: '@tanstack/virtual-core': 3.14.0 - vue: 3.5.30 + vue: 3.5.41(typescript@6.0.3) '@types/debug@4.1.13': dependencies: @@ -2269,9 +1987,9 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@25.6.0': + '@types/node@25.9.5': dependencies: - undici-types: 7.19.2 + undici-types: 7.24.6 '@types/unist@3.0.3': {} @@ -2279,30 +1997,31 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-vue@5.2.4(vite@6.4.3(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1))(vue@3.5.30)': + '@vitejs/plugin-vue@6.0.8(vite@6.4.3(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1))(vue@3.5.41(typescript@6.0.3))': dependencies: - vite: 6.4.3(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1) - vue: 3.5.30 + '@rolldown/pluginutils': 1.0.1 + vite: 6.4.3(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1) + vue: 3.5.41(typescript@6.0.3) - '@voidzero-dev/vitepress-theme@4.8.4(focus-trap@7.8.0)(vite@6.4.3(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1))(vitepress@1.6.4(@algolia/client-search@5.49.2)(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(search-insights@2.17.3))(vue@3.5.30)': + '@voidzero-dev/vitepress-theme@4.8.4(focus-trap@7.8.0)(vite@6.4.3(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1))(vitepress@2.0.0-alpha.16(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(typescript@6.0.3))(vue@3.5.41(typescript@6.0.3))': dependencies: '@docsearch/css': 4.6.2 '@docsearch/js': 4.6.2 '@docsearch/sidepanel-js': 4.6.2 - '@iconify/vue': 5.0.0(vue@3.5.30) + '@iconify/vue': 5.0.0(vue@3.5.41(typescript@6.0.3)) '@rive-app/canvas-lite': 2.37.3 '@tailwindcss/typography': 0.5.19(tailwindcss@4.2.1) - '@tailwindcss/vite': 4.2.1(vite@6.4.3(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1)) + '@tailwindcss/vite': 4.2.1(vite@6.4.3(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1)) '@vue/shared': 3.5.30 - '@vueuse/core': 14.2.1(vue@3.5.30) - '@vueuse/integrations': 14.2.1(focus-trap@7.8.0)(vue@3.5.30) - '@vueuse/shared': 14.2.1(vue@3.5.30) + '@vueuse/core': 14.2.1(vue@3.5.41(typescript@6.0.3)) + '@vueuse/integrations': 14.2.1(focus-trap@7.8.0)(vue@3.5.41(typescript@6.0.3)) + '@vueuse/shared': 14.2.1(vue@3.5.41(typescript@6.0.3)) mark.js: 8.11.1 minisearch: 7.2.0 - reka-ui: 2.9.6(vue@3.5.30) + reka-ui: 2.9.6(vue@3.5.41(typescript@6.0.3)) tailwindcss: 4.2.1 - vitepress: 1.6.4(@algolia/client-search@5.49.2)(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(search-insights@2.17.3) - vue: 3.5.30 + vitepress: 2.0.0-alpha.16(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(typescript@6.0.3) + vue: 3.5.41(typescript@6.0.3) transitivePeerDependencies: - '@vue/composition-api' - async-validator @@ -2319,142 +2038,119 @@ snapshots: - universal-cookie - vite - '@vue/compiler-core@3.5.30': + '@volar/language-core@2.4.28': dependencies: - '@babel/parser': 7.29.0 - '@vue/shared': 3.5.30 + '@volar/source-map': 2.4.28 + + '@volar/source-map@2.4.28': {} + + '@volar/typescript@2.4.28': + dependencies: + '@volar/language-core': 2.4.28 + path-browserify: 1.0.1 + vscode-uri: 3.1.0 + + '@vue/compiler-core@3.5.41': + dependencies: + '@babel/parser': 7.29.8 + '@vue/shared': 3.5.41 entities: 7.0.1 estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-dom@3.5.30': + '@vue/compiler-dom@3.5.41': dependencies: - '@vue/compiler-core': 3.5.30 - '@vue/shared': 3.5.30 + '@vue/compiler-core': 3.5.41 + '@vue/shared': 3.5.41 - '@vue/compiler-sfc@3.5.30': + '@vue/compiler-sfc@3.5.41': dependencies: - '@babel/parser': 7.29.0 - '@vue/compiler-core': 3.5.30 - '@vue/compiler-dom': 3.5.30 - '@vue/compiler-ssr': 3.5.30 - '@vue/shared': 3.5.30 + '@babel/parser': 7.29.8 + '@vue/compiler-core': 3.5.41 + '@vue/compiler-dom': 3.5.41 + '@vue/compiler-ssr': 3.5.41 + '@vue/shared': 3.5.41 estree-walker: 2.0.2 magic-string: 0.30.21 postcss: 8.5.15 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.5.30': + '@vue/compiler-ssr@3.5.41': dependencies: - '@vue/compiler-dom': 3.5.30 - '@vue/shared': 3.5.30 + '@vue/compiler-dom': 3.5.41 + '@vue/shared': 3.5.41 - '@vue/devtools-api@7.7.9': + '@vue/devtools-api@8.2.1': dependencies: - '@vue/devtools-kit': 7.7.9 + '@vue/devtools-kit': 8.2.1 - '@vue/devtools-kit@7.7.9': + '@vue/devtools-kit@8.2.1': dependencies: - '@vue/devtools-shared': 7.7.9 + '@vue/devtools-shared': 8.2.1 birpc: 2.9.0 hookable: 5.5.3 - mitt: 3.0.1 - perfect-debounce: 1.0.0 - speakingurl: 14.0.1 - superjson: 2.2.6 + perfect-debounce: 2.1.0 + + '@vue/devtools-shared@8.2.1': {} - '@vue/devtools-shared@7.7.9': + '@vue/language-core@3.3.10': dependencies: - rfdc: 1.4.1 + '@volar/language-core': 2.4.28 + '@vue/compiler-dom': 3.5.41 + '@vue/shared': 3.5.41 + alien-signals: 3.2.1 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + picomatch: 4.0.5 - '@vue/reactivity@3.5.30': + '@vue/reactivity@3.5.41': dependencies: - '@vue/shared': 3.5.30 + '@vue/shared': 3.5.41 - '@vue/runtime-core@3.5.30': + '@vue/runtime-core@3.5.41': dependencies: - '@vue/reactivity': 3.5.30 - '@vue/shared': 3.5.30 + '@vue/reactivity': 3.5.41 + '@vue/shared': 3.5.41 - '@vue/runtime-dom@3.5.30': + '@vue/runtime-dom@3.5.41': dependencies: - '@vue/reactivity': 3.5.30 - '@vue/runtime-core': 3.5.30 - '@vue/shared': 3.5.30 + '@vue/reactivity': 3.5.41 + '@vue/runtime-core': 3.5.41 + '@vue/shared': 3.5.41 csstype: 3.2.3 - '@vue/server-renderer@3.5.30(vue@3.5.30)': + '@vue/server-renderer@3.5.41': dependencies: - '@vue/compiler-ssr': 3.5.30 - '@vue/shared': 3.5.30 - vue: 3.5.30 + '@vue/compiler-ssr': 3.5.41 + '@vue/runtime-dom': 3.5.41 + '@vue/shared': 3.5.41 '@vue/shared@3.5.30': {} - '@vueuse/core@12.8.2': - dependencies: - '@types/web-bluetooth': 0.0.21 - '@vueuse/metadata': 12.8.2 - '@vueuse/shared': 12.8.2 - vue: 3.5.30 - transitivePeerDependencies: - - typescript + '@vue/shared@3.5.41': {} - '@vueuse/core@14.2.1(vue@3.5.30)': + '@vueuse/core@14.2.1(vue@3.5.41(typescript@6.0.3))': dependencies: '@types/web-bluetooth': 0.0.21 '@vueuse/metadata': 14.2.1 - '@vueuse/shared': 14.2.1(vue@3.5.30) - vue: 3.5.30 + '@vueuse/shared': 14.2.1(vue@3.5.41(typescript@6.0.3)) + vue: 3.5.41(typescript@6.0.3) - '@vueuse/integrations@12.8.2(focus-trap@7.8.0)': + '@vueuse/integrations@14.2.1(focus-trap@7.8.0)(vue@3.5.41(typescript@6.0.3))': dependencies: - '@vueuse/core': 12.8.2 - '@vueuse/shared': 12.8.2 - vue: 3.5.30 + '@vueuse/core': 14.2.1(vue@3.5.41(typescript@6.0.3)) + '@vueuse/shared': 14.2.1(vue@3.5.41(typescript@6.0.3)) + vue: 3.5.41(typescript@6.0.3) optionalDependencies: focus-trap: 7.8.0 - transitivePeerDependencies: - - typescript - - '@vueuse/integrations@14.2.1(focus-trap@7.8.0)(vue@3.5.30)': - dependencies: - '@vueuse/core': 14.2.1(vue@3.5.30) - '@vueuse/shared': 14.2.1(vue@3.5.30) - vue: 3.5.30 - optionalDependencies: - focus-trap: 7.8.0 - - '@vueuse/metadata@12.8.2': {} '@vueuse/metadata@14.2.1': {} - '@vueuse/shared@12.8.2': - dependencies: - vue: 3.5.30 - transitivePeerDependencies: - - typescript - - '@vueuse/shared@14.2.1(vue@3.5.30)': + '@vueuse/shared@14.2.1(vue@3.5.41(typescript@6.0.3))': dependencies: - vue: 3.5.30 + vue: 3.5.41(typescript@6.0.3) - algoliasearch@5.49.2: - dependencies: - '@algolia/abtesting': 1.15.2 - '@algolia/client-abtesting': 5.49.2 - '@algolia/client-analytics': 5.49.2 - '@algolia/client-common': 5.49.2 - '@algolia/client-insights': 5.49.2 - '@algolia/client-personalization': 5.49.2 - '@algolia/client-query-suggestions': 5.49.2 - '@algolia/client-search': 5.49.2 - '@algolia/ingestion': 1.49.2 - '@algolia/monitoring': 1.49.2 - '@algolia/recommend': 5.49.2 - '@algolia/requester-browser-xhr': 5.49.2 - '@algolia/requester-fetch': 5.49.2 - '@algolia/requester-node-http': 5.49.2 + alien-signals@3.2.1: {} ansi-regex@5.0.1: {} @@ -2504,10 +2200,6 @@ snapshots: comma-separated-tokens@2.0.3: {} - copy-anything@4.0.5: - dependencies: - is-what: 5.5.0 - cssesc@3.0.0: {} csstype@3.2.3: {} @@ -2530,8 +2222,6 @@ snapshots: dependencies: dequal: 2.0.3 - emoji-regex-xs@1.0.0: {} - emoji-regex@8.0.0: {} enhanced-resolve@5.20.0: @@ -2543,34 +2233,33 @@ snapshots: entities@7.0.1: {} - esbuild@0.25.12: + esbuild@0.25.0: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.12 - '@esbuild/android-arm': 0.25.12 - '@esbuild/android-arm64': 0.25.12 - '@esbuild/android-x64': 0.25.12 - '@esbuild/darwin-arm64': 0.25.12 - '@esbuild/darwin-x64': 0.25.12 - '@esbuild/freebsd-arm64': 0.25.12 - '@esbuild/freebsd-x64': 0.25.12 - '@esbuild/linux-arm': 0.25.12 - '@esbuild/linux-arm64': 0.25.12 - '@esbuild/linux-ia32': 0.25.12 - '@esbuild/linux-loong64': 0.25.12 - '@esbuild/linux-mips64el': 0.25.12 - '@esbuild/linux-ppc64': 0.25.12 - '@esbuild/linux-riscv64': 0.25.12 - '@esbuild/linux-s390x': 0.25.12 - '@esbuild/linux-x64': 0.25.12 - '@esbuild/netbsd-arm64': 0.25.12 - '@esbuild/netbsd-x64': 0.25.12 - '@esbuild/openbsd-arm64': 0.25.12 - '@esbuild/openbsd-x64': 0.25.12 - '@esbuild/openharmony-arm64': 0.25.12 - '@esbuild/sunos-x64': 0.25.12 - '@esbuild/win32-arm64': 0.25.12 - '@esbuild/win32-ia32': 0.25.12 - '@esbuild/win32-x64': 0.25.12 + '@esbuild/aix-ppc64': 0.25.0 + '@esbuild/android-arm': 0.25.0 + '@esbuild/android-arm64': 0.25.0 + '@esbuild/android-x64': 0.25.0 + '@esbuild/darwin-arm64': 0.25.0 + '@esbuild/darwin-x64': 0.25.0 + '@esbuild/freebsd-arm64': 0.25.0 + '@esbuild/freebsd-x64': 0.25.0 + '@esbuild/linux-arm': 0.25.0 + '@esbuild/linux-arm64': 0.25.0 + '@esbuild/linux-ia32': 0.25.0 + '@esbuild/linux-loong64': 0.25.0 + '@esbuild/linux-mips64el': 0.25.0 + '@esbuild/linux-ppc64': 0.25.0 + '@esbuild/linux-riscv64': 0.25.0 + '@esbuild/linux-s390x': 0.25.0 + '@esbuild/linux-x64': 0.25.0 + '@esbuild/netbsd-arm64': 0.25.0 + '@esbuild/netbsd-x64': 0.25.0 + '@esbuild/openbsd-arm64': 0.25.0 + '@esbuild/openbsd-x64': 0.25.0 + '@esbuild/sunos-x64': 0.25.0 + '@esbuild/win32-arm64': 0.25.0 + '@esbuild/win32-ia32': 0.25.0 + '@esbuild/win32-x64': 0.25.0 escalade@3.2.0: {} @@ -2590,13 +2279,13 @@ snapshots: dependencies: format: 0.2.2 - fdir@6.5.0(picomatch@4.0.4): + fdir@6.5.0(picomatch@4.0.5): optionalDependencies: - picomatch: 4.0.4 + picomatch: 4.0.5 focus-trap@7.8.0: dependencies: - tabbable: 6.4.0 + tabbable: 6.5.0 format@0.2.2: {} @@ -2642,8 +2331,6 @@ snapshots: is-plain-obj@4.1.0: {} - is-what@5.5.0: {} - jiti@2.6.1: {} js-yaml@3.15.0: @@ -2708,9 +2395,9 @@ snapshots: longest-streak@3.1.0: {} - lucide-vue-next@0.577.0(vue@3.5.30): + lucide-vue-next@0.577.0(vue@3.5.41(typescript@6.0.3)): dependencies: - vue: 3.5.30 + vue: 3.5.41(typescript@6.0.3) magic-string@0.30.21: dependencies: @@ -2944,17 +2631,19 @@ snapshots: minisearch@7.2.0: {} - mitt@3.0.1: {} - ms@2.1.3: {} - nanoid@3.3.12: {} + muggle-string@0.4.1: {} + + nanoid@3.3.18: {} ohash@2.0.11: {} - oniguruma-to-es@3.1.1: + oniguruma-parser@0.12.2: {} + + oniguruma-to-es@4.3.6: dependencies: - emoji-regex-xs: 1.0.0 + oniguruma-parser: 0.12.2 regex: 6.1.0 regex-recursion: 6.0.2 @@ -2982,13 +2671,15 @@ snapshots: '@oxfmt/binding-win32-ia32-msvc': 0.36.0 '@oxfmt/binding-win32-x64-msvc': 0.36.0 + path-browserify@1.0.1: {} + path-to-regexp@6.3.0: {} - perfect-debounce@1.0.0: {} + perfect-debounce@2.1.0: {} picocolors@1.1.1: {} - picomatch@4.0.4: {} + picomatch@4.0.5: {} postcss-selector-parser@6.0.10: dependencies: @@ -2997,12 +2688,10 @@ snapshots: postcss@8.5.15: dependencies: - nanoid: 3.3.12 + nanoid: 3.3.18 picocolors: 1.1.1 source-map-js: 1.2.1 - preact@10.29.0: {} - pretty-bytes@7.1.0: {} property-information@7.1.0: {} @@ -3019,19 +2708,19 @@ snapshots: dependencies: regex-utilities: 2.3.0 - reka-ui@2.9.6(vue@3.5.30): + reka-ui@2.9.6(vue@3.5.41(typescript@6.0.3)): dependencies: '@floating-ui/dom': 1.7.6 - '@floating-ui/vue': 1.1.11(vue@3.5.30) + '@floating-ui/vue': 1.1.11(vue@3.5.41(typescript@6.0.3)) '@internationalized/date': 3.12.1 '@internationalized/number': 3.6.6 - '@tanstack/vue-virtual': 3.13.24(vue@3.5.30) - '@vueuse/core': 14.2.1(vue@3.5.30) - '@vueuse/shared': 14.2.1(vue@3.5.30) + '@tanstack/vue-virtual': 3.13.24(vue@3.5.41(typescript@6.0.3)) + '@vueuse/core': 14.2.1(vue@3.5.41(typescript@6.0.3)) + '@vueuse/shared': 14.2.1(vue@3.5.41(typescript@6.0.3)) aria-hidden: 1.2.6 defu: 6.1.7 ohash: 2.0.11 - vue: 3.5.30 + vue: 3.5.41(typescript@6.0.3) transitivePeerDependencies: - '@vue/composition-api' @@ -3070,8 +2759,6 @@ snapshots: require-directory@2.1.1: {} - rfdc@1.4.1: {} - rollup@4.59.0: dependencies: '@types/estree': 1.0.8 @@ -3103,21 +2790,19 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 - search-insights@2.17.3: {} - section-matter@1.0.0: dependencies: extend-shallow: 2.0.1 kind-of: 6.0.3 - shiki@2.5.0: + shiki@3.23.0: dependencies: - '@shikijs/core': 2.5.0 - '@shikijs/engine-javascript': 2.5.0 - '@shikijs/engine-oniguruma': 2.5.0 - '@shikijs/langs': 2.5.0 - '@shikijs/themes': 2.5.0 - '@shikijs/types': 2.5.0 + '@shikijs/core': 3.23.0 + '@shikijs/engine-javascript': 3.23.0 + '@shikijs/engine-oniguruma': 3.23.0 + '@shikijs/langs': 3.23.0 + '@shikijs/themes': 3.23.0 + '@shikijs/types': 3.23.0 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -3125,8 +2810,6 @@ snapshots: space-separated-tokens@2.0.2: {} - speakingurl@14.0.1: {} - sprintf-js@1.0.3: {} string-width@4.2.3: @@ -3146,20 +2829,16 @@ snapshots: strip-bom-string@1.0.0: {} - superjson@2.2.6: - dependencies: - copy-anything: 4.0.5 - - tabbable@6.4.0: {} + tabbable@6.5.0: {} tailwindcss@4.2.1: {} tapable@2.3.0: {} - tinyglobby@0.2.16: + tinyglobby@0.2.17: dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 tinypool@2.1.0: {} @@ -3171,9 +2850,11 @@ snapshots: tslib@2.8.1: {} + typescript@6.0.3: {} + uc.micro@2.1.0: {} - undici-types@7.19.2: {} + undici-types@7.24.6: {} unified@11.0.5: dependencies: @@ -3226,16 +2907,16 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite@6.4.3(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1): + vite@6.4.3(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1): dependencies: - esbuild: 0.25.12 - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 + esbuild: 0.25.0 + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 postcss: 8.5.15 rollup: 4.59.0 - tinyglobby: 0.2.16 + tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 25.6.0 + '@types/node': 25.9.5 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.31.1 @@ -3259,37 +2940,36 @@ snapshots: transitivePeerDependencies: - supports-color - vitepress-plugin-tabs@0.8.0(vitepress@1.6.4(@algolia/client-search@5.49.2)(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(search-insights@2.17.3))(vue@3.5.30): + vitepress-plugin-tabs@0.8.0(vitepress@2.0.0-alpha.16(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(typescript@6.0.3))(vue@3.5.41(typescript@6.0.3)): dependencies: - vitepress: 1.6.4(@algolia/client-search@5.49.2)(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(search-insights@2.17.3) - vue: 3.5.30 + vitepress: 2.0.0-alpha.16(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(typescript@6.0.3) + vue: 3.5.41(typescript@6.0.3) - vitepress@1.6.4(@algolia/client-search@5.49.2)(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(search-insights@2.17.3): + vitepress@2.0.0-alpha.16(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1)(postcss@8.5.15)(typescript@6.0.3): dependencies: - '@docsearch/css': 3.8.2 - '@docsearch/js': 3.8.2(@algolia/client-search@5.49.2)(search-insights@2.17.3) + '@docsearch/css': 4.6.2 + '@docsearch/js': 4.6.2 + '@docsearch/sidepanel-js': 4.6.2 '@iconify-json/simple-icons': 1.2.73 - '@shikijs/core': 2.5.0 - '@shikijs/transformers': 2.5.0 - '@shikijs/types': 2.5.0 + '@shikijs/core': 3.23.0 + '@shikijs/transformers': 3.23.0 + '@shikijs/types': 3.23.0 '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 5.2.4(vite@6.4.3(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1))(vue@3.5.30) - '@vue/devtools-api': 7.7.9 + '@vitejs/plugin-vue': 6.0.8(vite@6.4.3(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1))(vue@3.5.41(typescript@6.0.3)) + '@vue/devtools-api': 8.2.1 '@vue/shared': 3.5.30 - '@vueuse/core': 12.8.2 - '@vueuse/integrations': 12.8.2(focus-trap@7.8.0) + '@vueuse/core': 14.2.1(vue@3.5.41(typescript@6.0.3)) + '@vueuse/integrations': 14.2.1(focus-trap@7.8.0)(vue@3.5.41(typescript@6.0.3)) focus-trap: 7.8.0 mark.js: 8.11.1 minisearch: 7.2.0 - shiki: 2.5.0 - vite: 6.4.3(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.31.1) - vue: 3.5.30 + shiki: 3.23.0 + vite: 6.4.3(@types/node@25.9.5)(jiti@2.6.1)(lightningcss@1.31.1) + vue: 3.5.41(typescript@6.0.3) optionalDependencies: postcss: 8.5.15 transitivePeerDependencies: - - '@algolia/client-search' - '@types/node' - - '@types/react' - async-validator - axios - change-case @@ -3302,11 +2982,8 @@ snapshots: - lightningcss - nprogress - qrcode - - react - - react-dom - sass - sass-embedded - - search-insights - sortablejs - stylus - sugarss @@ -3316,17 +2993,27 @@ snapshots: - universal-cookie - yaml - vue-demi@0.14.10(vue@3.5.30): + vscode-uri@3.1.0: {} + + vue-demi@0.14.10(vue@3.5.41(typescript@6.0.3)): dependencies: - vue: 3.5.30 + vue: 3.5.41(typescript@6.0.3) - vue@3.5.30: + vue-tsc@3.3.10(typescript@6.0.3): dependencies: - '@vue/compiler-dom': 3.5.30 - '@vue/compiler-sfc': 3.5.30 - '@vue/runtime-dom': 3.5.30 - '@vue/server-renderer': 3.5.30(vue@3.5.30) - '@vue/shared': 3.5.30 + '@volar/typescript': 2.4.28 + '@vue/language-core': 3.3.10 + typescript: 6.0.3 + + vue@3.5.41(typescript@6.0.3): + dependencies: + '@vue/compiler-dom': 3.5.41 + '@vue/compiler-sfc': 3.5.41 + '@vue/runtime-dom': 3.5.41 + '@vue/server-renderer': 3.5.41 + '@vue/shared': 3.5.41 + optionalDependencies: + typescript: 6.0.3 wrap-ansi@7.0.0: dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 4142cb87..92dbdf54 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,10 +1,26 @@ -allowBuilds: - esbuild: true - vue-demi: true -ignoredBuiltDependencies: - - esbuild +# pnpm workspace configuration. +# Holds settings that previously lived in package.json's "pnpm" field — +# pnpm reads overrides / peerDependencyRules / auditConfig from here. +# Keep the toolchain pins in sync with makeplane/developer-docs. + overrides: - esbuild: ^0.25.0 - vite: 6.4.3 - postcss: ^8.5.10 - js-yaml@<3.15.0: 3.15.0 + # Toolchain pins for VitePress 2 alpha compatibility. + rollup: 4.59.0 + lodash-es: 4.18.1 + esbuild: 0.25.0 + # Security overrides — force patched versions of vulnerable transitive deps + # (see `pnpm audit`). Bump these as new advisories are published. + vite: 6.4.3 # GHSA-fx2h-pf6j-xcff (high), GHSA-v6wh-96g9-6wx3 + postcss: 8.5.15 # GHSA-qx2v-qp2m-jg93 (via vite) + # Version-scoped so a future dep on js-yaml@^4 is not silently pinned back to the 3.x line. + js-yaml@<3.15.0: 3.15.0 # GHSA-h67p-54hq-rp68 quadratic-DoS via merge-key aliases (via gray-matter; stays in its ^3.13.1 range) + +peerDependencyRules: + allowedVersions: + vitepress: "2" + +# Build scripts left disabled (matching makeplane/developer-docs — neither was +# ever approved, and the site builds fine without them). Flip to true to allow. +allowBuilds: + esbuild: false + vue-demi: false diff --git a/tsconfig.json b/tsconfig.json index 3d7b5300..39efa4dc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,15 +1,3 @@ { - "compilerOptions": { - "target": "ES2022", - "module": "ESNext", - "moduleResolution": "node", - "types": ["node", "vitepress/client"], - "jsx": "preserve", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["docs/.vitepress/**/*.ts", "docs/.vitepress/**/*.vue", "docs/.vitepress/**/*.d.ts"], - "exclude": ["node_modules"] + "extends": "./docs/.vitepress/tsconfig.json" }