63 lines
1.6 KiB
Svelte
63 lines
1.6 KiB
Svelte
<script lang="ts">
|
|
import Header from '$lib/components/navigation/header.svelte';
|
|
import WeatherNav from '$lib/components/navigation/weather-nav.svelte';
|
|
|
|
import favicon from '$lib/assets/favicon.svg';
|
|
|
|
import './layout.css';
|
|
|
|
let { children } = $props();
|
|
|
|
let sidebarCollapsed = $state(false);
|
|
let mobileMenuOpen = $state(false);
|
|
|
|
const toggleSidebar = () => {
|
|
sidebarCollapsed = !sidebarCollapsed;
|
|
};
|
|
|
|
const toggleMobileMenu = () => {
|
|
mobileMenuOpen = !mobileMenuOpen;
|
|
};
|
|
|
|
const closeMobileMenu = () => {
|
|
mobileMenuOpen = false;
|
|
};
|
|
</script>
|
|
|
|
<svelte:head>
|
|
<link rel="icon" href={favicon} />
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
</svelte:head>
|
|
|
|
<div class="flex h-screen overflow-hidden bg-background text-foreground">
|
|
<!-- Desktop sidebar -->
|
|
<div class="hidden h-full shrink-0 md:block">
|
|
<WeatherNav collapsed={sidebarCollapsed} onToggle={toggleSidebar} />
|
|
</div>
|
|
|
|
<!-- Mobile overlay -->
|
|
{#if mobileMenuOpen}
|
|
<div class="fixed inset-0 z-50 md:hidden" role="presentation">
|
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
<div
|
|
class="absolute inset-0 bg-black/30"
|
|
onclick={closeMobileMenu}
|
|
onkeydown={closeMobileMenu}
|
|
></div>
|
|
<div class="relative z-1 h-full w-55 shadow-lg">
|
|
<WeatherNav collapsed={false} onMobileClose={closeMobileMenu} />
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
|
|
<!-- Main area: topbar + content -->
|
|
<div class="flex min-w-0 flex-1 flex-col h-full">
|
|
<Header onMenuToggle={toggleMobileMenu} />
|
|
|
|
<main class="flex-1 overflow-y-auto p-5 md:px-8 md:py-6">
|
|
{@render children()}
|
|
</main>
|
|
</div>
|
|
</div>
|