Geizkragen/404.php

253 lines
7.6 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// Wichtig: echten 404-Status setzen
http_response_code(404);
// Request-Daten absichern
$requestUri = htmlspecialchars($_SERVER['REQUEST_URI'] ?? '', ENT_QUOTES, 'UTF-8');
$method = htmlspecialchars($_SERVER['REQUEST_METHOD'] ?? '', ENT_QUOTES, 'UTF-8');
// Optional: einfaches Logging
error_log("[404] " . ($_SERVER['REMOTE_ADDR'] ?? '') . " $method $requestUri");
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="/assets/images/favicon.ico" sizes="any">
<link rel="stylesheet" href="/style.css">
<title>404 Seite nicht gefunden | Geizkragen</title>
</head>
<body>
<main>
<div class="container" style="
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
text-align: center;
padding-block: 4rem;
">
<!-- 404 Glitch-Zahl -->
<div class="error-code" aria-hidden="true">404</div>
<!-- Card -->
<div class="error-card">
<div class="error-card__icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round" width="28" height="28">
<circle cx="11" cy="11" r="8"/>
<path d="M21 21l-4.35-4.35"/>
<line x1="8" y1="11" x2="14" y2="11"/>
</svg>
</div>
<h1 class="error-card__title">Seite nicht gefunden</h1>
<p class="error-card__text">
Die Seite, die du suchst, existiert leider nicht oder wurde verschoben.
</p>
<div class="error-card__path"><?php echo $requestUri; ?></div>
<div class="error-card__actions">
<a href="/index.php" class="btn btn--primary">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round" width="18" height="18">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
<polyline points="9 22 9 12 15 12 15 22"/>
</svg>
Zur Startseite
</a>
<button onclick="history.back()" class="btn btn--ghost">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round" width="18" height="18">
<line x1="19" y1="12" x2="5" y2="12"/>
<polyline points="12 19 5 12 12 5"/>
</svg>
Zurück
</button>
</div>
</div>
</div>
</main>
<style>
/* ── 404 Glitch-Zahl ── */
.error-code {
font-size: clamp(7rem, 18vw, 12rem);
font-weight: 900;
line-height: 1;
letter-spacing: -0.04em;
background: linear-gradient(135deg, var(--color-primary), #4f46e5, var(--color-accent));
background-size: 200% 200%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: gradientShift 4s ease-in-out infinite;
margin-bottom: 1.5rem;
position: relative;
display: inline-block;
}
.error-code::before,
.error-code::after {
content: '404';
position: absolute;
top: 0; left: 0; right: 0;
overflow: hidden;
background: inherit;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.error-code::before {
clip-path: inset(0 0 65% 0);
animation: glitch1 3s infinite linear alternate-reverse;
}
.error-code::after {
clip-path: inset(65% 0 0 0);
animation: glitch2 3s infinite linear alternate-reverse;
}
@keyframes glitch1 {
0%,92% { transform: translate(0); }
93% { transform: translate(-6px,-2px); }
94% { transform: translate(3px,1px); }
95% { transform: translate(-2px,2px); }
96%,100%{ transform: translate(0); }
}
@keyframes glitch2 {
0%,90% { transform: translate(0); }
91% { transform: translate(4px,2px); }
92% { transform: translate(-5px,-1px); }
93% { transform: translate(2px,-2px); }
94%,100%{ transform: translate(0); }
}
/* ── Card ── */
.error-card {
background: rgba(31, 41, 55, 0.55);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-xl);
padding: 2.5rem 2.5rem 2rem;
max-width: 520px;
width: 100%;
box-shadow: var(--shadow-md), 0 0 60px var(--color-primary-glow);
animation: fadeInUp 0.6s ease-out 0.1s both;
}
.error-card__icon {
width: 56px;
height: 56px;
margin: 0 auto 1.25rem;
background: var(--color-primary-soft);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: var(--color-primary);
animation: pulse-glow 3s ease-in-out infinite;
}
.error-card__title {
font-size: 1.4rem;
font-weight: 800;
color: var(--text-primary);
margin-bottom: 0.6rem;
}
.error-card__text {
color: var(--text-muted);
font-size: 0.95rem;
line-height: 1.6;
margin-bottom: 0.25rem;
}
.error-card__path {
display: inline-block;
background: var(--color-primary-soft);
border: 1px solid rgba(39, 74, 151, 0.25);
color: #6b8fd8;
font-family: 'Courier New', Courier, monospace;
font-size: 0.82rem;
font-weight: 600;
padding: 0.35rem 0.9rem;
border-radius: var(--radius-md);
margin: 1rem 0 1.5rem;
word-break: break-all;
max-width: 100%;
}
/* ── Buttons ── */
.error-card__actions {
display: flex;
gap: 0.75rem;
justify-content: center;
flex-wrap: wrap;
}
.btn {
display: inline-flex;
align-items: center;
gap: 0.45rem;
padding: 0.7rem 1.4rem;
border-radius: var(--radius-md);
font-size: 0.9rem;
font-weight: 600;
font-family: var(--font-family);
text-decoration: none;
cursor: pointer;
border: none;
transition: all var(--transition-smooth);
}
.btn--primary {
background: var(--color-primary);
color: #fff;
box-shadow: 0 4px 14px var(--color-primary-glow);
}
.btn--primary:hover {
background: var(--color-primary-hover);
transform: translateY(-2px);
box-shadow: 0 8px 24px var(--color-primary-glow);
color: #fff;
}
.btn--ghost {
background: rgba(255,255,255,0.04);
color: var(--text-muted);
border: 1px solid var(--border-subtle);
}
.btn--ghost:hover {
background: rgba(255,255,255,0.09);
color: var(--text-primary);
transform: translateY(-2px);
}
/* ── Responsive ── */
@media (max-width: 480px) {
.error-card {
padding: 1.8rem 1.25rem 1.5rem;
}
.error-card__actions {
flex-direction: column;
}
.btn {
justify-content: center;
width: 100%;
}
}
</style>
</body>
</html>