feat: add custom 404 error page
- Create stylish 404 page with glitch animation and CRT scanline effects - Update nginx to serve custom 404 instead of falling back to index.html - Page inherits site layout with WebGL background and audio player Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
147
layouts/404.html
Normal file
147
layouts/404.html
Normal file
@@ -0,0 +1,147 @@
|
||||
{{ define "main" }}
|
||||
<style>
|
||||
/* Glitch animation for 404 text */
|
||||
.glitch {
|
||||
position: relative;
|
||||
font-size: clamp(8rem, 20vw, 16rem);
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
color: #fff;
|
||||
letter-spacing: 0.02em;
|
||||
animation: glitch-skew 4s infinite linear alternate-reverse;
|
||||
}
|
||||
|
||||
.glitch::before,
|
||||
.glitch::after {
|
||||
content: attr(data-text);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.glitch::before {
|
||||
color: #ff00ff;
|
||||
animation: glitch-1 2s infinite linear alternate-reverse;
|
||||
clip-path: polygon(0 0, 100% 0, 100% 35%, 0 35%);
|
||||
}
|
||||
|
||||
.glitch::after {
|
||||
color: #00ffff;
|
||||
animation: glitch-2 3s infinite linear alternate-reverse;
|
||||
clip-path: polygon(0 65%, 100% 65%, 100% 100%, 0 100%);
|
||||
}
|
||||
|
||||
@keyframes glitch-1 {
|
||||
0%, 100% { transform: translate(0); }
|
||||
20% { transform: translate(-3px, 3px); }
|
||||
40% { transform: translate(-3px, -3px); }
|
||||
60% { transform: translate(3px, 3px); }
|
||||
80% { transform: translate(3px, -3px); }
|
||||
}
|
||||
|
||||
@keyframes glitch-2 {
|
||||
0%, 100% { transform: translate(0); }
|
||||
20% { transform: translate(3px, -3px); }
|
||||
40% { transform: translate(3px, 3px); }
|
||||
60% { transform: translate(-3px, -3px); }
|
||||
80% { transform: translate(-3px, 3px); }
|
||||
}
|
||||
|
||||
@keyframes glitch-skew {
|
||||
0%, 100% { transform: skew(0deg); }
|
||||
30% { transform: skew(0.5deg); }
|
||||
60% { transform: skew(-0.5deg); }
|
||||
}
|
||||
|
||||
/* Scanline overlay */
|
||||
.scanlines {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
background: repeating-linear-gradient(
|
||||
0deg,
|
||||
rgba(0, 0, 0, 0.1) 0px,
|
||||
rgba(0, 0, 0, 0.1) 1px,
|
||||
transparent 1px,
|
||||
transparent 2px
|
||||
);
|
||||
animation: scanline-flicker 0.1s infinite;
|
||||
}
|
||||
|
||||
@keyframes scanline-flicker {
|
||||
0%, 100% { opacity: 0.8; }
|
||||
50% { opacity: 0.85; }
|
||||
}
|
||||
|
||||
/* CRT vignette effect */
|
||||
.vignette {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 9;
|
||||
background: radial-gradient(
|
||||
ellipse at center,
|
||||
transparent 0%,
|
||||
transparent 60%,
|
||||
rgba(0, 0, 0, 0.4) 100%
|
||||
);
|
||||
}
|
||||
|
||||
/* Button hover effect */
|
||||
.return-btn {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.return-btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.1),
|
||||
transparent
|
||||
);
|
||||
transition: left 0.5s ease;
|
||||
}
|
||||
|
||||
.return-btn:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.return-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 0 20px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="scanlines"></div>
|
||||
<div class="vignette"></div>
|
||||
|
||||
<section class="min-h-screen flex flex-col items-center justify-center px-4 relative z-20">
|
||||
<div class="text-center">
|
||||
<h1 class="glitch font-mono" data-text="404">404</h1>
|
||||
|
||||
<p class="mt-8 text-xl md:text-2xl text-text-secondary font-mono tracking-widest uppercase">
|
||||
Signal Lost
|
||||
</p>
|
||||
|
||||
<div class="mt-12">
|
||||
<a
|
||||
href="/"
|
||||
class="return-btn inline-block px-8 py-4 border border-text-secondary/30 text-text-primary font-mono text-sm tracking-wider uppercase hover:border-text-primary/50 focus:outline-none focus:ring-2 focus:ring-text-primary/30 focus:ring-offset-2 focus:ring-offset-bg-primary"
|
||||
>
|
||||
Return Home
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
||||
Reference in New Issue
Block a user