<script lang="ts">
import "#lib/components/landing/landing.css";
import "#lib/components/landing/material.css";
import { onMount } from "svelte";
import Cta from "#lib/components/landing/cta/Cta.svelte";
import EmbossFilter from "#lib/components/landing/EmbossFilter.svelte";
import Features from "#lib/components/landing/features/Features.svelte";
import { Guest, setGuest } from "#lib/components/landing/guest.svelte.ts";
import Hackable from "#lib/components/landing/hackable/Hackable.svelte";
import Hero from "#lib/components/landing/hero/Hero.svelte";
import Footer from "#lib/components/landing/shell/Footer.svelte";
import SelfHost from "#lib/components/landing/selfhost/SelfHost.svelte";
import Navbar from "#lib/components/landing/shell/Navbar.svelte";
import { setThread, Thread } from "#lib/components/landing/thread/thread.svelte.ts";
import ThreadRail from "#lib/components/landing/thread/ThreadRail.svelte";
import { loadSounds } from "#lib/components/landing/sound.ts";
import type { Notification } from "#lib/components/landing/hero/notifications.ts";
import RecentUpdates from "#lib/components/landing/updates/RecentUpdates.svelte";
import type { Update } from "#lib/components/landing/updates/updates.ts";
/*
* The landing page for signed-out visitors. One thread runs through it, from the hero's
* notification stack down the rail beside every section into the CTA's knot (thread/).
* Sections sit in rail containers, so their content keeps clear of the line.
*/
interface Props {
/** The hero stack's live activity, from the public timeline. */
activity?: Notification[] | null;
updates?: Update[] | null;
}
// Each is null when its source couldn't be reached: the hero's stack shows a recorded
// snapshot instead (hero/mock.ts) and Recent updates is left out.
let { activity, updates }: Props = $props();
const thread = setThread(new Thread());
const guest = setGuest(new Guest());
onMount(() => {
void loadSounds();
return () => guest.destroy();
});
const startAtTop = `<script>
if (performance.getEntriesByType("navigation")[0]?.type === "reload") {
history.scrollRestoration = "manual";
history.replaceState(null, "");
}
</${"script"}>`;
</script>
<svelte:head>
<!-- eslint-disable-next-line svelte/no-at-html-tags -- static -->
{@html startAtTop}
</svelte:head>
<div class="landing" {@attach thread.mark("root")}>
<!-- the hero's side grids, the full height of the page -->
<div class="page-grid l" aria-hidden="true"></div>
<div class="page-grid r" aria-hidden="true"></div>
<EmbossFilter />
<Navbar />
<main>
<Hero {activity} />
<div class="body" {@attach thread.mark("body")}>
<Features />
<Hackable />
<SelfHost />
{#if updates?.length}
<RecentUpdates {updates} />
{/if}
</div>
<Cta />
</main>
<Footer />
<ThreadRail />
</div>