diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index df7118e..d90af06 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -109,8 +109,8 @@ jobs:
build-docs:
name: Build docs site
runs-on: ubuntu-latest
- # GATED: docs-site/ directory does not exist yet. Uncomment + create docs-site/ before re-enabling.
- if: false
+ permissions:
+ contents: write
steps:
- uses: actions/checkout@v4
- name: Build static site
@@ -118,7 +118,10 @@ jobs:
run: |
npm ci
npm run build
+ # Build runs on every push/PR (validates the site). Deploy to gh-pages
+ # only on push to the default branch — PRs build but don't publish.
- uses: peaceiris/actions-gh-pages@v4
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs-site/out
diff --git a/README.md b/README.md
index 716a495..460b276 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Stackup
-**Kubernetes on your laptop. ArgoCD + Argo Rollouts + Prometheus + Loki + Tempo + Grafana. `make up` in 10 minutes. Free.**
+**Kubernetes on your laptop. ArgoCD + Argo Rollouts + Prometheus + Grafana. `make up` in 10 minutes. Free.**
[](https://github.com/ykstorm/stackup/actions/workflows/ci.yml)
[](LICENSE)
@@ -29,11 +29,16 @@ The buyerchat workload deliberately runs degraded (no DB). That's intentional. T
| **TLS** | cert-manager | Self-signed ClusterIssuer (swap to ACME in one line for prod) |
| **Secrets** | Sealed Secrets | Encrypted secrets in git, decrypted in-cluster |
| **Metrics** | kube-prometheus-stack | Prometheus + Alertmanager + Grafana, RED dashboards pre-imported |
-| **Logs** | Loki + Promtail | Pod stdout → Loki → Grafana Explore |
-| **Traces** | Tempo (monolithic) | OTLP traces from workloads |
| **Workload demo** | buyerchat Helm chart | Next.js app — demonstrates the cluster, not a production app |
| **Hardening** | PSS `restricted` + NetworkPolicy `default-deny` | Zero-trust on workload namespaces |
+### Roadmap (not installed yet)
+
+| Layer | Component | What it would do |
+|---|---|---|
+| **Logs** | Loki + Promtail | Pod stdout → Loki → Grafana Explore |
+| **Traces** | Tempo | OTLP traces from workloads |
+
---
## 10-minute quickstart
@@ -55,7 +60,7 @@ Add to `/etc/hosts` (Windows: `C:\Windows\System32\drivers\etc\hosts`):
Then open:
- **[https://buyerchat.local.stackup.dev](https://buyerchat.local.stackup.dev)** — workload, returns 503 degraded (no DB — expected)
-- **[https://grafana.local.stackup.dev](https://grafana.local.stackup.dev)** — RED metrics + Loki logs + Tempo traces
+- **[https://grafana.local.stackup.dev](https://grafana.local.stackup.dev)** — RED metrics from Prometheus (logs/traces are roadmap)
- **[https://argocd.local.stackup.dev](https://argocd.local.stackup.dev)** — GitOps tree of 6 child apps
---
@@ -88,15 +93,13 @@ graph TD
Apps --> Rollout[Argo Rollouts CRD]
Rollout --> Pods[Canary pods]
Pods --> Prom[Prometheus]
- Pods --> LokiL[Loki]
- Pods --> TempoT[Tempo]
Prom --> Graf[Grafana]
- LokiL --> Graf
- TempoT --> Graf
```
For full topology + sequence diagrams, see [docs/architecture.md](docs/architecture.md).
+A static documentation site (overview, getting started, architecture, GitOps + canary) is built from `docs-site/` and published to GitHub Pages on merge to `main`.
+
---
## Makefile targets
diff --git a/docs-site/.gitignore b/docs-site/.gitignore
new file mode 100644
index 0000000..6bc3a19
--- /dev/null
+++ b/docs-site/.gitignore
@@ -0,0 +1,5 @@
+/node_modules
+/.next
+/out
+*.tsbuildinfo
+.DS_Store
diff --git a/docs-site/app/architecture/page.js b/docs-site/app/architecture/page.js
new file mode 100644
index 0000000..451976f
--- /dev/null
+++ b/docs-site/app/architecture/page.js
@@ -0,0 +1,122 @@
+export const metadata = {
+ title: 'Architecture — Stackup',
+};
+
+export default function Architecture() {
+ return (
+ <>
+
Architecture
+
+ Cluster topology, the GitOps tree, the observability flow, and the
+ security posture — all of it reproducible from make up.
+
+
+ Cluster topology
+
+ kind launches the cluster as Docker containers, each node running
+ containerd and kubelet. Pods run inside the worker nodes as
+ containers-within-containers. The cluster declares{' '}
+ disableDefaultCNI: true and installs Calico, which enforces
+ ingress and egress NetworkPolicy rules in full. The whole thing fits in
+ roughly 3 GB of RAM.
+
+
+ GitOps tree (app-of-apps)
+
+ A single root ArgoCD Application is the only thing make up{' '}
+ applies. It manages six child applications, and ArgoCD syncs each of
+ them from the git repo:
+
+
+ cert-manager — TLS issuance
+ ingress-nginx — ingress and TLS termination
+ sealed-secrets — in-cluster secret decryption
+ kube-prometheus-stack — Prometheus, Alertmanager, Grafana
+ argo-rollouts — the canary controller
+ buyerchat — the demo workload
+
+
+ The discipline is that state lives in git, not in ad-hoc{' '}
+ kubectl apply commands. ArgoCD runs automated sync, prune,
+ and self-heal against what the repo declares.
+
+
+ Observability flow
+
+ kube-prometheus-stack installs Prometheus, Alertmanager, and Grafana.
+ Metrics flow into Prometheus and render as RED dashboards in Grafana:
+
+
+
+
+ Signal
+ Path
+ Store
+
+
+
+
+ Metrics
+ /api/metrics scraped every 30s
+ Prometheus
+
+
+
+
+ Roadmap
+
+ Logs and traces (Loki + Promtail, Tempo) are on the roadmap — not
+ installed yet. Once they are wired in, a Grafana panel would let you
+ drill from a metric into the matching logs, and from a log line jump to
+ the trace by its trace_id.
+
+
+ Security posture
+
+
+
+ Layer
+ Control
+
+
+
+
+ Pod admission
+
+ Pod Security Standards restricted on workload
+ namespaces
+
+
+
+ Network
+
+ NetworkPolicy default-deny, explicit allow rules per
+ service
+
+
+
+ Secrets
+ Sealed Secrets — encrypted in git, decrypted in-cluster
+
+
+ TLS
+ cert-manager self-signed CA (swap to ACME for production)
+
+
+ RBAC
+ No cluster-admin bindings on workload namespaces
+
+
+
+
+ What changes for production
+
+ Taking the stack to EKS, GKE, or AKS means swapping kind for a managed
+ control plane, the self-signed issuer for ACME via DNS-01, hostPort
+ ingress for a real LoadBalancer, local volumes for a CSI driver,
+ single-replica components for HA, and loosening nothing on the RBAC
+ side.
+
+ >
+ );
+}
diff --git a/docs-site/app/getting-started/page.js b/docs-site/app/getting-started/page.js
new file mode 100644
index 0000000..fe22288
--- /dev/null
+++ b/docs-site/app/getting-started/page.js
@@ -0,0 +1,88 @@
+export const metadata = {
+ title: 'Getting Started — Stackup',
+};
+
+export default function GettingStarted() {
+ return (
+ <>
+ Getting Started
+
+ Clone the repo, run one command, and reach a working cluster in about
+ ten minutes. You need Docker and kubectl on the machine.
+
+
+ Bring it up
+
+ {`git clone https://github.com/ykstorm/stackup && cd stackup
+make up`}
+
+
+ make up creates the kind cluster, installs the platform,
+ and deploys the buyerchat workload. The root ArgoCD Application is the
+ only thing applied directly; ArgoCD syncs everything else from the git
+ repo.
+
+
+ Map the hostnames
+
+ Add these entries to your hosts file (/etc/hosts, or{' '}
+ C:\Windows\System32\drivers\etc\hosts on Windows):
+
+
+ {`127.0.0.1 buyerchat.local.stackup.dev
+127.0.0.1 grafana.local.stackup.dev
+127.0.0.1 argocd.local.stackup.dev
+127.0.0.1 prometheus.local.stackup.dev`}
+
+
+ Open the surfaces
+
+
+ buyerchat.local.stackup.dev — the workload. It
+ returns 503 degraded because there is no database wired in. That
+ response is expected.
+
+
+ grafana.local.stackup.dev — RED metrics from
+ Prometheus. Logs and traces (Loki, Tempo) are on the roadmap, not
+ installed yet.
+
+
+ argocd.local.stackup.dev — the GitOps tree of six
+ child apps.
+
+
+
+ Makefile targets
+
+ {`make help # Show all targets
+make up # Create cluster + install platform + buyerchat
+make down # Tear down the kind cluster
+make smoke # Run smoke tests (requires cluster up)
+make lint # Lint all YAML + Helm charts
+make rollout-status # Watch the buyerchat canary progress`}
+
+
+ Known limits
+
+
+ No real LoadBalancer service type — kind does not ship one, so the
+ stack uses hostPort. Deploy to a cloud cluster for a real load
+ balancer.
+
+
+ Storage is local-path PVs by default. Re-creating the cluster wipes
+ them. Add Longhorn or OpenEBS for persistence across teardowns.
+
+
+ Single-tenant workload namespace. Multi-tenant needs more
+ NetworkPolicy and RBAC work.
+
+
+ The buyerchat workload runs degraded with no database, on purpose. The
+ cluster is the demo, not the app.
+
+
+ >
+ );
+}
diff --git a/docs-site/app/gitops-canary/page.js b/docs-site/app/gitops-canary/page.js
new file mode 100644
index 0000000..005774d
--- /dev/null
+++ b/docs-site/app/gitops-canary/page.js
@@ -0,0 +1,62 @@
+export const metadata = {
+ title: 'GitOps & Canary — Stackup',
+};
+
+export default function GitopsCanary() {
+ return (
+ <>
+ GitOps & Canary
+
+ How a single commit turns into a canary rollout gated on Prometheus,
+ with automatic rollback when the analysis fails.
+
+
+ The trigger
+
+ Push a commit that bumps helm/buyerchat/values.yaml{' '}
+ image.tag. ArgoCD notices the change and syncs. Argo
+ Rollouts applies the new Rollout revision. Watch it advance:
+
+
+ {`make rollout-status
+# same as: kubectl argo rollouts get rollout buyerchat -n app --watch`}
+
+
+ The canary steps
+
+ Argo Rollouts shifts 25% of traffic to the new version and pauses, then
+ runs an analysis step. An AnalysisTemplate queries
+ Prometheus three times over 90 seconds. If the success condition holds,
+ the rollout advances to 50%, then 75%, then 100%. If the analysis fails,
+ Argo Rollouts aborts and rolls back to the previous revision. This is the
+ canary pattern teams run in production, reproduced on a laptop.
+
+
+
+ Scale the canary to 25% of traffic and pause.
+ Run the Prometheus analysis query three times over 90 seconds.
+ If the gate passes, advance to 50%, then 75%, then 100%.
+ If the gate fails, abort and revert to the previous revision.
+
+
+ The analysis query
+
+ The current analysis query is a conservative liveness check: is the
+ canary up and being scraped. Once the buyerchat image exports request
+ counters on /api/metrics, swap it for a real success-rate
+ ratio. The template carries a TODO marking the one line to
+ change.
+
+
+ Why GitOps for this
+
+ Because the image tag lives in git and ArgoCD reconciles against it, the
+ rollout has a single source of truth. There is no out-of-band{' '}
+ kubectl set image. A reviewer can read the diff that
+ triggered a deploy, and a revert is a git revert. The canary gate then
+ decides whether that change reaches all traffic, with Prometheus as the
+ judge.
+
+ >
+ );
+}
diff --git a/docs-site/app/globals.css b/docs-site/app/globals.css
new file mode 100644
index 0000000..7e184a4
--- /dev/null
+++ b/docs-site/app/globals.css
@@ -0,0 +1,198 @@
+:root {
+ --bg: #0d1117;
+ --panel: #161b22;
+ --border: #30363d;
+ --text: #e6edf3;
+ --muted: #9da7b3;
+ --accent: #2f81f7;
+ --accent-soft: #1f6feb33;
+ --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html,
+body {
+ margin: 0;
+ padding: 0;
+ background: var(--bg);
+ color: var(--text);
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
+ line-height: 1.6;
+}
+
+a {
+ color: var(--accent);
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+.site-header {
+ border-bottom: 1px solid var(--border);
+ background: var(--panel);
+}
+
+.site-header .inner {
+ max-width: 880px;
+ margin: 0 auto;
+ padding: 14px 24px;
+ display: flex;
+ align-items: center;
+ gap: 24px;
+ flex-wrap: wrap;
+}
+
+.brand {
+ font-weight: 700;
+ font-size: 18px;
+ color: var(--text);
+}
+
+.brand:hover {
+ text-decoration: none;
+}
+
+.nav {
+ display: flex;
+ gap: 18px;
+ font-size: 14px;
+}
+
+.nav a {
+ color: var(--muted);
+}
+
+.nav a:hover {
+ color: var(--text);
+ text-decoration: none;
+}
+
+main {
+ max-width: 880px;
+ margin: 0 auto;
+ padding: 40px 24px 80px;
+}
+
+h1 {
+ font-size: 30px;
+ line-height: 1.2;
+ margin: 0 0 8px;
+}
+
+h2 {
+ font-size: 21px;
+ margin: 36px 0 12px;
+ padding-top: 8px;
+ border-top: 1px solid var(--border);
+}
+
+h3 {
+ font-size: 17px;
+ margin: 24px 0 8px;
+}
+
+.lede {
+ font-size: 17px;
+ color: var(--muted);
+ margin: 0 0 24px;
+}
+
+code {
+ font-family: var(--mono);
+ font-size: 0.9em;
+ background: var(--panel);
+ border: 1px solid var(--border);
+ border-radius: 4px;
+ padding: 1px 5px;
+}
+
+pre {
+ background: var(--panel);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 14px 16px;
+ overflow-x: auto;
+}
+
+pre code {
+ background: none;
+ border: none;
+ padding: 0;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+ margin: 16px 0;
+ font-size: 14px;
+}
+
+th,
+td {
+ border: 1px solid var(--border);
+ padding: 8px 12px;
+ text-align: left;
+ vertical-align: top;
+}
+
+th {
+ background: var(--panel);
+}
+
+ul,
+ol {
+ padding-left: 22px;
+}
+
+li {
+ margin: 4px 0;
+}
+
+.cards {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
+ gap: 16px;
+ margin: 24px 0;
+}
+
+.card {
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 18px;
+ background: var(--panel);
+}
+
+.card h3 {
+ margin-top: 0;
+}
+
+.card p {
+ color: var(--muted);
+ font-size: 14px;
+ margin: 8px 0 0;
+}
+
+.tag {
+ display: inline-block;
+ font-size: 12px;
+ font-family: var(--mono);
+ background: var(--accent-soft);
+ color: var(--accent);
+ border-radius: 4px;
+ padding: 2px 8px;
+ margin-bottom: 16px;
+}
+
+footer {
+ border-top: 1px solid var(--border);
+ color: var(--muted);
+ font-size: 13px;
+ max-width: 880px;
+ margin: 0 auto;
+ padding: 24px;
+}
diff --git a/docs-site/app/layout.js b/docs-site/app/layout.js
new file mode 100644
index 0000000..e959549
--- /dev/null
+++ b/docs-site/app/layout.js
@@ -0,0 +1,41 @@
+import './globals.css';
+
+export const metadata = {
+ title: 'Stackup Docs',
+ description:
+ 'Production-shaped Kubernetes on a laptop: ArgoCD app-of-apps, Argo Rollouts canary, kube-prometheus-stack, all from make up.',
+};
+
+function Header() {
+ return (
+
+ );
+}
+
+export default function RootLayout({ children }) {
+ return (
+
+
+
+ {children}
+
+ Stackup — Apache License 2.0. Built with Next.js static export.{' '}
+ Source on GitHub .
+
+
+
+ );
+}
diff --git a/docs-site/app/page.js b/docs-site/app/page.js
new file mode 100644
index 0000000..e7ff567
--- /dev/null
+++ b/docs-site/app/page.js
@@ -0,0 +1,114 @@
+export default function Home() {
+ return (
+ <>
+ kind · ArgoCD · Argo Rollouts · Prometheus
+ Stackup
+
+ A production-shaped Kubernetes stack that runs on your laptop. One{' '}
+ make up brings up a kind cluster with GitOps, canary
+ delivery, and full observability — for free.
+
+
+
+ Managed Kubernetes starts around $200/month on cloud providers. Stackup
+ runs the same control-plane patterns on kind, in Docker, on a single
+ machine. The buyerchat workload deliberately runs degraded with no
+ database. That is intentional: the cluster is the demo, not the app.
+
+
+ What it is
+
+ A kind-based cluster wired with a real ArgoCD app-of-apps over six child
+ applications, Argo Rollouts canary progressive delivery, the
+ kube-prometheus-stack for metrics (Prometheus, Alertmanager, Grafana),
+ cert-manager TLS, Sealed Secrets encrypted in git, and Calico
+ NetworkPolicy enforcement. Pod Security Standards restricted{' '}
+ applies on every workload namespace.
+
+
+ The components
+
+
+
+ Layer
+ Component
+ Role
+
+
+
+
+ Cluster
+ kind on Docker
+ Kubernetes nodes running in containers
+
+
+ CNI
+ Calico
+ NetworkPolicy enforcement (ingress + egress)
+
+
+ GitOps
+ ArgoCD app-of-apps
+ One root app manages six children; sync, prune, self-heal
+
+
+ Progressive delivery
+ Argo Rollouts
+ Canary 25 to 100% with an analysis gate and auto-rollback
+
+
+ Ingress
+ ingress-nginx
+ TLS termination over hostPort 80/443
+
+
+ TLS
+ cert-manager
+ Self-signed ClusterIssuer, swap to ACME for production
+
+
+ Secrets
+ Sealed Secrets
+ Encrypted in git, decrypted in-cluster
+
+
+ Metrics
+ kube-prometheus-stack
+ Prometheus, Alertmanager, Grafana with RED dashboards
+
+
+ Workload
+ buyerchat Helm chart
+ Next.js demo app that exercises the cluster
+
+
+
+
+ On the roadmap, not installed yet: logs (Loki + Promtail) and traces
+ (Tempo) for the full three-signal view in Grafana.
+
+
+ Start here
+
+
+
+
Clone, run make up, and reach the cluster in about ten minutes.
+
+
+
+
Cluster topology, the GitOps tree, and the observability flow.
+
+
+
+
How a commit becomes a canary rollout with a Prometheus gate.
+
+
+ >
+ );
+}
diff --git a/docs-site/next.config.mjs b/docs-site/next.config.mjs
new file mode 100644
index 0000000..579a9ff
--- /dev/null
+++ b/docs-site/next.config.mjs
@@ -0,0 +1,8 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ output: 'export',
+ images: { unoptimized: true },
+ trailingSlash: true,
+};
+
+export default nextConfig;
diff --git a/docs-site/package-lock.json b/docs-site/package-lock.json
new file mode 100644
index 0000000..5e4964e
--- /dev/null
+++ b/docs-site/package-lock.json
@@ -0,0 +1,899 @@
+{
+ "name": "stackup-docs",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "stackup-docs",
+ "version": "1.0.0",
+ "dependencies": {
+ "next": "15.4.11",
+ "react": "19.1.0",
+ "react-dom": "19.1.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz",
+ "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@img/colour": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
+ "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
+ "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-darwin-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
+ "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
+ "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
+ "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
+ "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
+ "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-ppc64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
+ "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-riscv64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
+ "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
+ "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
+ "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
+ "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
+ "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
+ "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
+ "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-ppc64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
+ "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-ppc64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-riscv64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
+ "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-riscv64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
+ "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
+ "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
+ "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
+ "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
+ "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.7.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
+ "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-ia32": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
+ "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
+ "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@next/env": {
+ "version": "15.4.11",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-15.4.11.tgz",
+ "integrity": "sha512-mIYp/091eYfPFezKX7ZPTWqrmSXq+ih6+LcUyKvLmeLQGhlPtot33kuEOd4U+xAA7sFfj21+OtCpIZx0g5SpvQ==",
+ "license": "MIT"
+ },
+ "node_modules/@next/swc-darwin-arm64": {
+ "version": "15.4.8",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.4.8.tgz",
+ "integrity": "sha512-Pf6zXp7yyQEn7sqMxur6+kYcywx5up1J849psyET7/8pG2gQTVMjU3NzgIt8SeEP5to3If/SaWmaA6H6ysBr1A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-darwin-x64": {
+ "version": "15.4.8",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.4.8.tgz",
+ "integrity": "sha512-xla6AOfz68a6kq3gRQccWEvFC/VRGJmA/QuSLENSO7CZX5WIEkSz7r1FdXUjtGCQ1c2M+ndUAH7opdfLK1PQbw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-gnu": {
+ "version": "15.4.8",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.4.8.tgz",
+ "integrity": "sha512-y3fmp+1Px/SJD+5ntve5QLZnGLycsxsVPkTzAc3zUiXYSOlTPqT8ynfmt6tt4fSo1tAhDPmryXpYKEAcoAPDJw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-musl": {
+ "version": "15.4.8",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.4.8.tgz",
+ "integrity": "sha512-DX/L8VHzrr1CfwaVjBQr3GWCqNNFgyWJbeQ10Lx/phzbQo3JNAxUok1DZ8JHRGcL6PgMRgj6HylnLNndxn4Z6A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-gnu": {
+ "version": "15.4.8",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.4.8.tgz",
+ "integrity": "sha512-9fLAAXKAL3xEIFdKdzG5rUSvSiZTLLTCc6JKq1z04DR4zY7DbAPcRvNm3K1inVhTiQCs19ZRAgUerHiVKMZZIA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-musl": {
+ "version": "15.4.8",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.4.8.tgz",
+ "integrity": "sha512-s45V7nfb5g7dbS7JK6XZDcapicVrMMvX2uYgOHP16QuKH/JA285oy6HcxlKqwUNaFY/UC6EvQ8QZUOo19cBKSA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-arm64-msvc": {
+ "version": "15.4.8",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.4.8.tgz",
+ "integrity": "sha512-KjgeQyOAq7t/HzAJcWPGA8X+4WY03uSCZ2Ekk98S9OgCFsb6lfBE3dbUzUuEQAN2THbwYgFfxX2yFTCMm8Kehw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-x64-msvc": {
+ "version": "15.4.8",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.4.8.tgz",
+ "integrity": "sha512-Exsmf/+42fWVnLMaZHzshukTBxZrSwuuLKFvqhGHJ+mC1AokqieLY/XzAl3jc/CqhXLqLY3RRjkKJ9YnLPcRWg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.15",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
+ "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001799",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz",
+ "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
+ "license": "MIT"
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.12",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
+ "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/next": {
+ "version": "15.4.11",
+ "resolved": "https://registry.npmjs.org/next/-/next-15.4.11.tgz",
+ "integrity": "sha512-IJRyXal45mIsshZI5XJne/intjusslUP1F+FHVBIyMGEqbYtIq1Irdx5vdWBBg58smviPDycmDeV6txsfkv1RQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@next/env": "15.4.11",
+ "@swc/helpers": "0.5.15",
+ "caniuse-lite": "^1.0.30001579",
+ "postcss": "8.4.31",
+ "styled-jsx": "5.1.6"
+ },
+ "bin": {
+ "next": "dist/bin/next"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
+ },
+ "optionalDependencies": {
+ "@next/swc-darwin-arm64": "15.4.8",
+ "@next/swc-darwin-x64": "15.4.8",
+ "@next/swc-linux-arm64-gnu": "15.4.8",
+ "@next/swc-linux-arm64-musl": "15.4.8",
+ "@next/swc-linux-x64-gnu": "15.4.8",
+ "@next/swc-linux-x64-musl": "15.4.8",
+ "@next/swc-win32-arm64-msvc": "15.4.8",
+ "@next/swc-win32-x64-msvc": "15.4.8",
+ "sharp": "^0.34.3"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.1.0",
+ "@playwright/test": "^1.51.1",
+ "babel-plugin-react-compiler": "*",
+ "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
+ "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
+ "sass": "^1.3.0"
+ },
+ "peerDependenciesMeta": {
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "@playwright/test": {
+ "optional": true
+ },
+ "babel-plugin-react-compiler": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/postcss": {
+ "version": "8.4.31",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/react": {
+ "version": "19.1.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
+ "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "19.1.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
+ "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
+ "license": "MIT",
+ "dependencies": {
+ "scheduler": "^0.26.0"
+ },
+ "peerDependencies": {
+ "react": "^19.1.0"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.26.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
+ "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz",
+ "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==",
+ "license": "ISC",
+ "optional": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/sharp": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
+ "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@img/colour": "^1.0.0",
+ "detect-libc": "^2.1.2",
+ "semver": "^7.7.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.34.5",
+ "@img/sharp-darwin-x64": "0.34.5",
+ "@img/sharp-libvips-darwin-arm64": "1.2.4",
+ "@img/sharp-libvips-darwin-x64": "1.2.4",
+ "@img/sharp-libvips-linux-arm": "1.2.4",
+ "@img/sharp-libvips-linux-arm64": "1.2.4",
+ "@img/sharp-libvips-linux-ppc64": "1.2.4",
+ "@img/sharp-libvips-linux-riscv64": "1.2.4",
+ "@img/sharp-libvips-linux-s390x": "1.2.4",
+ "@img/sharp-libvips-linux-x64": "1.2.4",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.4",
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.4",
+ "@img/sharp-linux-arm": "0.34.5",
+ "@img/sharp-linux-arm64": "0.34.5",
+ "@img/sharp-linux-ppc64": "0.34.5",
+ "@img/sharp-linux-riscv64": "0.34.5",
+ "@img/sharp-linux-s390x": "0.34.5",
+ "@img/sharp-linux-x64": "0.34.5",
+ "@img/sharp-linuxmusl-arm64": "0.34.5",
+ "@img/sharp-linuxmusl-x64": "0.34.5",
+ "@img/sharp-wasm32": "0.34.5",
+ "@img/sharp-win32-arm64": "0.34.5",
+ "@img/sharp-win32-ia32": "0.34.5",
+ "@img/sharp-win32-x64": "0.34.5"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/styled-jsx": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
+ "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==",
+ "license": "MIT",
+ "dependencies": {
+ "client-only": "0.0.1"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "babel-plugin-macros": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ }
+ }
+}
diff --git a/docs-site/package.json b/docs-site/package.json
new file mode 100644
index 0000000..0a20481
--- /dev/null
+++ b/docs-site/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "stackup-docs",
+ "version": "1.0.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "next": "15.4.11",
+ "react": "19.1.0",
+ "react-dom": "19.1.0"
+ }
+}