Skip to content

Commit 28854b8

Browse files
committed
feat: add branded default index and 404 pages based on BackendStack21 identity
2 parents 8320763 + 83a0bf6 commit 28854b8

File tree

2 files changed

+451
-41
lines changed

2 files changed

+451
-41
lines changed

public/404.html

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>404 — Not Found</title>
7+
<style>
8+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
9+
10+
:root {
11+
--bg: #0f172a;
12+
--surface: #1e293b;
13+
--border: #334155;
14+
--accent: #38bdf8;
15+
--accent-2: #818cf8;
16+
--text: #f1f5f9;
17+
--muted: #94a3b8;
18+
--red: #f87171;
19+
--radius: 10px;
20+
}
21+
22+
body {
23+
font-family: "Outfit", ui-rounded, system-ui, -apple-system, sans-serif;
24+
background: var(--bg);
25+
color: var(--text);
26+
min-height: 100vh;
27+
display: flex;
28+
flex-direction: column;
29+
align-items: center;
30+
justify-content: center;
31+
padding: 40px 20px;
32+
position: relative;
33+
overflow-x: hidden;
34+
}
35+
36+
body::before {
37+
content: "";
38+
position: fixed;
39+
inset: 0;
40+
background:
41+
radial-gradient(ellipse 70% 45% at 50% -5%, rgba(248,113,113,.09) 0%, transparent 70%),
42+
radial-gradient(ellipse 55% 35% at 85% 85%, rgba(129,140,248,.07) 0%, transparent 60%);
43+
pointer-events: none;
44+
z-index: 0;
45+
}
46+
47+
body::after {
48+
content: "";
49+
position: fixed;
50+
inset: 0;
51+
background-image: radial-gradient(rgba(148,163,184,.1) 1px, transparent 1px);
52+
background-size: 28px 28px;
53+
pointer-events: none;
54+
z-index: 0;
55+
}
56+
57+
.card {
58+
position: relative;
59+
z-index: 1;
60+
background: var(--surface);
61+
border: 1px solid var(--border);
62+
border-radius: 16px;
63+
padding: 44px 48px;
64+
max-width: 560px;
65+
width: 100%;
66+
box-shadow: 0 24px 64px rgba(0,0,0,.4);
67+
text-align: center;
68+
}
69+
70+
.code {
71+
font-size: clamp(4rem, 18vw, 7rem);
72+
font-weight: 800;
73+
line-height: 1;
74+
background: linear-gradient(135deg, var(--red) 0%, rgba(248,113,113,.5) 100%);
75+
-webkit-background-clip: text;
76+
background-clip: text;
77+
-webkit-text-fill-color: transparent;
78+
margin-bottom: 16px;
79+
letter-spacing: -.03em;
80+
}
81+
82+
h1 {
83+
font-size: 1.3rem;
84+
font-weight: 600;
85+
margin-bottom: 10px;
86+
}
87+
88+
.sub {
89+
color: var(--muted);
90+
font-size: .92rem;
91+
line-height: 1.65;
92+
margin-bottom: 36px;
93+
}
94+
95+
.actions {
96+
display: flex;
97+
align-items: center;
98+
justify-content: center;
99+
flex-wrap: wrap;
100+
gap: 10px;
101+
}
102+
103+
.btn {
104+
display: inline-flex;
105+
align-items: center;
106+
gap: 7px;
107+
border-radius: 9px;
108+
padding: 10px 20px;
109+
font-size: .87rem;
110+
font-weight: 600;
111+
text-decoration: none;
112+
cursor: pointer;
113+
border: none;
114+
transition: opacity .15s, background .15s, border-color .15s;
115+
font-family: inherit;
116+
}
117+
118+
.btn-primary {
119+
background: var(--accent);
120+
color: #0f172a;
121+
}
122+
123+
.btn-primary:hover { opacity: .88; }
124+
125+
.btn-ghost {
126+
background: transparent;
127+
color: var(--muted);
128+
border: 1px solid var(--border);
129+
}
130+
131+
.btn-ghost:hover {
132+
border-color: var(--accent);
133+
color: var(--accent);
134+
}
135+
136+
.divider {
137+
border: none;
138+
border-top: 1px solid var(--border);
139+
margin: 32px 0 24px;
140+
}
141+
142+
.brand {
143+
display: inline-flex;
144+
align-items: center;
145+
gap: 8px;
146+
font-size: .82rem;
147+
color: var(--muted);
148+
text-decoration: none;
149+
}
150+
151+
.brand-logo {
152+
width: 20px;
153+
height: 20px;
154+
border-radius: 5px;
155+
background: linear-gradient(135deg, var(--accent), var(--accent-2));
156+
display: flex;
157+
align-items: center;
158+
justify-content: center;
159+
font-weight: 800;
160+
font-size: .6rem;
161+
color: #0f172a;
162+
letter-spacing: -.5px;
163+
flex-shrink: 0;
164+
}
165+
166+
.brand:hover { color: var(--text); }
167+
168+
@media (max-width: 500px) {
169+
.card { padding: 32px 24px; }
170+
}
171+
</style>
172+
</head>
173+
<body>
174+
<div class="card">
175+
<div class="code">404</div>
176+
<h1>Page not found</h1>
177+
<p class="sub">
178+
The page you're looking for doesn't exist or has been moved.<br>
179+
Double-check the URL or head back home.
180+
</p>
181+
182+
<div class="actions">
183+
<a href="/" class="btn btn-primary">
184+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
185+
<path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/>
186+
</svg>
187+
Go home
188+
</a>
189+
<button class="btn btn-ghost" onclick="history.back()">
190+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
191+
<polyline points="15 18 9 12 15 6"/>
192+
</svg>
193+
Go back
194+
</button>
195+
</div>
196+
197+
<hr class="divider" />
198+
199+
<a href="https://21no.de" class="brand">
200+
<div class="brand-logo">21</div>
201+
<span>Served by static-web &mdash; BackendStack21</span>
202+
</a>
203+
</div>
204+
</body>
205+
</html>

0 commit comments

Comments
 (0)