ADDED - Frame site content in a macOS-style shell window on an ambient desktop

- Wrap #smooth-wrapper in an .app-shell: a fixed, inset, rounded, bordered
  panel. Its transform makes it the containing block for the fixed wrapper, so
  ScrollSmoother sizes the scroll viewport to the shell (content scrolls inside
  it) without fighting ScrollSmoother's inline styles.
- Dock and corner controls stay outside the shell, on a brand-tinted 'desktop'
  wallpaper painted on body.
- Reduced-motion path: the shell scrolls its content natively.
This commit is contained in:
moh
2026-09-20 20:16:49 +02:00
parent 31dc72b1c8
commit 2fc0641512
2 changed files with 57 additions and 11 deletions
+9 -7
View File
@@ -45,13 +45,15 @@ export default async function SiteLayout({ children, params }: SiteLayoutProps)
<ScrollSmootherProvider /> <ScrollSmootherProvider />
<SiteAmbientBackdrop /> <SiteAmbientBackdrop />
<SiteDock defaultLocale={siteSettings.defaultLocale} isSuperAdmin={authenticated} /> <SiteDock defaultLocale={siteSettings.defaultLocale} isSuperAdmin={authenticated} />
<div id="smooth-wrapper"> <div className="app-shell">
<div id="smooth-content"> <div id="smooth-wrapper">
<div className="site-content-frame flex min-h-screen flex-col"> <div id="smooth-content">
<main className="flex-1"> <div className="site-content-frame flex min-h-screen flex-col">
<PageTransition>{children}</PageTransition> <main className="flex-1">
</main> <PageTransition>{children}</PageTransition>
<SiteFooter defaultLocale={siteSettings.defaultLocale} /> </main>
<SiteFooter defaultLocale={siteSettings.defaultLocale} />
</div>
</div> </div>
</div> </div>
</div> </div>
+48 -4
View File
@@ -187,8 +187,12 @@ html[lang="ar"] .eyebrow {
body { body {
@apply min-h-screen text-foreground antialiased; @apply min-h-screen text-foreground antialiased;
background-color: hsl(var(--background)); /* The "desktop" behind the shell window: a subtle brand-tinted wallpaper. */
background-image: none; background-color: hsl(var(--surface-3));
background-image:
radial-gradient(1100px 780px at 12% -8%, hsl(var(--primary) / 0.16), transparent 55%),
radial-gradient(1000px 720px at 108% 112%, hsl(217 55% 45% / 0.16), transparent 55%);
background-attachment: fixed;
font-family: inherit; font-family: inherit;
} }
@@ -903,8 +907,39 @@ html[lang="ar"] .eyebrow {
0 0 30px rgba(220, 68, 22, 0.08); 0 0 30px rgba(220, 68, 22, 0.08);
} }
/* ── ScrollSmoother wrapper ── */ /* ── App shell (macOS-style "window") ──
Frames the scrolling content: the shell is a fixed, inset, rounded panel and
— because it sets a `transform` — it becomes the containing block for the
position:fixed #smooth-wrapper inside it, so ScrollSmoother's own inline
`inset:0; width/height:100%` sizes the wrapper to the SHELL, not the viewport.
The dock and corner controls render outside the shell, on the ambient desktop. */
.app-shell {
position: fixed;
top: calc(env(safe-area-inset-top, 0px) + 12px);
left: 12px;
right: 12px;
bottom: calc(env(safe-area-inset-bottom, 0px) + 94px);
overflow: hidden;
border-radius: 28px;
border: 1px solid hsl(var(--foreground) / 0.12);
background: hsl(var(--background));
box-shadow:
0 40px 90px -30px rgba(0, 0, 0, 0.65),
inset 0 1px 0 hsl(var(--foreground) / 0.08);
transform: translateZ(0);
}
@media (max-width: 640px) {
.app-shell {
top: calc(env(safe-area-inset-top, 0px) + 8px);
left: 8px;
right: 8px;
bottom: calc(env(safe-area-inset-bottom, 0px) + 86px);
border-radius: 22px;
}
}
/* ── ScrollSmoother wrapper (fills the shell) ── */
#smooth-wrapper { #smooth-wrapper {
overflow: hidden; overflow: hidden;
position: fixed; position: fixed;
@@ -920,8 +955,17 @@ html[lang="ar"] .eyebrow {
} }
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
/* No ScrollSmoother: let the shell itself scroll its content natively. */
.app-shell {
overflow-y: auto;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
}
#smooth-wrapper { #smooth-wrapper {
position: static;
inset: auto;
width: 100%;
height: auto;
overflow: visible; overflow: visible;
position: relative;
} }
} }