Files
EpicNext-Cms/src/app/(site)/layout.tsx
T
openhands 97012a78f6
CI / check (push) Successful in 2m40s
CI / deploy (push) Successful in 2m13s
CI / publish-container (push) Successful in 2m10s
feat(site): drifting cloud puffs across the public background
Add a fixed, decorative layer of soft clouds that slowly float across
the Habbo sky behind the content:
- Five clouds at staggered sizes, heights, opacities and loop timings
  (60s–190s) so the drift feels organic.
- Dimmed further in dark mode; frozen by prefers-reduced-motion.
- Pure decoration: aria-hidden, pointer-events: none, no color
  utilities in markup (cloud shapes live in globals.css).
2026-09-12 17:12:55 +02:00

68 lines
1.8 KiB
TypeScript

import dynamic from "next/dynamic";
import type { ReactNode } from "react";
import { CloudsField } from "@/components/clouds-field";
import MotionPageWrapper from "@/components/motion-page-wrapper";
import { Navigation } from "@/components/navigation";
import { SiteFooter } from "@/components/site-footer";
import { SiteHeader } from "@/components/site-header";
import { TopHeader } from "@/components/top-header";
import { auth } from "@/lib/auth";
const RadioPlayerGate = dynamic(
() => import("@/components/public/radio-player-gate"),
{
loading: () => (
<div className="animate-pulse bg-[var(--admin-surface)] rounded h-12" />
),
},
);
/**
* Public site chrome. Route group `(site)` keeps this off `/admin` and `/client`,
* so housekeeping is never constrained by the public max-w-7xl grid.
*/
export default async function SiteLayout({
children,
}: {
children: ReactNode;
}) {
const session = await auth();
return (
<>
<CloudsField />
{session?.user?.id ? (
<>
<div data-theme-block="top_header">
<TopHeader session={session} />
</div>
<div data-theme-block="site_header">
<SiteHeader />
</div>
<div data-theme-block="navigation">
<Navigation session={session} />
</div>
</>
) : null}
<main>
<div
data-theme-block="content_grid"
className="mx-auto mt-4 grid max-w-7xl grid-cols-12 gap-x-3 gap-y-5 px-3 py-3 sm:px-4 sm:py-4 md:mt-0 md:px-6 md:py-6 md:gap-y-6"
>
<div className="col-span-12 min-w-0">
<div data-theme-block="page_transition">
<MotionPageWrapper>{children}</MotionPageWrapper>
</div>
</div>
</div>
</main>
<div data-theme-block="footer">
<SiteFooter />
</div>
<div data-theme-block="radio_player">
<RadioPlayerGate />
</div>
</>
);
}