From 9d2cde36d3d553c5d2759775e9bde0f6983e41ad Mon Sep 17 00:00:00 2001 From: x Date: Thu, 6 Aug 2026 21:13:25 +0800 Subject: [PATCH] =?UTF-8?q?AIT-607:=20Home=20Generate=20360=20continuity?= =?UTF-8?q?=20residual=20=E2=80=94=20sources=20+=20mobile=20dual=20doors?= =?UTF-8?q?=20+=20Lab=20labels?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Post–AIT-593 residual on gallery-calm home: - Register dormant home-* CTA sources (browse/feature/proof-wall/tool-shelf) so workbench first-run stays Lab/Live honest (not dead /projects/{source}) - AppShell mobile Home dual doors: Generate 360 solid primary + Moment outline secondary after hero fold scrolls away - Honest PIKBO Lab badges on hero still + designer-toy gallery stills - Smokes: generate-360-cta, generate-workbench-lab-honesty Closes AIT-607. No fake UGC; no Stripe live; no production deploy. Co-authored-by: multica-agent --- components/AppShell.tsx | 43 +++++++++++--- components/HomeCinemaHero.tsx | 7 ++- components/HomeDesignerGallery.tsx | 6 +- lib/createRouteContract.ts | 16 +++++ lib/designerToyGallery.ts | 16 ++--- scripts/generate-360-cta-smoke.mjs | 58 +++++++++++++++++++ .../generate-workbench-lab-honesty-smoke.mjs | 18 ++++++ 7 files changed, 143 insertions(+), 21 deletions(-) diff --git a/components/AppShell.tsx b/components/AppShell.tsx index f8d25079..67fe95f2 100644 --- a/components/AppShell.tsx +++ b/components/AppShell.tsx @@ -26,6 +26,12 @@ const DEFAULT_MOMENT_CREATE_HREF = `${MOMENT_CREATE_HREF}&source=moment-shell`; const PRIMARY_NAV_CREATE_HREF = `${MOMENT_CREATE_HREF}&source=primary-nav`; /** Home sticky shell: one primary Generate→360 (AIT-413 friction cut). */ const HOME_SHELL_GENERATE_HREF = createGenerate360Href("app-shell-home"); +/** + * Mobile home Moment secondary door (AIT-607 residual dual doors). + * Generate stays the solid primary; Moment is outline/text only so sticky + * still offers both product paths after the hero dual-door fold scrolls away. + */ +const HOME_SHELL_MOMENT_HREF = `${MOMENT_CREATE_HREF}&source=app-shell-home-moment` as const; function active(path: string, href: string) { const route = href.split("?")[0]; @@ -259,15 +265,36 @@ function AppShellInner({ children }: { children: React.ReactNode }) { )} /> -
+
{momentSurface ? ( - - {home ? "Generate 360°" : "Use this motion"} - + home ? ( + // AIT-607: sticky dual doors after hero scrolls — Generate solid + // primary + Moment text secondary (not dual solid / Moment-first). + <> + + Generate 360° + + + Create with my toy + + + ) : ( + + Use this motion + + ) ) : resultShell ? ( <>
-

- Style study · try 360° +

+ PIKBO Lab · Style study · try 360°

{HERO_STILL.title} diff --git a/components/HomeDesignerGallery.tsx b/components/HomeDesignerGallery.tsx index 81e22624..50058809 100644 --- a/components/HomeDesignerGallery.tsx +++ b/components/HomeDesignerGallery.tsx @@ -40,9 +40,9 @@ export function HomeDesignerGallery() { Collectible subjects — not cartoon fillers

- Style studies and lab lighting references for vinyl, blind box, - mecha kits, and plush. Labeled studies — not customer uploads, not - fake UGC. Tap any still to open listing 360°. + PIKBO Lab style studies and lighting references for vinyl, blind + box, mecha kits, and plush. Labeled Lab stills — not customer + uploads, not fake UGC. Tap any still to open listing 360°.

diff --git a/lib/createRouteContract.ts b/lib/createRouteContract.ts index 8a94e6b3..10451b1f 100644 --- a/lib/createRouteContract.ts +++ b/lib/createRouteContract.ts @@ -117,6 +117,10 @@ export function isGenerate360Effect(effect: string | undefined): boolean { * * AIT-521 gallery residual: every designer-toy still is a one-tap 360 door * (home-gallery-*) so home never routes stills through /toys or Moment first. + * + * AIT-607 residual continuity: dormant / off-home rails that still tag home-* + * (browse, feature, proof wall, tool shelf) must stay entry tags — never + * invent dead `/projects/home-*` remix links or skip Lab/Live honesty. */ export const HOME_GENERATE_ENTRY_SOURCES = [ "home-hero", @@ -132,6 +136,10 @@ export const HOME_GENERATE_ENTRY_SOURCES = [ "home-gallery-capsule", "home-gallery-section", "home-explore-rail", + "home-browse", + "home-feature", + "home-proof-wall", + "home-tool-shelf", ] as const; export type HomeGenerateEntrySource = @@ -177,6 +185,14 @@ export function homeGenerateEntryLabel( return "From Home · gallery Generate"; case "home-explore-rail": return "From Home · Lab explore rail"; + case "home-browse": + return "From Home · browse Generate 360°"; + case "home-feature": + return "From Home · feature Generate 360°"; + case "home-proof-wall": + return "From Home · Lab proof wall"; + case "home-tool-shelf": + return "From Home · tool shelf Generate"; default: return "From Home · Generate 360°"; } diff --git a/lib/designerToyGallery.ts b/lib/designerToyGallery.ts index 5c97986d..3d8952b1 100644 --- a/lib/designerToyGallery.ts +++ b/lib/designerToyGallery.ts @@ -53,7 +53,7 @@ export const DESIGNER_TOY_GALLERY: DesignerToyGalleryItem[] = [ toyKind: "art-toys", src: "/style-studies/art-vinyl-guardian-v1.jpg", href: createGenerate360Href("home-gallery-vinyl-guardian"), - badge: "Style study · try 360°", + badge: "PIKBO Lab · Style study · try 360°", aspect: "3/4", }, { @@ -63,7 +63,7 @@ export const DESIGNER_TOY_GALLERY: DesignerToyGalleryItem[] = [ toyKind: "blind-box-figures", src: "/style-studies/art-vinyl-blind-box-direction-v1.jpg", href: createGenerate360Href("home-gallery-blind-box"), - badge: "Style study · try 360°", + badge: "PIKBO Lab · Style study · try 360°", aspect: "3/4", }, { @@ -73,7 +73,7 @@ export const DESIGNER_TOY_GALLERY: DesignerToyGalleryItem[] = [ toyKind: "vinyl-figures", src: "/style-studies/art-vinyl-social-flash-direction-v1.jpg", href: createGenerate360Href("home-gallery-social-flash"), - badge: "Style study · try 360°", + badge: "PIKBO Lab · Style study · try 360°", aspect: "3/4", }, { @@ -83,7 +83,7 @@ export const DESIGNER_TOY_GALLERY: DesignerToyGalleryItem[] = [ toyKind: "model-kits", src: "/style-studies/precision-mecha-v1.jpg", href: createGenerate360Href("home-gallery-mecha"), - badge: "Style study · try 360°", + badge: "PIKBO Lab · Style study · try 360°", aspect: "3/4", }, { @@ -93,7 +93,7 @@ export const DESIGNER_TOY_GALLERY: DesignerToyGalleryItem[] = [ toyKind: "plush-toys", src: "/style-studies/plush-hybrid-v1.jpg", href: createGenerate360Href("home-gallery-plush"), - badge: "Style study · try 360°", + badge: "PIKBO Lab · Style study · try 360°", aspect: "3/4", }, { @@ -103,7 +103,7 @@ export const DESIGNER_TOY_GALLERY: DesignerToyGalleryItem[] = [ toyKind: "art-toys", src: "/moments/gallery-spotlight.jpg", href: createGenerate360Href("home-gallery-spotlight"), - badge: "Lab still · try 360°", + badge: "PIKBO Lab · still · try 360°", aspect: "16/9", }, { @@ -113,7 +113,7 @@ export const DESIGNER_TOY_GALLERY: DesignerToyGalleryItem[] = [ toyKind: "blind-box-figures", src: "/moments/capsule-reveal.jpg", href: createGenerate360Href("home-gallery-capsule"), - badge: "Lab still · try 360°", + badge: "PIKBO Lab · still · try 360°", aspect: "16/9", }, { @@ -124,7 +124,7 @@ export const DESIGNER_TOY_GALLERY: DesignerToyGalleryItem[] = [ src: "/moments/colorblock-pedestal.jpg", // AIT-462 / AIT-521: skip /effects hop — one tap into listing 360 workbench href: createGenerate360Href("home-gallery-pedestal"), - badge: "Lab still · 360 listing", + badge: "PIKBO Lab · still · 360 listing", aspect: "16/9", }, ]; diff --git a/scripts/generate-360-cta-smoke.mjs b/scripts/generate-360-cta-smoke.mjs index e6bdde64..36f0f5da 100644 --- a/scripts/generate-360-cta-smoke.mjs +++ b/scripts/generate-360-cta-smoke.mjs @@ -419,6 +419,64 @@ assert.doesNotMatch( /home \? ["']Try Street Power-Up["']|home \? ["']Create my drop clip["']/, "AppShell home sticky must not remain Moment-only copy" ); +// AIT-607 residual: mobile Home dual doors — Generate solid primary + Moment secondary +assert.match( + appShellSrc, + /data-shell-mobile-360-cta/, + "AppShell mobile home must mark Generate 360 dual-door primary" +); +assert.match( + appShellSrc, + /data-shell-mobile-moment-cta/, + "AppShell mobile home must mark Moment dual-door secondary" +); +assert.match( + appShellSrc, + /data-shell-mobile-360-cta[\s\S]*data-shell-mobile-moment-cta/, + "mobile dual doors must order Generate primary then Moment secondary" +); +assert.match( + appShellSrc, + /source=app-shell-home-moment/, + "mobile Moment secondary must tag app-shell-home-moment (not bare Moment)" +); +assert.doesNotMatch( + appShellSrc, + /data-shell-mobile-moment-cta[\s\S]{0,200}bg-\[var\(--grad-cta\)\]/, + "mobile Moment secondary must not use solid primary CTA fill" +); +// Honest Lab labels on gallery-calm stills (never bare style study without Lab) +const designerGallery = read("lib/designerToyGallery.ts"); +assert.match( + designerGallery, + /PIKBO Lab · Style study · try 360°/, + "gallery style-study badges must prefix PIKBO Lab" +); +assert.match( + designerGallery, + /PIKBO Lab · still · try 360°/, + "gallery Lab still badges must prefix PIKBO Lab" +); +assert.match( + designerGallery, + /PIKBO Lab · still · 360 listing/, + "gallery pedestal badge must prefix PIKBO Lab" +); +assert.doesNotMatch( + designerGallery, + /badge:\s*["']Style study · try 360°["']/, + "gallery must not ship bare Style study badges without Lab" +); +assert.match( + homeHero, + /data-home-hero-lab-label/, + "home hero still must mark honest Lab label" +); +assert.match( + homeHero, + /PIKBO Lab · Style study · try 360°/, + "home hero still caption must prefix PIKBO Lab" +); // Browse surfaces that keep AppShell tab nav must be in showBar for (const route of [ "/explore", diff --git a/scripts/generate-workbench-lab-honesty-smoke.mjs b/scripts/generate-workbench-lab-honesty-smoke.mjs index 991b9613..251662b2 100644 --- a/scripts/generate-workbench-lab-honesty-smoke.mjs +++ b/scripts/generate-workbench-lab-honesty-smoke.mjs @@ -316,6 +316,7 @@ assert.match( "createRouteContract must export HOME_GENERATE_ENTRY_SOURCES" ); // AIT-462 money doors + AIT-521 gallery residual + explore rail +// AIT-607 residual: dormant home-* rails stay entry tags (not project remix ids) for (const tag of [ "home-hero", "app-shell-home", @@ -330,6 +331,10 @@ for (const tag of [ "home-gallery-capsule", "home-gallery-section", "home-explore-rail", + "home-browse", + "home-feature", + "home-proof-wall", + "home-tool-shelf", ]) { assert.match( contractLib, @@ -337,6 +342,19 @@ for (const tag of [ `HOME_GENERATE_ENTRY_SOURCES must include ${tag}` ); } +// Honest entry eyebrows for residual home rails +for (const [tag, label] of [ + ["home-browse", "browse Generate 360"], + ["home-feature", "feature Generate 360"], + ["home-proof-wall", "Lab proof wall"], + ["home-tool-shelf", "tool shelf Generate"], +]) { + assert.match( + contractLib, + new RegExp(`case\\s+["']${tag}["'][\\s\\S]*?return\\s+["'][^"']*${label}`), + `homeGenerateEntryLabel must cover ${tag}` + ); +} assert.match( contractLib, /export function isHomeGenerateEntrySource/,