COMPLETE REDESIGN
This commit is contained in:
parent
46b32793f2
commit
dbfb7fd415
@ -1,3 +1,7 @@
|
||||
# [PKRM.DEV](https://pkrm.dev)
|
||||
|
||||
This is the repo for my personal website ([pkrm.dev](https://pkrm.dev)). Feel free to fork this project or download the code and use it for your needs. Happy coding!
|
||||
This is the repo for my personal website ([pkrm.dev](https://pkrm.dev)).
|
||||
|
||||
Heavily inspired by the "Hello Friend NG" HUGO Theme, found [here](https://github.com/rhazdon/hugo-theme-hello-friend-ng).
|
||||
|
||||
Feel free to fork this project or download the code and use it for your needs. Happy coding!
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 186 KiB |
BIN
app/static/github.png
Normal file
BIN
app/static/github.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
app/static/gnugpg.png
Normal file
BIN
app/static/gnugpg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
app/static/gnupg.png
Normal file
BIN
app/static/gnupg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
@ -1,451 +0,0 @@
|
||||
* {
|
||||
font-family: 'Kanit', sans-serif;
|
||||
margin: 0;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body{
|
||||
overflow-x: hidden;
|
||||
background-image: url(/static/bg.png);
|
||||
background-size: cover;
|
||||
color: #fff;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.fa-angle-down {
|
||||
color: #fff;
|
||||
font-size: 1.823vw;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
bottom: 5.208vw;
|
||||
}
|
||||
|
||||
.fa-angle-down:hover {
|
||||
opacity: .6;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Fixed footer */
|
||||
footer {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
background-color: #0d0d0d;
|
||||
font-size: 1.042vw;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 10;
|
||||
padding: 1.042vw;
|
||||
}
|
||||
|
||||
footer a {
|
||||
text-decoration: underline;
|
||||
color: white
|
||||
}
|
||||
|
||||
footer a:hover {
|
||||
opacity: .6;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Media query for footer on tablets */
|
||||
@media screen and (max-width: 1280px) {
|
||||
footer {
|
||||
font-size: 2.5vw;
|
||||
}
|
||||
}
|
||||
|
||||
/* Media query for footer on mobile */
|
||||
@media screen and (max-width: 600px) {
|
||||
footer {
|
||||
font-size: 5vw;
|
||||
}
|
||||
}
|
||||
|
||||
/* Navbar mobile icons */
|
||||
#hamburger i {
|
||||
font-size: 2.083vw;
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
right: 40px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#x i {
|
||||
font-size: 2.083vw;
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
right: 40px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* Main page (Hi I'm Parker) */
|
||||
#main {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
nav a {
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
font-size: 1.823vw;
|
||||
margin: 0 25px;
|
||||
}
|
||||
|
||||
nav a:hover {
|
||||
opacity: .6;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icons i {
|
||||
font-size: 3.125vw;
|
||||
margin: 1.042vw 50px;
|
||||
}
|
||||
|
||||
.icons i:hover {
|
||||
opacity: .6;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: 8.333vw;
|
||||
}
|
||||
|
||||
header h2 {
|
||||
font-size: 3.125vw;
|
||||
/* animation: bringIn 2s; */
|
||||
padding-right: 50px;
|
||||
}
|
||||
|
||||
/* Main section media query for tablets */
|
||||
@media screen and (max-width: 1280px) {
|
||||
nav a {
|
||||
font-size: 4vw;
|
||||
margin-bottom: 3.646vw;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: 12vw;
|
||||
}
|
||||
|
||||
header h2 {
|
||||
font-size: 7vw;
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
.icons {
|
||||
margin-top: 3vw;
|
||||
}
|
||||
|
||||
.icons i {
|
||||
font-size: 7vw;
|
||||
margin: 0 25px;
|
||||
}
|
||||
|
||||
.fa-angle-down {
|
||||
font-size: 5vw;
|
||||
bottom: 15vw;
|
||||
}
|
||||
}
|
||||
|
||||
/* Main section media query for mobile */
|
||||
@media screen and (max-width: 600px) {
|
||||
#hamburger i,
|
||||
#x i {
|
||||
font-size: 8vw;
|
||||
}
|
||||
nav {
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
nav a {
|
||||
font-size: 7vw;
|
||||
margin-bottom: 15vw;
|
||||
}
|
||||
|
||||
header {
|
||||
flex-direction: column;
|
||||
bottom: 100px;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: 17vw;
|
||||
}
|
||||
|
||||
header h2 {
|
||||
font-size: 12vw;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.icons {
|
||||
flex-direction: row;
|
||||
position: absolute;
|
||||
bottom: 60vw;
|
||||
}
|
||||
|
||||
.icons i {
|
||||
font-size: 12vw;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.fa-angle-down {
|
||||
font-size: 8vw;
|
||||
bottom: 20vw;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the keyframes fade in */
|
||||
@keyframes fadeIn {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes fadeIn {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
/* About me section */
|
||||
#about {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#about h1 {
|
||||
font-size: 4.167vw;
|
||||
margin-bottom: 1.563vw;
|
||||
}
|
||||
|
||||
#about p {
|
||||
font-size: 1.563vw;
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* About section media query for tablets */
|
||||
@media screen and (max-width: 1280px) {
|
||||
#about h1 {
|
||||
font-size: 10vw;
|
||||
}
|
||||
#about p {
|
||||
font-size: 4vw;
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
/* About section media query for mobile */
|
||||
@media screen and (max-width: 600px) {
|
||||
#about h1 {
|
||||
font-size: 12vw;
|
||||
}
|
||||
#about p {
|
||||
font-size: 5vw;
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Slider for Projects - Credit to this codepen - https://codepen.io/maheshambure21/pen/qZZrxy */
|
||||
*, *:before, *:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.slider {
|
||||
height: 100vh;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.slider__nav {
|
||||
width: 1.042vw;
|
||||
height: 1.042vw;
|
||||
margin: 1.042vw 0.521vw;
|
||||
border-radius: 50%;
|
||||
z-index: 10;
|
||||
outline: 14px solid white;
|
||||
outline-offset: -14px;
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.slider__nav:checked {
|
||||
-webkit-animation: check 0.4s linear forwards;
|
||||
animation: check 0.4s linear forwards;
|
||||
}
|
||||
|
||||
.slider__nav:checked:nth-of-type(1) ~ .slider__inner {
|
||||
left: 0%;
|
||||
}
|
||||
|
||||
.slider__nav:checked:nth-of-type(2) ~ .slider__inner {
|
||||
left: -100%;
|
||||
}
|
||||
|
||||
.slider__nav:checked:nth-of-type(3) ~ .slider__inner {
|
||||
left: -200%;
|
||||
}
|
||||
|
||||
.slider__nav:checked:nth-of-type(4) ~ .slider__inner {
|
||||
left: -300%;
|
||||
}
|
||||
|
||||
.slider__inner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 400%;
|
||||
height: 100%;
|
||||
-webkit-transition: left 0.7s;
|
||||
transition: left 0.7s;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
}
|
||||
|
||||
.slider__contents {
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-flow: column nowrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.slider__caption {
|
||||
font-size: 4.167vw;
|
||||
margin: 1.563vw;
|
||||
max-width: 75%;
|
||||
}
|
||||
|
||||
.slider__txt {
|
||||
color: white;
|
||||
max-width: 30%;
|
||||
font-size: 1.563vw;
|
||||
}
|
||||
|
||||
.slider__txt .inner-reference {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.slider__button {
|
||||
font-size: 1.563vw;
|
||||
padding: 0.391vw 1.042vw;
|
||||
border-radius: 5px;
|
||||
background: #333;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
margin-right: 1.042vw;
|
||||
}
|
||||
|
||||
.slider__button:hover {
|
||||
opacity: .6;
|
||||
transition: all .2s ease-in-out;
|
||||
-webkit-transition: all .2s ease-in-out;
|
||||
}
|
||||
|
||||
/* Projects section media query for tablets */
|
||||
@media screen and (max-width: 1280px) {
|
||||
.slider__caption {
|
||||
max-width: 95%;
|
||||
font-size: 10vw;
|
||||
}
|
||||
.slider__txt {
|
||||
font-size: 4vw;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.slider__button {
|
||||
font-size: 4vw;
|
||||
}
|
||||
|
||||
.slider__nav {
|
||||
margin-bottom: 2.64vw;
|
||||
width: 3vw;
|
||||
height: 3vw;
|
||||
margin: 0 2vw 10vw 2vw;
|
||||
}
|
||||
}
|
||||
|
||||
/* Projects section media query for mobile */
|
||||
@media screen and (max-width: 600px) {
|
||||
.slider__caption {
|
||||
font-size: 12vw;
|
||||
max-width: 95%;
|
||||
}
|
||||
.slider__txt {
|
||||
font-size: 5vw;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.slider__button {
|
||||
font-size: 5vw;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 0;
|
||||
margin-bottom: 6vw;
|
||||
}
|
||||
|
||||
.slider__nav {
|
||||
margin-bottom: 2.64vw;
|
||||
width: 5vw;
|
||||
height: 5vw;
|
||||
margin: 0 2vw 10vw 2vw;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes check {
|
||||
50% {
|
||||
outline-color: #333;
|
||||
}
|
||||
100% {
|
||||
outline-color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes check {
|
||||
50% {
|
||||
outline-color: #333;
|
||||
}
|
||||
100% {
|
||||
outline-color: #333;
|
||||
}
|
||||
}
|
@ -1,185 +0,0 @@
|
||||
// Define the variables
|
||||
const hamburger = document.querySelector('.fa-bars');
|
||||
const x = document.querySelector('.fa-times');
|
||||
const nav = document.querySelectorAll('nav')[0];
|
||||
const navOptions = nav.querySelectorAll('a');
|
||||
const main = document.getElementById('main');
|
||||
const mainh1 = main.getElementsByTagName('h1')[0];
|
||||
const mainh2 = main.getElementsByTagName('h2')[0];
|
||||
const iconNav = document.querySelectorAll('nav')[1];
|
||||
const icons = document.querySelectorAll('nav')[1].getElementsByTagName('i');
|
||||
const arrow = document.getElementById('about-text')
|
||||
const projects = document.getElementById('projects');
|
||||
const footer = document.querySelector('footer');
|
||||
|
||||
// If the user is on mobile, remove the fingerprint from the footer, also remove
|
||||
// the down arrow buttons
|
||||
if (window.innerWidth <= 768) {
|
||||
footer.removeChild(footer.lastChild);
|
||||
arrow.style.display = 'none';
|
||||
}
|
||||
|
||||
// If the user is on mobile
|
||||
if (window.innerWidth < 768) {
|
||||
x.style.display = 'none';
|
||||
hamburger.style.display = 'block';
|
||||
nav.style.display = 'none';
|
||||
mobileAnimations();
|
||||
} else {
|
||||
x.style.display = 'none';
|
||||
hamburger.style.display = 'none';
|
||||
nav.style.display = 'flex';
|
||||
desktopAnimations();
|
||||
}
|
||||
|
||||
// Only create listener if the user is on mobile
|
||||
if (window.innerWidth < 768) {
|
||||
// When the hamburger is clicked, show the X and open the menu
|
||||
hamburger.addEventListener('click', function () {
|
||||
hamburger.style.display = 'none';
|
||||
x.style.display = 'block';
|
||||
mainh1.style.display = 'none';
|
||||
mainh2.style.display = 'none';
|
||||
iconNav.style.display = 'none';
|
||||
arrow.style.display = 'none';
|
||||
|
||||
// Slowly fade in the nav with keyframes
|
||||
nav.style.display = 'flex';
|
||||
nav.style.animation = 'fadeIn 0.75s ease-in-out';
|
||||
|
||||
// Lock the scroll
|
||||
document.body.style.overflow = 'hidden';
|
||||
});
|
||||
}
|
||||
|
||||
// Collapse the mobile nav menu
|
||||
function collapseMenu() {
|
||||
hamburger.style.display = 'block';
|
||||
x.style.display = 'none';
|
||||
nav.style.display = 'none';
|
||||
|
||||
// Slowly fade in the h1, h2, icons, and arrow with keyframes
|
||||
mainh1.style.display = 'block';
|
||||
mainh1.style.animation = 'fadeIn 0.75s ease-in-out';
|
||||
mainh2.style.display = 'block';
|
||||
mainh2.style.animation = 'fadeIn 0.75s ease-in-out';
|
||||
iconNav.style.display = 'flex';
|
||||
iconNav.style.animation = 'fadeIn 0.75s ease-in-out';
|
||||
arrow.style.display = 'block';
|
||||
arrow.style.animation = 'fadeIn 0.75s ease-in-out';
|
||||
|
||||
// Unlock the scroll
|
||||
document.body.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
// Only create listener if the user is on mobile
|
||||
if (window.innerWidth < 768) {
|
||||
// When the X is clicked, show the hamburger and close the menu
|
||||
x.addEventListener('click', function () {
|
||||
collapseMenu();
|
||||
});
|
||||
}
|
||||
|
||||
// When a nav link is clicked, close the menu
|
||||
const navLinks = document.querySelectorAll('nav a');
|
||||
navLinks.forEach(function (link) {
|
||||
link.addEventListener('click', function () {
|
||||
// Only collapse the menu if the user is on mobile
|
||||
if (window.innerWidth < 768) {
|
||||
collapseMenu();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Animation for the desktop version
|
||||
function desktopAnimations() {
|
||||
let everythingSlideUp = new mojs.Html({
|
||||
el: main,
|
||||
y: {150: 0},
|
||||
duration: 1000,
|
||||
delay: 250,
|
||||
easing: 'sin.out'
|
||||
}).play();
|
||||
|
||||
let everythingOpacity = new mojs.Html({
|
||||
el: main,
|
||||
opacity: {0: 1},
|
||||
duration: 2000,
|
||||
delay: 250,
|
||||
easing: 'sin.out'
|
||||
}).play();
|
||||
}
|
||||
|
||||
// Animation for the mobile version
|
||||
function mobileAnimations() {
|
||||
let h2ScaleUp = new mojs.Html({
|
||||
el: mainh2,
|
||||
y: {75: 75},
|
||||
opacity: {0: 1},
|
||||
scale: {0.5: 1},
|
||||
duration: 1500,
|
||||
easing: mojs.easing.path('M0,100 C50,100 50,67.578125 50,50 C50,32.421875 50,0 100,0')
|
||||
}).play();
|
||||
|
||||
let h2SlideUp = new mojs.Html({
|
||||
el: mainh2,
|
||||
y: {75: 0},
|
||||
duration: 1500,
|
||||
delay: 1000,
|
||||
easing: mojs.easing.path('M0,100 C50,100 50,67.578125 50,50 C50,32.421875 50,0 100,0')
|
||||
}).play();
|
||||
|
||||
let h1Opacity = new mojs.Html({
|
||||
el: mainh1,
|
||||
opacity: {0: 1},
|
||||
duration: 2000,
|
||||
delay: 1750,
|
||||
easing: 'sin.out'
|
||||
}).play();
|
||||
|
||||
let iconBringIn1 = new mojs.Html({
|
||||
el: icons[0],
|
||||
y: {25: 0},
|
||||
opacity: {0: 1},
|
||||
duration: 1000,
|
||||
delay: 2000,
|
||||
easing: 'sin.out'
|
||||
}).play();
|
||||
|
||||
let iconBringIn2 = new mojs.Html({
|
||||
el: icons[1],
|
||||
y: {25: 0},
|
||||
opacity: {0: 1},
|
||||
duration: 1000,
|
||||
delay: 2250,
|
||||
easing: 'sin.out'
|
||||
}).play();
|
||||
}
|
||||
|
||||
// Rotate the projects every 4 seconds, only for desktop
|
||||
window.onload = slideProjects();
|
||||
function slideProjects() {
|
||||
const inputs = document.querySelectorAll('input');
|
||||
if (window.innerWidth >= 768) {
|
||||
let i = 0;
|
||||
setInterval(() => {
|
||||
if (i == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
inputs[i].checked = true;
|
||||
i++;
|
||||
|
||||
if (i >= inputs.length) {
|
||||
i = 0;
|
||||
}
|
||||
}, 4000);
|
||||
|
||||
// If one of the inputs is clicked, stop the rotation of the projects
|
||||
inputs.forEach(input => {
|
||||
input.addEventListener('click', () => {
|
||||
i = -1;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
BIN
app/static/linkedin.png
Normal file
BIN
app/static/linkedin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
BIN
app/static/mail.png
Normal file
BIN
app/static/mail.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
132
app/templates/about.html
Normal file
132
app/templates/about.html
Normal file
@ -0,0 +1,132 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Home</title>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<div class="navbar-left">
|
||||
<a href="/">~$ cd /home</a>
|
||||
</div>
|
||||
|
||||
<div class="navbar-right">
|
||||
<a href="/about">About</a>
|
||||
<a href="/contact">Contact</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<h1>About Me</h1>
|
||||
<p>I am a senior in high school who enjoys programming and learning more about different technologies. I manage a Debian home server where I self-host tools like: <a href="https://dnscrypt.org" target="_blank" style="text-decoration: underline; color: #9F9FAA">DNSCrypt</a>, <a href="https://github.com/AdguardTeam/AdguardHome" target="_blank" style="text-decoration: underline; color: #9F9FAA">AdGuard</a>, <a href="https://wireguard.org" target="_blank" style="text-decoration: underline; color: #9F9FAA">WireGuard</a>, <a href="https://syncthing.net" target="_blank" style="text-decoration: underline; color: #9F9FAA">Syncthing</a>, and many more media/system management utilities.<br><br>Find my work by viewing my open-sourced repositories on <a href="https://github.com/packetparker" target="_blank" style="text-decoration: underline; color: #9F9FAA">GitHub</a>.</p>
|
||||
</div>
|
||||
|
||||
<footer>PGP Fingerprint: 58B7 6B8B BAB8 794D 21E2 579C 95CD 2E0C 7E32 9F2A</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<style>
|
||||
/* Import Montserrat font */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@200;300;400;500;600;700&display=swap');
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
background-color: #242528;
|
||||
color: #9F9FAA;
|
||||
}
|
||||
|
||||
|
||||
/* Navbar styles */
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1rem 2rem;
|
||||
background-color: #212223;
|
||||
color: #9F9FAA;
|
||||
}
|
||||
|
||||
nav a {
|
||||
text-decoration: none;
|
||||
color: #9F9FAA;
|
||||
font-size: 1.5rem;
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
nav a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.navbar-left {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-left: 15%;
|
||||
}
|
||||
|
||||
.navbar-right {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-right: 15%;
|
||||
}
|
||||
|
||||
/* Navbar media query for mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
nav a {
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.navbar-left {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.navbar-right {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.navbar-right a {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Container styles */
|
||||
.container {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1.75rem;
|
||||
text-align: center;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
/* Continer media query for mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
.container {
|
||||
font-size: 1.25rem;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.container p {
|
||||
margin: 1rem 0 2rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Footer styles */
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
width: 90vw;
|
||||
}
|
||||
</style>
|
@ -2,245 +2,269 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- Add .onion link -->
|
||||
<meta http-equiv="onion-location" content="http://w6rshvdkwg3m757xjsk6avsbwphi3znwlvqpnbcchol6h7wxfzyabayd.onion/contact">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Kanit:wght@200;300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<title>Contact | pkrm.dev</title>
|
||||
|
||||
<meta name="robots" content="index, follow">
|
||||
<meta name="theme-color" content="#000" />
|
||||
<meta name="apple-mobile-web-app-title" content="Parker M. | Contact" />
|
||||
|
||||
<meta property="og:title" content="Parker M. | Contact" />
|
||||
<meta property="og:url" content="https://pkrm.dev" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:description" content="Fill out this form in order to contact me." />
|
||||
|
||||
<meta name="description" content="Fill out this form in order to contact me." />
|
||||
<meta name="robots" content="index, follow" />
|
||||
<meta name="http-equiv" content="X-Robots-Tag : index, follow" />
|
||||
<meta name="googlebot" content="index, follow" />
|
||||
|
||||
<meta http-equiv="Onion-Location" content="http://dazz5im5t55mdzyfgegonv4d5nug2bt5nzck4m7zhqwynxo3xcvc77ad.onion/contact">
|
||||
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<script src="/static/contact.js" defer></script>
|
||||
<title>Home</title>
|
||||
</head>
|
||||
<body>
|
||||
<a href="/" id="back-home">Back Home</a>
|
||||
<nav>
|
||||
<div class="navbar-left">
|
||||
<a href="/">~$ cd /home</a>
|
||||
</div>
|
||||
|
||||
<div class="navbar-right">
|
||||
<a href="/about">About</a>
|
||||
<a href="/contact">Contact</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<p id="attention">ATTENTION: To send any sensitive information, please email me at <a href="mailto:contact@pkrm.dev" id="contact-email">contact@pkrm.dev</a> and encrypt the message with my <a href="/static/contact.asc" id="pgp-key">PGP public key</a>. This form should not be thought of as a secure way of communication.</p>
|
||||
<form actions="/contact" method="POST" name="contact" onsubmit="event.preventDefault(); checkForm();">
|
||||
<input name="name" placeholder="Name">
|
||||
<input name="email" placeholder="Email">
|
||||
<h1>Contact Me</h1>
|
||||
|
||||
<form action="/contact" method="POST">
|
||||
<input type="text" name="name" placeholder="Name">
|
||||
<input type="text" name="email" placeholder="Email">
|
||||
<textarea name="message" placeholder="Message"></textarea>
|
||||
<button>Send</button>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
|
||||
{% if success %}
|
||||
<p class="success">Thank you for contacting me! I will get back to you soon.</p>
|
||||
<p class="success-message">Thank you for contacting me. I'll get back soon.</p>
|
||||
{% endif %}
|
||||
{% if error %}
|
||||
<p class="error">There was an error sending your message. Please try again later.</p>
|
||||
<p class="error-message">An error occured, please try again later.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<footer>PGP Fingerprint: 58B7 6B8B BAB8 794D 21E2 579C 95CD 2E0C 7E32 9F2A</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
const nameInput = document.querySelector('input[name="name"]');
|
||||
const email = document.querySelector('input[name="email"]');
|
||||
const message = document.querySelector('textarea[name="message"]');
|
||||
|
||||
window.onload = validateForm();
|
||||
|
||||
function validateForm() {
|
||||
nameInput.addEventListener('input', () => {
|
||||
if (nameInput.value.length > 0) {
|
||||
nameInput.style.border = '2px solid #242424';
|
||||
} else {
|
||||
nameInput.style.border = '2px solid #FA5B5B';
|
||||
}
|
||||
});
|
||||
|
||||
email.addEventListener('input', () => {
|
||||
if (email.value.length > 0) {
|
||||
email.style.border = '2px solid #242424';
|
||||
} else {
|
||||
email.style.border = '2px solid #FA5B5B';
|
||||
}
|
||||
});
|
||||
|
||||
message.addEventListener('input', () => {
|
||||
if (message.value.length > 0) {
|
||||
message.style.border = '2px solid #242424';
|
||||
} else {
|
||||
message.style.border = '2px solid #FA5B5B';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function checkForm() {
|
||||
// If nothing is empty, submit
|
||||
if (nameInput.value.length > 0 && email.value.length > 0 && message.value.length > 0) {
|
||||
document.forms['contact'].submit();
|
||||
// Otherwise, outline the empty fields in red
|
||||
} else {
|
||||
if (nameInput.value.length == 0) {
|
||||
nameInput.style.border = '2px solid #FA5B5B';
|
||||
}
|
||||
|
||||
if (email.value.length == 0) {
|
||||
email.style.border = '2px solid #FA5B5B';
|
||||
}
|
||||
|
||||
if (message.value.length == 0) {
|
||||
message.style.border = '2px solid #FA5B5B';
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* Import Montserrat font */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@200;300;400;500;600;700&display=swap');
|
||||
|
||||
* {
|
||||
font-family: 'Kanit', sans-serif;
|
||||
margin: 0;
|
||||
scroll-behavior: smooth;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
background-image: url(/static/bg.png);
|
||||
background-size: cover;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #242528;
|
||||
color: #9F9FAA;
|
||||
}
|
||||
|
||||
#back-home {
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
padding-top: 2.604vw;
|
||||
font-size: 2.083vw;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
cursor: pointer;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* "Back Home" media query for mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
#back-home {
|
||||
font-size: 7vw;
|
||||
padding-top: 4.167vw;
|
||||
width: 90%;
|
||||
/* Navbar styles */
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1rem 2rem;
|
||||
background-color: #212223;
|
||||
color: #9F9FAA;
|
||||
}
|
||||
|
||||
nav a {
|
||||
text-decoration: none;
|
||||
color: #9F9FAA;
|
||||
font-size: 1.5rem;
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
nav a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.navbar-left {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-left: 15%;
|
||||
}
|
||||
|
||||
.navbar-right {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-right: 15%;
|
||||
}
|
||||
|
||||
/* Navbar media query for mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
nav a {
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.navbar-left {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.navbar-right {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.navbar-right a {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Container styles */
|
||||
.container {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1.75rem;
|
||||
text-align: center;
|
||||
border: 1px solid #9F9FAA;
|
||||
border-radius: 5px;
|
||||
padding: 2rem;
|
||||
height: 450px;
|
||||
width: 550px;
|
||||
}
|
||||
|
||||
/* Container media query for mobile */
|
||||
.container h1 {
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
|
||||
/* Continer media query for mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
.container {
|
||||
position: absolute;
|
||||
top: 60%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1.25rem;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.container h1 {
|
||||
margin: 0 0 2rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
#attention {
|
||||
font-size: 1.302vw;
|
||||
text-align: center;
|
||||
margin: 0.521vw;
|
||||
}
|
||||
|
||||
/* Attention media query for mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
#attention, #attention a {
|
||||
font-size: 5vw;
|
||||
}
|
||||
}
|
||||
|
||||
#pgp-key, #contact-email {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
font-size: 1.302vw;
|
||||
}
|
||||
|
||||
/* Form styles */
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 10px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
form input, form textarea, form button {
|
||||
color: white;
|
||||
background-color: #242424;
|
||||
border: 2px solid #242424;
|
||||
border-radius: 10px;
|
||||
padding: 0.521vw;
|
||||
margin: 0.521vw;
|
||||
width: 50vw;
|
||||
font-size: 1.563vw;
|
||||
resize: none;
|
||||
input {
|
||||
margin: 0.75rem 0;
|
||||
padding: 0.5rem 1rem;
|
||||
border: 1px solid #9F9FAA;
|
||||
border-radius: 5px;
|
||||
background-color: #242528;
|
||||
color: #9F9FAA;
|
||||
font-size: 1.25rem;
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
form button {
|
||||
width: 20vw;
|
||||
}
|
||||
|
||||
form button:hover {
|
||||
input[type="submit"] {
|
||||
width: calc(500px + 2rem);
|
||||
cursor: pointer;
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
textarea {
|
||||
margin: 0.75rem 0;
|
||||
padding: 0.5rem 1rem;
|
||||
border: 1px solid #9F9FAA;
|
||||
border-radius: 5px;
|
||||
background-color: #242528;
|
||||
color: #9F9FAA;
|
||||
font-size: 1.25rem;
|
||||
height: 100px;
|
||||
width: 500px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
/* Form media query for mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
form input, form textarea, form button {
|
||||
width: 70vw;
|
||||
font-size: 7vw;
|
||||
margin: 5px;
|
||||
input {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
form button {
|
||||
width: 50vw;
|
||||
margin-left: 50%;
|
||||
input[type="submit"] {
|
||||
width: calc(250px + 2rem);
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Success/Error messages */
|
||||
.success-message {
|
||||
color: #71A172;
|
||||
font-size: 1.25rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: #B16161;
|
||||
font-size: 1.25rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
|
||||
/* Footer styles */
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
.success {
|
||||
font-size: 1.302vw;
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
color: #73C276;
|
||||
}
|
||||
|
||||
|
||||
.error {
|
||||
font-size: 1.302vw;
|
||||
text-align: center;
|
||||
color: #FA5B5B
|
||||
}
|
||||
|
||||
/* Response media query for mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
.error,
|
||||
.success {
|
||||
font-size: 3.125vw;
|
||||
}
|
||||
margin-bottom: 2rem;
|
||||
width: 90vw;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Get the form
|
||||
const form = document.querySelector('form');
|
||||
|
||||
// Get the inputs
|
||||
const nameInput = document.querySelector('input[name="name"]');
|
||||
const email = document.querySelector('input[name="email"]');
|
||||
const message = document.querySelector('textarea[name="message"]');
|
||||
|
||||
// For each input, if it is empty, make the border red
|
||||
form.addEventListener('submit', (e) => {
|
||||
if (nameInput.value === '') {
|
||||
e.preventDefault();
|
||||
nameInput.style.borderColor = '#B16161';
|
||||
}
|
||||
|
||||
if (email.value === '') {
|
||||
e.preventDefault();
|
||||
email.style.borderColor = '#B16161';
|
||||
}
|
||||
|
||||
if (message.value === '') {
|
||||
e.preventDefault();
|
||||
message.style.borderColor = '#B16161';
|
||||
}
|
||||
});
|
||||
|
||||
// If the user starts typing in an input, make the border grey
|
||||
nameInput.addEventListener('input', () => {
|
||||
nameInput.style.borderColor = '#9F9FAA';
|
||||
});
|
||||
|
||||
email.addEventListener('input', () => {
|
||||
email.style.borderColor = '#9F9FAA';
|
||||
});
|
||||
|
||||
message.addEventListener('input', () => {
|
||||
message.style.borderColor = '#9F9FAA';
|
||||
});
|
||||
|
||||
// On form submit, make sure all inputs are filled out
|
||||
form.addEventListener('submit', (e) => {
|
||||
if (nameInput.value === '' || email.value === '' || message.value === '') {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
</script>
|
@ -2,121 +2,164 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- Add .onion link -->
|
||||
<meta http-equiv="onion-location" content="http://w6rshvdkwg3m757xjsk6avsbwphi3znwlvqpnbcchol6h7wxfzyabayd.onion/">
|
||||
<!-- import font awesome through CDN link -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Kanit:wght@200;300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<title>Parker | pkrm.dev</title>
|
||||
|
||||
<meta name="robots" content="index, follow">
|
||||
<meta name="theme-color" content="#000" />
|
||||
<meta name="apple-mobile-web-app-title" content="Parker M." />
|
||||
|
||||
<meta property="og:title" content="Parker M." />
|
||||
<meta property="og:url" content="https://pkrm.dev" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:description" content="This is my website. Take a look around." />
|
||||
|
||||
<meta name="description" content="This is my website. Take a look around." />
|
||||
<meta name="robots" content="index, follow" />
|
||||
<meta name="http-equiv" content="X-Robots-Tag : index, follow" />
|
||||
<meta name="googlebot" content="index, follow" />
|
||||
|
||||
<meta name="twitter:card" content="summary" />
|
||||
|
||||
<link rel="stylesheet" href="static/index.css">
|
||||
<script src="/static/index.js" defer></script>
|
||||
<title>Home</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<section id="main">
|
||||
<a id="hamburger"><i class="fa-solid fa-bars"></i></a>
|
||||
<a id="x"><i class="fa-solid fa-times"></i></a>
|
||||
|
||||
<nav>
|
||||
<a href="#home">Home</a>
|
||||
<a href="#about">About</a>
|
||||
<!-- Send to 'end' otherwise the carousel points at the bottom won't appear because of
|
||||
the footer covering them -->
|
||||
<a href="#end">Projects</a>
|
||||
<div class="navbar-left">
|
||||
<a href="/">~$ cd /home</a>
|
||||
</div>
|
||||
|
||||
<div class="navbar-right">
|
||||
<a href="/about">About</a>
|
||||
<a href="/contact">Contact</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<header>
|
||||
<h2>Hi, I'm</h2>
|
||||
<h1>PARKER</h1>
|
||||
</header>
|
||||
<div class="container">
|
||||
<h1>Hello, I'm Parker</h1>
|
||||
<p>A student with a strong passion for technology and privacy.</p>
|
||||
|
||||
<nav class="icons">
|
||||
<a href="https://github.com/PacketParker" target="_blank"><i class="fa-brands fa-github"></i></a>
|
||||
<a href="mailto:contact@pkrm.dev" target="_blank"><i class="fa-solid fa-envelope"></i></a>
|
||||
</nav>
|
||||
<a href="mailto:contact@pkrm.dev" target="_blank"><img class="icons" src="{{ url_for('static', filename='mail.png') }}"></a>
|
||||
<a href="https://github.com/packetparker" target="_blank"><img class="icons" src="{{ url_for('static', filename='github.png') }}"></a>
|
||||
<!-- <a href="https://linkedin.com" target="_blank"><img class="icons" src="{{ url_for('static', filename='linkedin.png') }}"></a> -->
|
||||
<a href="/pgp" target="_blank"><img class="icons" src="{{ url_for('static', filename='gnupg.png') }}"></a>
|
||||
</div>
|
||||
|
||||
<a href="#about" id="about-text"><i class="fa fa-angle-down"></i></a>
|
||||
</section>
|
||||
|
||||
<section id="about">
|
||||
<h1>About Me</h1>
|
||||
<p>I am a Senior in high school and enjoy learning about new technologies. I currently use HTML/CSS, Python, Javascript, and SQL. I have competed at the district and state levels in SkillsUSA for Cybersecurity and Programming, and have placed 2nd for the Congressional App Challenge. This year I plan on learning more about web3 and artificial intelligence.</p>
|
||||
<!-- Link to 'end' rather than 'projects' otherwise it wouldn't go to the bottom completely -->
|
||||
<a href="#end" id="projects-text"><i class="fa fa-angle-down"></i></a>
|
||||
</section>
|
||||
|
||||
<section id="projects">
|
||||
<div class="slider">
|
||||
<input type="radio" name="slider" title="slide1" checked="checked" class="slider__nav"/>
|
||||
<input type="radio" name="slider" title="slide2" class="slider__nav"/>
|
||||
<input type="radio" name="slider" title="slide3" class="slider__nav"/>
|
||||
<input type="radio" name="slider" title="slide4" class="slider__nav"/>
|
||||
<div class="slider__inner">
|
||||
<div class="slider__contents">
|
||||
<h2 class="slider__caption">PeakPass</h2>
|
||||
<p class="slider__txt">
|
||||
PeakPass is a password manager that also doubles as a tool to check your passwords against those that have been affected in previous data breaches. Along with this we offer a blog to teach users about standards that keep them safe online.
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://github.com/peakpass/peakpass" target="_blank" referrerpolicy="no-referrer" class="slider__button">Source Code</a>
|
||||
<a href="https://peakpass.pkrm.dev" target="_blank" referrerpolicy="no-referrer" class="slider__button">View Site</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="slider__contents">
|
||||
<h2 class="slider__caption">Aqua Bot</h2>
|
||||
<p class="slider__txt">
|
||||
A multipurpose Discord bot made with the discord.py 2.0 library. Aqua Bot has features like moderation, an economy, gambling. In addition to this, users can play music from YouTube, Spotify, and SoundCloud thanks to lavalink.py
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://github.com/PacketParker/aquabot" target="_blank" referrerpolicy="no-referrer" class="slider__button">Source Code</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="slider__contents">
|
||||
<h2 class="slider__caption">VaultCheck</h2>
|
||||
<p class="slider__txt">
|
||||
Uses the bitwarden-cli tool, the Twilio API, and the HaveIBeenPwned API in order to check your vault for leaked passwords. If a compromised password is found, it alerts you with a text message.
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://github.com/PacketParker/bitwarden-password-checker" target="_blank" referrerpolicy="no-referrer" class="slider__button">Source Code</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="slider__contents">
|
||||
<h2 class="slider__caption">Messagearr</h2>
|
||||
<p class="slider__txt">
|
||||
Docker container that has integration with <a href="https://radarr.video/" class="inner-reference">Radarr</a> in order to allow users to request movies to be downloaded through text messaging. Currently supports the Twilio and Telnyx messaging APIs.
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://github.com/PacketParker/messagearr" target="_blank" referrerpolicy="no-referrer" class="slider__button">Source Code</a>
|
||||
<a href="https://hub.docker.com/r/packetparker/messagearr" target="_blank" referrerpolicy="no-referrer" class="slider__button">Docker Hub</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer><a title="My PGP Public Key" href="/static/contact.asc">PGP Public Key</a>  Fingerprint: 58B7 6B8B BAB8 794D 21E2 579C 95CD 2E0C 7E32 9F2A</footer>
|
||||
<a id="end"></a>
|
||||
<footer>PGP Fingerprint: 58B7 6B8B BAB8 794D 21E2 579C 95CD 2E0C 7E32 9F2A</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/@mojs/core"></script>
|
||||
<style>
|
||||
/* Import Montserrat font */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@200;300;400;500;600;700&display=swap');
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
background-color: #242528;
|
||||
color: #9F9FAA;
|
||||
}
|
||||
|
||||
|
||||
/* Navbar styles */
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1rem 2rem;
|
||||
background-color: #212223;
|
||||
color: #9F9FAA;
|
||||
}
|
||||
|
||||
nav a {
|
||||
text-decoration: none;
|
||||
color: #9F9FAA;
|
||||
font-size: 1.5rem;
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
nav a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.navbar-left {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-left: 15%;
|
||||
}
|
||||
|
||||
.navbar-right {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-right: 15%;
|
||||
}
|
||||
|
||||
/* Navbar media query for mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
nav a {
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.navbar-left {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.navbar-right {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.navbar-right a {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Container styles */
|
||||
.container {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1.75rem;
|
||||
text-align: center;
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
.container h1 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.container p {
|
||||
margin: 2rem 0 3rem 0;
|
||||
}
|
||||
|
||||
.icons {
|
||||
margin: 0 1rem;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
color: #9F9FAA;
|
||||
}
|
||||
|
||||
.icons:hover {
|
||||
cursor: pointer;
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.25s ease-in-out;
|
||||
|
||||
}
|
||||
|
||||
/* Continer media query for mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
.container {
|
||||
font-size: 1.5rem;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.container p {
|
||||
margin: 1rem 0 2rem 0;
|
||||
}
|
||||
|
||||
.icons {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Footer styles */
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
width: 90vw;
|
||||
}
|
||||
</style>
|
169
app/templates/pgp.html
Normal file
169
app/templates/pgp.html
Normal file
@ -0,0 +1,169 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Home</title>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<div class="navbar-left">
|
||||
<a href="/">~$ cd /home</a>
|
||||
</div>
|
||||
|
||||
<div class="navbar-right">
|
||||
<a href="/about">About</a>
|
||||
<a href="/contact">Contact</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<h1>Copy my key below, or click <a href="/parker.asc" style="text-decoration: underline; color: #9F9FAA;">here</a> to download it.</h1>
|
||||
<p>
|
||||
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
<br><br>
|
||||
xjMEZI06YRYJKwYBBAHaRw8BAQdAxymP7jguJxjtKKqGQ/fSXGwZVzOiix6iRS1F
|
||||
6BVMu+3NG1BhcmtlciBNIDxjb250YWN0QHBrcm0uZGV2PsKTBBMWCgA7FiEEWLdr
|
||||
i7q4eU0h4leclc0uDH4ynyoFAmSNOmECGwMFCwkIBwICIgIGFQoJCAsCBBYCAwEC
|
||||
HgcCF4AACgkQlc0uDH4ynyrBIAEAu7y2oebvsBb+tJXPUOZkjqE+rsAwiDgHLj3U
|
||||
gYMM4XUBALPsZ4IgA5mWhTDTV00QLHmVtybCJzCdc7LzyvQH78cHzjgEZI06YRIK
|
||||
KwYBBAGXVQEFAQEHQLBpSX+qSOtSFVrp9+VfJGHsoPaIhoxIjz44byrtLXZ4AwEI
|
||||
B8J4BBgWCgAgFiEEWLdri7q4eU0h4leclc0uDH4ynyoFAmSNOmECGwwACgkQlc0u
|
||||
DH4ynyqQhAEAuo1HGXEKkBUzji+cCW3wF/oqg0cQklQzfKUkifLhiC8A/2gdilxS
|
||||
AYHKY0lEJandkOjid/otDdiIZCUBt5mXjncL
|
||||
=ni8o
|
||||
<br>
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<footer>PGP Fingerprint: 58B7 6B8B BAB8 794D 21E2 579C 95CD 2E0C 7E32 9F2A</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<style>
|
||||
/* Import Montserrat font */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@200;300;400;500;600;700&display=swap');
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
background-color: #242528;
|
||||
color: #9F9FAA;
|
||||
}
|
||||
|
||||
|
||||
/* Navbar styles */
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1rem 2rem;
|
||||
background-color: #212223;
|
||||
color: #9F9FAA;
|
||||
}
|
||||
|
||||
nav a {
|
||||
text-decoration: none;
|
||||
color: #9F9FAA;
|
||||
font-size: 1.5rem;
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
nav a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.navbar-left {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-left: 15%;
|
||||
}
|
||||
|
||||
.navbar-right {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-right: 15%;
|
||||
}
|
||||
|
||||
/* Navbar media query for mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
nav a {
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.navbar-left {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.navbar-right {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.navbar-right a {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Container styles */
|
||||
.container {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 1.25rem;
|
||||
text-align: center;
|
||||
width: 600px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.container p {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Continer media query for mobile */
|
||||
@media only screen and (max-width: 600px) {
|
||||
.container {
|
||||
font-size: 1.25rem;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.container p {
|
||||
margin: 1rem 0 2rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Footer styles */
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
width: 90vw;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Get the h1
|
||||
const h1 = document.querySelector('h1');
|
||||
|
||||
// Get the p tag
|
||||
const p = document.querySelector('p');
|
||||
|
||||
// If the user is on mobile, remove the p tag and change the h1
|
||||
if (window.innerWidth <= 600) {
|
||||
p.remove();
|
||||
h1.innerHTML = 'Click <a href="/parker.asc" style="text-decoration: underline; color: #9F9FAA;">here</a> to download my PGP key.';
|
||||
h1.style.wordBreak = 'normal';
|
||||
}
|
||||
</script>
|
14
app/views.py
14
app/views.py
@ -4,7 +4,6 @@ import discord
|
||||
import dotenv
|
||||
|
||||
app = flask.Flask(__name__)
|
||||
app.secret_key = os.urandom(32)
|
||||
dotenv.load_dotenv()
|
||||
webhook_url = os.getenv("WEBHOOK_URL")
|
||||
|
||||
@ -12,6 +11,10 @@ webhook_url = os.getenv("WEBHOOK_URL")
|
||||
def index():
|
||||
return flask.render_template('index.html')
|
||||
|
||||
@app.route('/about', methods=['GET'])
|
||||
def about():
|
||||
return flask.render_template('about.html')
|
||||
|
||||
@app.route('/contact', methods=['GET', 'POST'])
|
||||
def contact():
|
||||
if flask.request.method == 'GET':
|
||||
@ -36,3 +39,12 @@ def contact():
|
||||
# If any error happens for any reason, return the contact page with error
|
||||
except:
|
||||
return flask.render_template('contact.html', error=True)
|
||||
|
||||
@app.route('/pgp', methods=['GET'])
|
||||
def pgp():
|
||||
return flask.render_template('pgp.html')
|
||||
|
||||
@app.route('/parker.asc', methods=['GET'])
|
||||
def parker():
|
||||
# Send the file to download
|
||||
return flask.send_file('static/parker.asc', as_attachment=True)
|
Loading…
x
Reference in New Issue
Block a user