Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@
--mobile-generate-bar-pad: calc(
var(--mobile-generate-bar-h) + var(--mobile-nav-clearance) + 0.5rem
);
/*
* Toast stack clears MobileGenerateBar + tab nav (AIT-597 / AIT-447 residual).
* MobileGenerateBar parks at --mobile-nav-clearance (pill row ~3.25rem).
* Without bar-h, toast lands in the same band as the Generate pills on browse
* surfaces (library/explore/pricing/…). Desktop keeps lg:bottom-6 in Toast.tsx.
*/
--toast-clearance: calc(
var(--mobile-nav-clearance) + var(--mobile-generate-bar-h) + 0.5rem
);

/* shadcn-compatible aliases */
--background: var(--bg);
Expand Down
7 changes: 5 additions & 2 deletions components/Toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ export function ToastProvider({ children }: { children: React.ReactNode }) {
return (
<ToastCtx.Provider value={value}>
{children}
{/* Clear tab nav + home indicator on mobile; desktop keeps a simple inset. */}
{/*
Mobile: --toast-clearance stacks MobileGenerateBar + tab nav + gap
(AIT-597 / AIT-447 residual). Desktop keeps a simple inset (lg:bottom-6).
*/}
<div
data-toast-stack="safe"
className="pointer-events-none fixed bottom-[calc(var(--mobile-nav-clearance)+0.5rem)] right-4 z-[120] flex max-w-[min(22rem,calc(100vw-2rem))] flex-col gap-2 lg:bottom-6"
className="pointer-events-none fixed bottom-[var(--toast-clearance)] right-4 z-[120] flex max-w-[min(22rem,calc(100vw-2rem))] flex-col gap-2 lg:bottom-6"
>
{items.map((t) => (
<div
Expand Down
35 changes: 33 additions & 2 deletions scripts/generate-360-cta-smoke.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -556,23 +556,54 @@ assert.match(
"BatchStudio sticky must expose clearance branch marker"
);

// 8. AIT-185 — Toast stack clears tab + home indicator (never hard bottom-20)
// 8. AIT-597 / AIT-447 — Toast clears MobileGenerateBar + tab + home indicator
const toastSrc = read("components/Toast.tsx");
assert.match(
toastSrc,
/data-toast-stack=["']safe["']/,
"Toast stack must expose data-toast-stack=safe"
);
assert.match(
toastSrc,
/bottom-\[var\(--toast-clearance\)\]/,
"Toast stack must use --toast-clearance (bar + nav, AIT-597)"
);
assert.match(
toastSrc,
/lg:bottom-6/,
"Toast desktop keeps bottom-6"
);
assert.doesNotMatch(
toastSrc,
/bottom-\[calc\(var\(--mobile-nav-clearance\)\+0\.5rem\)\]/,
"Toast stack must clear tab nav + home indicator via --mobile-nav-clearance"
"Toast must not park on nav-only clearance under MobileGenerateBar"
);
assert.doesNotMatch(
toastSrc,
/bottom-20/,
"Toast stack must not hardcode bottom-20 (misses notched safe-area)"
);
assert.match(
globalsCss,
/--toast-clearance:\s*calc\(\s*var\(--mobile-nav-clearance\)\s*\+\s*var\(--mobile-generate-bar-h\)\s*\+\s*0\.5rem\s*\)/,
"globals --toast-clearance stacks bar-h + nav clearance + gap"
);
assert.match(
globalsCss,
/--mobile-generate-bar-h:\s*3\.25rem/,
"globals defines --mobile-generate-bar-h for toast stack"
);
// Bar-route: MobileGenerateBar and toast must not share the same bottom band
assert.match(
mobileBar,
/bottom-\[var\(--mobile-nav-clearance\)\]/,
"MobileGenerateBar parks on --mobile-nav-clearance"
);
assert.match(
mobileBar,
/data-floating-generate=["']mobile-bar["']/,
"MobileGenerateBar keeps data-floating-generate marker on bar routes"
);
// AIT-374: Toast residual competitor lime → neon-pink / void board tokens
assert.doesNotMatch(
toastSrc,
Expand Down
36 changes: 35 additions & 1 deletion scripts/mobile-proof-regression.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,38 @@ assert.match(
);
{
const toast = source("components/Toast.tsx");
const globals = source("app/globals.css");
// AIT-597 / AIT-447: toast must clear MobileGenerateBar + tab nav, not nav alone
assert.match(
toast,
/bottom-\[var\(--toast-clearance\)\]/,
"Toast stack uses --toast-clearance (bar + nav, AIT-597)"
);
assert.match(
toast,
/lg:bottom-6/,
"Toast desktop keeps bottom-6"
);
assert.doesNotMatch(
toast,
/bottom-\[calc\(var\(--mobile-nav-clearance\)\+0\.5rem\)\]/,
"Toast stack clears mobile nav + safe-area (AIT-185)"
"Toast must not park on nav-only clearance under MobileGenerateBar"
);
assert.doesNotMatch(
toast,
/bottom-20/,
"Toast must not hardcode bottom-20 under notched home indicator"
);
assert.match(
globals,
/--toast-clearance:\s*calc\(\s*var\(--mobile-nav-clearance\)\s*\+\s*var\(--mobile-generate-bar-h\)\s*\+\s*0\.5rem\s*\)/,
"globals --toast-clearance stacks bar-h + nav clearance + gap"
);
assert.match(
globals,
/--mobile-generate-bar-h:\s*3\.25rem/,
"globals defines MobileGenerateBar height token for toast stack"
);
// AIT-374: residual competitor lime → neon-pink / void board
assert.doesNotMatch(
toast,
Expand All @@ -152,6 +174,18 @@ assert.match(
/rgba\(255,\s*78,\s*205/,
"Toast glow uses neon-pink board rgba"
);
// Bar-route surface still mounts MobileGenerateBar above the same nav band
const bar = source("components/MobileGenerateBar.tsx");
assert.match(
bar,
/data-floating-generate=["']mobile-bar["']/,
"MobileGenerateBar marker remains for bar-route collision smoke"
);
assert.match(
bar,
/bottom-\[var\(--mobile-nav-clearance\)\]/,
"MobileGenerateBar parks on nav clearance; toast must clear above it"
);
}
{
// AIT-394: MobileGenerateBar floating Generate primary CTA off residual lime
Expand Down
Loading