File size: 4,444 Bytes
96dd062
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ea754eb
96dd062
 
 
 
 
 
 
 
 
 
 
 
ea754eb
20a9193
ea754eb
 
 
 
20a9193
ea754eb
 
20a9193
ea754eb
 
 
 
 
 
 
99cf942
 
ea754eb
96dd062
 
ea754eb
 
 
 
 
 
 
 
 
96dd062
 
 
 
 
 
 
99cf942
96dd062
 
 
 
ea754eb
 
 
 
 
 
 
 
 
 
 
 
 
20a9193
 
99cf942
20a9193
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ea754eb
 
 
 
 
 
 
 
99cf942
ea754eb
 
99cf942
 
ea754eb
 
 
20a9193
 
99cf942
ea754eb
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
---
import OverlayWallpaper from "@components/features/OverlayWallpaper.astro";
import Navbar from "@components/layout/Navbar.astro";
import ImageWrapper from "@/components/common/ImageWrapper.astro";
import { backgroundWallpaper, siteConfig } from "@/config";
import { getBackgroundImages } from "@/utils/layout-utils";
import Layout from "./Layout.astro";

interface Props {
	title?: string;
	description?: string;
}

const { title, description } = Astro.props;
const backgroundImages = getBackgroundImages();
const bannerImage =
	typeof backgroundImages.desktop === "string"
		? backgroundImages.desktop
		: typeof backgroundImages.mobile === "string"
			? backgroundImages.mobile
			: "";
const isOverlayMode = backgroundWallpaper.mode === "overlay";
const isWallpaperSwitchable = backgroundWallpaper.switchable ?? true;
---

<Layout title={title} description={description}>
	{(isWallpaperSwitchable || isOverlayMode) && (
		<OverlayWallpaper
			config={{
				src: {
					desktop:
						typeof backgroundImages.desktop === "string"
							? backgroundImages.desktop
							: "",
					mobile:
						typeof backgroundImages.mobile === "string"
							? backgroundImages.mobile
							: "",
				},
				zIndex: backgroundWallpaper.overlay?.zIndex,
				opacity: backgroundWallpaper.overlay?.opacity,
				blur: backgroundWallpaper.overlay?.blur,
			}}
			className={isOverlayMode ? undefined : "hidden opacity-0"}
		/>
	)}

	<slot slot="head" name="head" />

	<div
		id="admin-top-row"
		class:list={[
			"z-50 pointer-events-none relative transition-all duration-700 mx-auto",
			siteConfig.navbar.widthFull ? "" : "max-w-(--page-width) px-0 md:px-4",
		]}
	>
		<div id="navbar-wrapper" class="pointer-events-auto sticky top-0 transition-all">
			<Navbar />
		</div>
	</div>

	<section class="relative z-20 w-full px-2 pt-6 md:px-4 md:pt-8">
		<div class="mx-auto max-w-(--page-width)">
			<div class="card-base admin-hero overflow-hidden">
				<div class="admin-hero-frame">
					{bannerImage ? (
						<ImageWrapper
							src={bannerImage}
							alt="Admin banner image"
							class="admin-hero-media absolute inset-0 h-full w-full"
							loading="eager"
							fetchpriority="high"
							layout="none"
							widths={[1280, 1920]}
							sizes="100vw"
						/>
					) : (
						<div class="admin-hero-fallback absolute inset-0" />
					)}
					<div class="absolute inset-0 admin-hero-overlay" />
					<div class="absolute inset-0 admin-hero-grid gap-5 p-6 text-white md:p-8">
						<div class="admin-hero-copy flex max-w-3xl flex-col gap-4">
							<div class="inline-flex w-fit items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-medium backdrop-blur-md">
							<span class="h-2.5 w-2.5 rounded-full bg-[oklch(0.75_0.14_var(--hue))]" />
							Firefly Admin
							</div>
							<div class="max-w-3xl">
								<h1 class="banner-title text-3xl font-bold md:text-5xl">
									博客后台管理
								</h1>
								<p class="banner-subtitle mt-3 max-w-2xl text-sm text-white/85 md:text-lg">
									统一管理站点配置、文章、图片与重建状态,界面风格和前台博客保持一致。
								</p>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</section>

	<main class="relative z-30 -mt-5 w-full px-2 pb-10 pt-0 md:-mt-6 md:px-4">
		<div class="mx-auto max-w-(--page-width)">
			<slot />
		</div>
	</main>
</Layout>

<style>
	#admin-top-row {
		height: auto;
	}

	.admin-hero-overlay {
		background:
			linear-gradient(135deg, rgb(9 23 30 / 0.86), rgb(18 38 48 / 0.56)),
			linear-gradient(180deg, rgb(0 0 0 / 0.12), rgb(0 0 0 / 0.42));
	}

	.admin-hero-frame {
		position: relative;
		height: clamp(15rem, 26vw, 20rem);
	}

	.admin-hero-media {
		position: absolute;
		inset: 0;
	}

	.admin-hero :global(picture),
	.admin-hero :global(img[data-astro-image]),
	.admin-hero :global(img) {
		display: block;
		width: 100%;
		height: 100% !important;
		max-width: none;
		object-fit: cover;
	}

	.admin-hero-fallback {
		background:
			radial-gradient(circle at top right, rgb(255 255 255 / 0.18), transparent 36%),
			linear-gradient(135deg, oklch(0.32 0.06 calc(var(--hue) * 1deg)), oklch(0.42 0.08 calc(var(--hue) * 1deg)));
	}

	.admin-hero-grid {
		display: flex;
		align-items: flex-start;
	}

	.admin-hero-copy {
		padding-top: clamp(0.5rem, 2vw, 1.25rem);
	}

	@media (max-width: 959px) {
		.admin-hero-frame {
			height: auto;
			min-height: 14rem;
		}
	}
</style>