Files
zoe-shaldon/ui/src/routes/+layout.svelte
T

136 lines
4.3 KiB
Svelte

<script lang="ts">
import "../app.css";
import favicon from "$lib/assets/favicon.svg";
import { page } from "$app/state";
import Countdown from "$lib/components/Countdown.svelte";
import { createWeddingInfo, formatFullDate } from "$lib/wedding-info.svelte";
let { children } = $props();
const wedding = createWeddingInfo();
const metaDescription = $derived(
`Zoé & Shaldon are getting married on ${formatFullDate(wedding.date)} at ${wedding.venueName}, ${wedding.venueAddress}. Find venue directions, dress code, the order of events, and RSVP here.`,
);
const shareDescription = $derived(
`${formatFullDate(wedding.date)} at ${wedding.venueName}, ${wedding.venueAddress}. Directions, dress code, the schedule, and RSVP.`,
);
const links = [
{ href: "/", label: "Home" },
{ href: "/rsvp", label: "RSVP" },
{ href: "/photos", label: "Photos" },
{ href: "/venue", label: "Venue" },
{ href: "/details", label: "Details" },
{ href: "/wedding-party", label: "Wedding Party" },
];
let menuOpen = $state(false);
$effect(() => {
page.url.pathname;
menuOpen = false;
});
</script>
<svelte:head>
<title>Zoé &amp; Shaldon are getting married</title>
<link rel="icon" href={favicon} />
<meta name="description" content={metaDescription} />
<meta property="og:type" content="website" />
<meta property="og:title" content="Zoé &amp; Shaldon are getting married" />
<meta property="og:description" content={shareDescription} />
<meta property="og:url" content={wedding.siteUrl} />
<meta property="og:image" content="{wedding.siteUrl}/photos/IMG_0528.JPG" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Zoé &amp; Shaldon are getting married" />
<meta name="twitter:description" content={shareDescription} />
<meta name="twitter:image" content="{wedding.siteUrl}/photos/IMG_0528.JPG" />
</svelte:head>
<div
class="bg-surface-50 dark:bg-surface-950 flex min-h-screen flex-col bg-[url('/patterns/damask.svg')] bg-repeat [background-size:160px_160px]"
>
<div class="sticky top-0 z-20 flex flex-col">
<nav
class="bg-primary-950 flex items-center justify-between px-4 py-3 sm:px-8"
>
<a
href="/"
class="text-surface-50 font-malibu hidden text-3xl tracking-wide sm:inline"
>Zoé &amp; Shaldon</a
>
<Countdown
target={wedding.date}
compact
pastMessage="Already married! 🎉"
/>
<div class="hidden gap-2 sm:flex">
{#each links as link (link.href)}
<a
href={link.href}
class="btn field-sm {page.url.pathname === link.href
? 'preset-filled-secondary-500'
: 'text-surface-100 hover:text-secondary-400'}"
>
{link.label}
</a>
{/each}
</div>
<button
type="button"
class="text-surface-50 flex items-center justify-center p-2 sm:hidden"
aria-label="Menu"
aria-expanded={menuOpen}
onclick={() => (menuOpen = !menuOpen)}
>
{#if menuOpen}
<svg
viewBox="0 0 24 24"
class="size-6"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path stroke-linecap="round" d="M6 6l12 12M18 6L6 18" />
</svg>
{:else}
<svg
viewBox="0 0 24 24"
class="size-6"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path stroke-linecap="round" d="M4 7h16M4 12h16M4 17h16" />
</svg>
{/if}
</button>
</nav>
{#if menuOpen}
<div
class="bg-primary-950 border-primary-800 flex flex-col gap-1 border-t px-4 py-3 sm:hidden"
>
{#each links as link (link.href)}
<a
href={link.href}
class="btn field-sm w-full {page.url.pathname === link.href
? 'preset-filled-secondary-500'
: 'text-surface-100 hover:text-secondary-400'}"
>
{link.label}
</a>
{/each}
</div>
{/if}
</div>
<main
class="text-surface-900 dark:text-surface-100 text-shadow-sm text-shadow-white/80 dark:text-shadow-black/70 flex flex-1 flex-col"
>
{@render children()}
</main>
</div>