Added countdown and error-pages
This commit is contained in:
parent
d566a95288
commit
20e62ea01b
3 changed files with 417 additions and 0 deletions
90
static/internal/countdown/index.html
Normal file
90
static/internal/countdown/index.html
Normal file
|
@ -0,0 +1,90 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--
|
||||
(c) Sangelo
|
||||
Simple countdown webpage that can be used as a startpage
|
||||
You can feed the date the counter should be counting down to in the URL like this:
|
||||
http://<countdown>/?date=YYYY-MM-DDTHH:MM:SS
|
||||
-->
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Countdown Timer</title>
|
||||
<style>
|
||||
body {
|
||||
background: radial-gradient(circle, #414144, #202123);
|
||||
background-size: 100% 500%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
font-family: monospace, monospace;
|
||||
color: #ffffff75;
|
||||
}
|
||||
|
||||
#countdown {
|
||||
font-size: 200px;
|
||||
margin: 0 20px;
|
||||
opacity: 1;
|
||||
transition: opacity 0.5s;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.completed {
|
||||
color: #fff; /* Full opacity when countdown is completed */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="countdown">000:00:00:00</div>
|
||||
|
||||
<script async>
|
||||
function formatWithLeadingZeros(number, length) {
|
||||
return number.toLocaleString('en-US', {minimumIntegerDigits: length, useGrouping: false});
|
||||
}
|
||||
|
||||
const countdownElement = document.getElementById("countdown");
|
||||
const countdownDate = getDateFromUrl();
|
||||
|
||||
function updateCountdown() {
|
||||
const now = new Date().getTime();
|
||||
const distance = countdownDate - now;
|
||||
|
||||
if (distance <= 0) {
|
||||
countdownElement.innerHTML = "🥳";
|
||||
countdownElement.classList.add("completed");
|
||||
return;
|
||||
}
|
||||
|
||||
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
|
||||
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
|
||||
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
|
||||
|
||||
const formattedDays = formatWithLeadingZeros(days, 3);
|
||||
const formattedHours = formatWithLeadingZeros(hours, 2);
|
||||
const formattedMinutes = formatWithLeadingZeros(minutes, 2);
|
||||
const formattedSeconds = formatWithLeadingZeros(seconds, 2);
|
||||
|
||||
countdownElement.innerHTML = `${formattedDays}:${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
|
||||
requestAnimationFrame(updateCountdown);
|
||||
}
|
||||
|
||||
function getDateFromUrl() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const dateParam = urlParams.get('date');
|
||||
if (dateParam) {
|
||||
const timestamp = Date.parse(dateParam);
|
||||
if (!isNaN(timestamp)) {
|
||||
return timestamp;
|
||||
}
|
||||
}
|
||||
return new Date("1970-01-01T00:00:00").getTime();
|
||||
}
|
||||
|
||||
requestAnimationFrame(updateCountdown);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
166
static/internal/error/400.html
Normal file
166
static/internal/error/400.html
Normal file
|
@ -0,0 +1,166 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Error {{placeholder "http.error.status_code"}}</title>
|
||||
<style>
|
||||
@import url("https://fonts.cdnfonts.com/css/manrope");
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
height: 100vh;
|
||||
background-color: #121316;
|
||||
color: #fff;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.text {
|
||||
flex: 1 1 50%;
|
||||
padding: 2em;
|
||||
overflow: auto;
|
||||
font-family: "Manrope", sans-serif;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.text h1 {
|
||||
font-size: 80px;
|
||||
margin-bottom: 0;
|
||||
margin-top: 0.2em;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.text h2 {
|
||||
font-size: 40px;
|
||||
font-weight: 500;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.text p {
|
||||
font-weight: 300;
|
||||
font-size: 22px;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.text a.button {
|
||||
text-decoration: none;
|
||||
background-color: #ffffff;
|
||||
padding: 0.6em;
|
||||
padding-left: 1.5em;
|
||||
padding-right: 1.5em;
|
||||
border-radius: 8px;
|
||||
color: #121316;
|
||||
font-weight: 700;
|
||||
transition: opacity ease-in-out 0.3;
|
||||
}
|
||||
|
||||
.text a.button:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.text a.button:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.blob {
|
||||
position: relative;
|
||||
flex: 1 1 50%;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.blob svg {
|
||||
height: 100vh;
|
||||
width: auto;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
@media (max-width: 850px) {
|
||||
.blob {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="text">
|
||||
<h1>{{placeholder "http.error.status_code"}}</h1>
|
||||
<h2>{{placeholder "http.error.status_text"}}</h2>
|
||||
<p>
|
||||
Looks like you got lost in space. Try searching again at planet earth.
|
||||
</p>
|
||||
<a class="button" href="/">Fly back home</a>
|
||||
</div>
|
||||
<div class="blob">
|
||||
<svg
|
||||
width="686"
|
||||
height="1080"
|
||||
viewBox="0 0 686 1080"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g filter="url(#filter0_i_1002_1047)">
|
||||
<path
|
||||
d="M88.6758 136C88.6758 34.6337 0 -8.02344 0 -66H686V1146H0C0 1146 88.6758 1044.94 88.6758 944C88.6758 843.064 0 843.419 0 742.582C0 641.745 88.6758 641.124 88.6758 540C88.6758 438.876 0 439.674 0 338.938C0 238.201 88.6758 237.366 88.6758 136Z"
|
||||
fill="url(#paint0_radial_1002_1047)"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter
|
||||
id="filter0_i_1002_1047"
|
||||
x="0"
|
||||
y="-66"
|
||||
width="689"
|
||||
height="1214"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"
|
||||
>
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="BackgroundImageFix"
|
||||
result="shape"
|
||||
/>
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset dx="3" dy="2" />
|
||||
<feGaussianBlur stdDeviation="4" />
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.35 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="shape"
|
||||
result="effect1_innerShadow_1002_1047"
|
||||
/>
|
||||
</filter>
|
||||
<radialGradient
|
||||
id="paint0_radial_1002_1047"
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(32 540) scale(654 3651.84)"
|
||||
>
|
||||
<stop offset="0.34828" stop-color="#00B2FA" />
|
||||
<stop offset="1" stop-color="#007DFF" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
161
static/internal/error/500.html
Normal file
161
static/internal/error/500.html
Normal file
|
@ -0,0 +1,161 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Error {{placeholder "http.err.status_code"}}</title>
|
||||
<style>
|
||||
@import url("https://fonts.cdnfonts.com/css/manrope");
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
height: 100vh;
|
||||
background-color: #121316;
|
||||
color: #fff;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.text {
|
||||
flex: 1 1 50%;
|
||||
padding: 2em;
|
||||
overflow: auto;
|
||||
font-family: "Manrope", sans-serif;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.text h1 {
|
||||
font-size: 80px;
|
||||
margin-bottom: 0;
|
||||
margin-top: 0.2em;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.text h2 {
|
||||
font-size: 40px;
|
||||
font-weight: 500;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.text p {
|
||||
font-weight: 300;
|
||||
font-size: 22px;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.text a {
|
||||
color: #00c4fb;
|
||||
}
|
||||
|
||||
.text a:hover {
|
||||
opacity: 0.9;
|
||||
color: #00b2fa;
|
||||
}
|
||||
|
||||
.text a:active {
|
||||
opacity: 0.9;
|
||||
color: #0091fb;
|
||||
}
|
||||
|
||||
.blob {
|
||||
position: relative;
|
||||
flex: 1 1 50%;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.blob svg {
|
||||
height: 100vh;
|
||||
width: auto;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
@media (max-width: 850px) {
|
||||
.blob {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="text">
|
||||
<h1>{{placeholder "http.err.status_code"}}</h1>
|
||||
<h2>{{placeholder "http.err.status_text"}}</h2>
|
||||
<p>
|
||||
Looks like the website is down at the moment. Please try again later.<br />If
|
||||
the error persists, contact me at
|
||||
<a href="mailto:me@stelian.net">me@stelian.net</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div class="blob">
|
||||
<svg
|
||||
width="686"
|
||||
height="1080"
|
||||
viewBox="0 0 686 1080"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g filter="url(#filter0_i_1002_1047)">
|
||||
<path
|
||||
d="M88.6758 136C88.6758 34.6337 0 -8.02344 0 -66H686V1146H0C0 1146 88.6758 1044.94 88.6758 944C88.6758 843.064 0 843.419 0 742.582C0 641.745 88.6758 641.124 88.6758 540C88.6758 438.876 0 439.674 0 338.938C0 238.201 88.6758 237.366 88.6758 136Z"
|
||||
fill="url(#paint0_radial_1002_1047)"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter
|
||||
id="filter0_i_1002_1047"
|
||||
x="0"
|
||||
y="-66"
|
||||
width="689"
|
||||
height="1214"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"
|
||||
>
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="BackgroundImageFix"
|
||||
result="shape"
|
||||
/>
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset dx="3" dy="2" />
|
||||
<feGaussianBlur stdDeviation="4" />
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.35 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="shape"
|
||||
result="effect1_innerShadow_1002_1047"
|
||||
/>
|
||||
</filter>
|
||||
<radialGradient
|
||||
id="paint0_radial_1002_1047"
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(32 540) scale(654 3651.84)"
|
||||
>
|
||||
<stop offset="0.34828" stop-color="#00B2FA" />
|
||||
<stop offset="1" stop-color="#007DFF" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
Loading…
Reference in a new issue