diff --git a/apps/stage-web/src/pages/devtools/polaroid.browser.test.ts b/apps/stage-web/src/pages/devtools/polaroid.browser.test.ts
index 85f79edda..98ed2bb62 100644
--- a/apps/stage-web/src/pages/devtools/polaroid.browser.test.ts
+++ b/apps/stage-web/src/pages/devtools/polaroid.browser.test.ts
@@ -1,14 +1,13 @@
import type { Component } from 'vue'
+import PolaroidPage from '@proj-airi/stage-pages/pages/devtools/polaroid.vue'
+
import { DisplayModelFormat, useDisplayModelsStore } from '@proj-airi/stage-ui/stores/display-models'
import { useSettingsStageModel } from '@proj-airi/stage-ui/stores/settings/stage-model'
import { createPinia } from 'pinia'
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest'
import { createApp } from 'vue'
-import PocketPolaroid from '../../../../stage-pocket/src/pages/devtools/polaroid.vue'
-import WebPolaroid from './polaroid.vue'
-
import 'virtual:uno.css'
let presetArchive: Blob
@@ -110,7 +109,7 @@ async function expectImportedModelPhoto(component: Component, modelId: string) {
}
describe('polaroid imported Live2D model', () => {
- it('loads and captures an imported model on the web page', async () => {
+ it('loads and captures an imported model on the shared page', async () => {
// ROOT CAUSE:
//
// Polaroid passed only the object URL to the Live2D loader. An imported
@@ -120,10 +119,6 @@ describe('polaroid imported Live2D model', () => {
// The loader also kept its mutex locked when the first render had no model
// source. We fixed both paths by passing the selected ID and releasing the
// mutex across every early return.
- await expectImportedModelPhoto(WebPolaroid, 'display-model-polaroid-web')
- })
-
- it('loads and captures an imported model on the pocket page', async () => {
- await expectImportedModelPhoto(PocketPolaroid, 'display-model-polaroid-pocket')
+ await expectImportedModelPhoto(PolaroidPage, 'display-model-polaroid')
})
})
diff --git a/apps/stage-web/src/pages/devtools/polaroid.vue b/apps/stage-web/src/pages/devtools/polaroid.vue
deleted file mode 100644
index de3898d09..000000000
--- a/apps/stage-web/src/pages/devtools/polaroid.vue
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/stage-pages/README.md b/packages/stage-pages/README.md
new file mode 100644
index 000000000..8114c8ec5
--- /dev/null
+++ b/packages/stage-pages/README.md
@@ -0,0 +1,23 @@
+# Stage Pages
+
+`@proj-airi/stage-pages` contains route-level Vue pages that multiple AIRI stage applications share.
+
+## Use
+
+Add a page under `src/pages`. Each stage application scans this directory through its Vite router configuration.
+
+Import a shared page through the package boundary when code needs the component directly:
+
+```ts
+import PolaroidPage from '@proj-airi/stage-pages/pages/devtools/polaroid.vue'
+```
+
+## When to use this package
+
+Use this package when two or more stage applications need the same page behavior and route structure.
+
+## When not to use this package
+
+Keep application-specific pages in the owning application. Put reusable business components in `@proj-airi/stage-ui`.
+
+Put primitive UI components in `@proj-airi/ui`. Put shared layouts in `@proj-airi/stage-layouts`.
diff --git a/apps/stage-pocket/src/pages/devtools/polaroid.vue b/packages/stage-pages/src/pages/devtools/polaroid.vue
similarity index 100%
rename from apps/stage-pocket/src/pages/devtools/polaroid.vue
rename to packages/stage-pages/src/pages/devtools/polaroid.vue