diff --git a/img/bg-projects.jpg b/img/bg-projects.jpg new file mode 100644 index 0000000..a30e4b7 Binary files /dev/null and b/img/bg-projects.jpg differ diff --git a/img/bg-social.jpg b/img/bg-social.jpg new file mode 100644 index 0000000..d3b830f Binary files /dev/null and b/img/bg-social.jpg differ diff --git a/img/bg.jpeg b/img/bg.jpeg deleted file mode 100644 index a553e3f..0000000 Binary files a/img/bg.jpeg and /dev/null differ diff --git a/img/bg.jpg b/img/bg.jpg new file mode 100644 index 0000000..24e6214 Binary files /dev/null and b/img/bg.jpg differ diff --git a/img/ce.jpg b/img/ce.jpg new file mode 100644 index 0000000..4d56a82 Binary files /dev/null and b/img/ce.jpg differ diff --git a/img/cw.jpeg b/img/cw.jpeg new file mode 100644 index 0000000..a86d1a8 Binary files /dev/null and b/img/cw.jpeg differ diff --git a/img/gm.png b/img/gm.png new file mode 100644 index 0000000..8bc0fef Binary files /dev/null and b/img/gm.png differ diff --git a/img/icon/discord.svg b/img/icon/discord.svg index f913d53..af8a4cc 100644 --- a/img/icon/discord.svg +++ b/img/icon/discord.svg @@ -3,4 +3,4 @@ - \ No newline at end of file + diff --git a/img/icon/email.svg b/img/icon/email.svg new file mode 100644 index 0000000..1108106 --- /dev/null +++ b/img/icon/email.svg @@ -0,0 +1,4 @@ + + + + diff --git a/img/icon/github.svg b/img/icon/github.svg index 8b8d58f..3c815c6 100644 --- a/img/icon/github.svg +++ b/img/icon/github.svg @@ -3,4 +3,4 @@ - \ No newline at end of file + diff --git a/img/icon/kofi.svg b/img/icon/kofi.svg index adbb90d..230e408 100644 --- a/img/icon/kofi.svg +++ b/img/icon/kofi.svg @@ -1 +1,4 @@ - \ No newline at end of file + + + diff --git a/img/icon/linkedin.svg b/img/icon/linkedin.svg new file mode 100644 index 0000000..db243c5 --- /dev/null +++ b/img/icon/linkedin.svg @@ -0,0 +1,4 @@ + + + diff --git a/img/icon/modrinth.svg b/img/icon/modrinth.svg index 64471da..f1fdd86 100644 --- a/img/icon/modrinth.svg +++ b/img/icon/modrinth.svg @@ -1 +1,4 @@ - \ No newline at end of file + + + diff --git a/img/icon/spotify.svg b/img/icon/spotify.svg new file mode 100644 index 0000000..4bc9ac1 --- /dev/null +++ b/img/icon/spotify.svg @@ -0,0 +1,5 @@ + + + + diff --git a/img/icon/steam.svg b/img/icon/steam.svg index 35d5048..091e58b 100644 --- a/img/icon/steam.svg +++ b/img/icon/steam.svg @@ -1,6 +1,9 @@ - - - - + + + + diff --git a/img/icon/website.svg b/img/icon/website.svg new file mode 100644 index 0000000..35bb777 --- /dev/null +++ b/img/icon/website.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/img/icon/youtube.svg b/img/icon/youtube.svg index fa75d67..87777a9 100644 --- a/img/icon/youtube.svg +++ b/img/icon/youtube.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/img/meapi.png b/img/meapi.png new file mode 100644 index 0000000..eb81f3f Binary files /dev/null and b/img/meapi.png differ diff --git a/img/minecraft-hobbit-hole.jpeg b/img/minecraft-hobbit-hole.jpeg deleted file mode 100644 index 9f827c6..0000000 Binary files a/img/minecraft-hobbit-hole.jpeg and /dev/null differ diff --git a/img/ps.jpeg b/img/ps.jpeg new file mode 100644 index 0000000..272649c Binary files /dev/null and b/img/ps.jpeg differ diff --git a/index.html b/index.html index 49cb8f6..16da5e2 100644 --- a/index.html +++ b/index.html @@ -13,97 +13,255 @@ + - -
-
YouHaveTrouble's avatar by PikachuTurnip
-
-

Online status unknown

-

-
-
-

- Hi! I'm Trouble, and I'm currently working as a fullstack developer. In my free time I enjoy working on my - side projects that mostly include programming. I'm extremely passionate about games and what goes into - creating them. I'm also "that one person" of every friend group that sets game servers up! Additionally, - I own and am slowly learning bass. -

-
-
+
-
-

Featured Projects

-
- -
-
-
+
+ +
+

Censura

+

+ Minecraft plugin for bukkit-based servers that cancels messages, item renames, writing in books + or signs if they contain blacklisted words or regex expressions. +

+ +
+
+
+ +
+

Guild Master

+

+ Guild Master is a web browser game about managing a guild of adventurers. It is currently in + early development, but is already playable. +

+ +
+
+
+ +
+

Me API

+

+ API that allows you to query your current activity, status and game profiles. +

+ +
+
-
-
-

Socials

- -
- - + + Spotify + Spotify + + + LinkedIn + LinkedIn + + + Email + Email + + +
- diff --git a/index.js b/index.js index 07191cb..1db0de7 100644 --- a/index.js +++ b/index.js @@ -1,45 +1,68 @@ -const status = document.querySelector("#status"); -const action = document.querySelector("#status-action"); -const avatar = document.querySelector(".avatar"); +const sections = document.querySelectorAll('main section'); +const navLinks = document.querySelectorAll('[data-link]'); -updateStatus(); -window.setInterval(updateStatus, 10000); +const observer = new IntersectionObserver((entries) => { + if (window.innerWidth <= 767) return; + entries.forEach(entry => { + if (entry.isIntersecting) { + const sectionId = entry.target.id; + setActiveLink(sectionId); + } + }); +}, { + root: null, + rootMargin: '-20% 0px -20% 0px', + threshold: 0.3 +}); -async function updateStatus() { - const result = await fetch("https://api.youhavetrouble.me/online"); +const mobileObserver = new IntersectionObserver((entries) => { + if (window.innerWidth > 767) return; + entries.forEach(entry => { + if (entry.isIntersecting) { + const sectionId = entry.target.id; + setActiveLink(sectionId); + } + }); +}, { + root: null, + rootMargin: '-30% 0px -30% 0px', + threshold: 0.1 +}); - if (result.status !== 200) return; +sections.forEach(section => { + observer.observe(section); + mobileObserver.observe(section); +}); - const json = await result.json(); - switch (json.steam.status) { - case "ONLINE": - status.innerText = "Currently Online"; - action.innerText = ""; - setavatarBg("online") - return; - case "IN_GAME": - status.innerText = "Currently Online"; - action.innerText = `Playing ${json.steam.game}`; - setavatarBg("online") - return; - } - - if (json.discord === "DO_NOT_DISTURB" || json.discord === "ONLINE") { - status.innerText = "Currently Online"; - action.innerText = ""; - setavatarBg("online") - return; - } - - status.innerText = "Currently Offline"; - action.innerText = ""; - setavatarBg("offline") +function setActiveLink(sectionId) { + navLinks.forEach(link => { + link.classList.remove('active'); + if (link.getAttribute('data-link') === sectionId) { + link.classList.add('active'); + } + }); } -function setavatarBg(status) { - if (status === "online") { - avatar.style.backgroundColor = "#5a9a5a" - } else if (status === "offline") { - avatar.style.backgroundColor = "#a62d2d" + +/** Shuffle data-info elements */ +function shuffleArray(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; } } + +const dataInfo = document.querySelector("[data-info]"); +const dataInfoElements = []; +for (const element of dataInfo.children) { + dataInfoElements.push(element); +} +shuffleArray(dataInfoElements); +dataInfo.innerHTML = ""; +for (const element of dataInfoElements) { + dataInfo.appendChild(element); +} + + + + diff --git a/main.css b/main.css index 0791af4..ea436ef 100644 --- a/main.css +++ b/main.css @@ -1,302 +1,325 @@ -@import url('https://fonts.googleapis.com/css2?family=Open+Sans&display=swap'); :root { - margin: 0; - padding: 0; - --max-width: 40rem; -} - -::-moz-selection { - background: rgba(255,255,255, 0.2); -} - -::selection { - background: rgba(255,255,255, 0.2); + --text-color: #cccccc; + --text-color-highlight: #ffffff; + scroll-behavior: smooth; } html { - font-family: 'Open Sans', sans-serif; - color: white; - background-size: cover; - font-size: 1.2em; + font-family: system-ui, sans-serif; + font-weight: normal; + color: var(--text-color); } + body { - margin: 0; - background-color: rgba(16, 16, 16, 0.7); display: flex; - flex-direction: column; - align-items: center; - gap: 1rem; - width: 100%; - min-height: 100vh; - padding: 0; - background-image: url("img/bg.jpeg"); - background-position: center; - background-attachment: fixed; + flex-direction: row; + justify-content: start; + align-items: start; + color: var(--text-color); + background-image: url("/img/bg.jpg"); + background-repeat: no-repeat; background-size: cover; - background-blend-mode: overlay; + background-blend-mode: darken; + background-color: rgba(0, 0, 0, 0.65); + background-attachment: fixed; + background-position: center; } -small { - font-size: 0.6rem; -} - -p, h1, h2, h3, h4, h5, h6 { - text-align: center; +hr { + border: none; + border-bottom: 1px solid var(--text-color); + width: 100%; margin: 0; } -a { - text-decoration: none; +.text-center { + text-align: center; } -h2 { - font-size: 1.1rem; -} - -header { - padding-block: 2rem; - padding-inline: 1rem; +nav { + padding-block: 0.5rem; + background-color: #232323; + width: 2rem; + height: 150vh; display: flex; + position: fixed; flex-direction: column; - justify-content: center; - align-items: center; - gap: 1rem; + justify-content: start; + padding-top: 10%; + overflow: clip; +} + +nav a { + writing-mode: tb-rl; + transform: rotate(-180deg); + color: #cccccc; + padding-block: 0.2rem; + padding-inline: 0.5rem; + transition: background-color 0.2s, color 0.2s; +} + +nav a.active { + background-color: rgba(255,255,255, 0.1); + color: var(--text-color-highlight); +} + +nav a.active::after { + opacity: 1; + background-color: var(--text-color-highlight); +} + +nav a::after { + content: ''; + position: absolute; + top: 0; + left: 0.1rem; + width: 1px; + height: 100%; + background-color: var(--text-color); + opacity: 0; + transition: opacity 0.2s; +} + +nav a:hover { + color: white; +} + +nav a:hover::after { + height: 100%; + color: #cccccc; + opacity: 1; } main { - width: calc(100% - 2rem); - max-width: var(--max-width); - padding-inline: 1rem; - display: flex; - flex-direction: column; - gap: 3rem; + padding: 0; + margin-left: 2rem; + width: 100%; } -main article { +section { + padding: 0; + margin: 0; + width: 100%; + height: 100vh; +} + +article { + width: 100%; +} + +#about { display: flex; flex-direction: column; justify-content: center; align-items: center; - gap: 1rem; } -.avatar { - width: min(16rem, 100%); - height: min(16rem, 100%); - aspect-ratio: 1/1; - border-radius: 50%; - border: 3px solid #44251a; - background-color: gray; - overflow: clip; - transition: background-color 0.3s linear; -} - -.avatar img { - width: 100%; - height: 100%; -} - -.status { - max-width: var(--max-width); - width: min(100%, 16rem); - border: 2px solid #000; - border-radius: 0.2rem; - background-color: rgba(0,0,0, 0.5); - backdrop-filter: blur(4px); - box-sizing: border-box; - min-height: 5rem; +#projects { display: flex; flex-direction: column; + justify-content: start; + align-items: center; + background-color: rgba(0,0,0, 0.85); + background-blend-mode: darken; + padding-top: 2rem; + padding-bottom: 2rem; + background-image: url("/img/bg-projects.jpg"); + background-position: center; + background-attachment: fixed; + height: auto; +} + +#projects .links { + display: flex; + flex-direction: row; justify-content: center; align-items: center; gap: 0.5rem; + padding-top: 0.5rem; } -.status #status-action:empty { - display: none; -} - -.bio { - padding: 1rem; - max-width: var(--max-width); - width: 100%; - border: 2px solid #000; +#projects .links a button { + width: 2rem; + height: 2rem; + border: 1px solid #fff; border-radius: 0.2rem; - background-color: rgba(0,0,0, 0.5); - backdrop-filter: blur(4px); - box-sizing: border-box; + padding: 0.2rem; + background: transparent; + cursor: pointer; } -.projects { - text-align: center; +#projects .links a button:hover { + background-color: rgba(255,255,255, 0.15); + transition: background-color 0.2s; +} + +#projects .links a button img { width: 100%; + height: 100%; +} + +.tags { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; - gap: 1rem; + align-items: center; + gap: 0.5rem; + padding: 1rem; + max-width: 18rem; } -.vertical-screen { - padding: 1rem; - border: 2px solid #000; +.tags span { + font-size: 0.65rem; + border: 1px solid var(--text-color); + padding: 0.2rem; border-radius: 0.2rem; - position: relative; - background-color: rgba(0,0,0, 0.5); - backdrop-filter: blur(4px); - box-sizing: border-box; - min-height: 20rem; - width: 12rem; + cursor: default; + user-select: none; + transition: transform 0.2s, color 0.2s, border-color 0.2s +} + +.tags span:hover { + transform: scale(1.2); + color: var(--text-color-highlight); + border-color: var(--text-color-highlight); +} + +#about article { display: flex; flex-direction: column; - justify-content: space-between; + justify-content: center; align-items: center; - text-decoration: none; - color: #fff; - transition: border-color 0.1s linear; + gap: 1.5rem; } -.vertical-screen:hover { - border-color: #fff; +#about h1 { + color: var(--text-color-highlight); } -.vertical-screen p { +section h2 { + font-size: 1.5rem; + color: var(--text-color-highlight); + padding-bottom: 1.5rem; +} + +#projects .project-scroller { + height: 100%; + max-width: 100vw; +} + +#projects .project-scroller article { + display: flex; + flex-direction: row; + justify-content: start; + text-align: start; + flex-wrap: wrap; + max-width: 34rem; + padding-top: 0.5rem; + padding-bottom: 1.5rem; + padding-inline: min(1rem, 5%); + gap: 0.75rem; +} + +#projects .project-scroller article:nth-child(2n+0) { + justify-content: end; + flex-direction: row-reverse; + text-align: end; +} + +#projects .project-scroller article .links { + justify-content: flex-start; +} + +#projects .project-scroller article:nth-child(2n+0) .links { + justify-content: flex-end; +} + +#projects .project-scroller article .title { + font-size: 1.4rem; + color: var(--text-color-highlight); + text-align: inherit; +} + +#projects .project-scroller article .description { + width: fit-content; + flex: 1; + min-width: 14rem; +} + +#projects .project-scroller article .description p { font-size: 0.8rem; - color: rgba(255,255,255, 0.75); + color: var(--text-color); + text-align: inherit; } -.vertical-screen .logo { +#projects .project-scroller article .project-logo { + min-width: 9rem; + min-height: 9rem; + max-width: 9rem; + max-height: 9rem; + border-radius: 0.5rem; +} + +#projects .project-scroller article .project-logo img { width: 100%; height: 100%; - opacity: 0.75; + border-radius: 0.5rem; +} + +#socials { display: flex; flex-direction: column; justify-content: center; align-items: center; - min-height: 15rem; -} - -.vertical-screen .bg { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; - opacity: 0.075; - transition: opacity 0.1s linear; -} - -.vertical-screen:hover .bg { - opacity: 0.15; -} - -.vertical-screen.side-projects .bg { - background-image: url("img/board.jpeg"); + background-color: rgba(0,0,0, 0.85); + background-image: url("img/bg-social.jpg"); + background-blend-mode: darken; + padding-top: 2rem; + padding-bottom: 2rem; background-position: center; - animation: pan-image-1 60s infinite alternate both ease-in-out; + background-attachment: fixed; } -.vertical-screen.side-projects .logo { - height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - min-height: 15rem; - opacity: 0.75; -} - -.vertical-screen.side-projects .logo .small { - font-size: 0.6rem; -} - -.vertical-screen.side-projects .logo .big { - font-size: 1.3rem; - font-weight: bold; - line-height: 1; -} - -.vertical-screen.purpur .bg { - background-image: url("img/minecraft-hobbit-hole.jpeg"); - background-position: center; - animation: pan-image-2 90s infinite alternate both ease-in-out; -} - -.flex-row { +#socials article { display: flex; flex-direction: row; flex-wrap: wrap; - gap: 1rem; justify-content: center; align-items: center; + gap: 0.75rem; + max-width: 28rem; } -.icon-square { +#socials .social-link { display: flex; + flex-direction: column; justify-content: center; align-items: center; - flex-direction: column; - width: 6rem; - height: 6rem; - border-radius: 0.2rem; - background-color: rgba(0,0,0, 0.4); - backdrop-filter: blur(4px); - box-sizing: border-box; - border: 2px solid #000; - transition: border 0.1s linear, background 0.1s linear; - padding: 1rem; - color: #fff; + color: var(--text-color); + transition: all 0.2s; + border-radius: 0.25rem; + border: 1px solid var(--text-color); + width: 5rem; + height: 5rem; + padding: 0.5rem; + gap: 0.2rem; } -.icon-square img { - width: 100%; - aspect-ratio: 1/1; - opacity: 0.8; - transition: opacity 0.1s linear, transform 0.1s linear; - transform: scale(0.8); +#socials .social-link:hover { + color: var(--text-color-highlight); + border-color: var(--text-color-highlight); + background-color: rgba(255,255,255, 0.15); } -.icon-square:hover img { - opacity: 1; - transform: scale(0.85); +#socials .social-link img { + width: 75%; + height: 75%; + filter: brightness(0.85); + transition: filter 0.2s, scale 0.2s } -.icon-square:hover { - border-color: #fff; - background-color: rgba(0,0,0, 0.6); +#socials .social-link:hover img { + filter: brightness(1); + scale: 1.05; } - -@keyframes pan-image-1 { - 0% { - background-position: 36% 42%; - } - 25% { - background-position: 60% 84%; - } - 50% { - background-position: 45% 60%; - } - 75% { - background-position: 12% 20%; - } - 100% { - background-position: 36% 42%; - } -} - -@keyframes pan-image-2 { - 0% { - background-position: 0 0; - } - 33% { - background-position: 56% 60%; - } - 66% { - background-position: 77% 42%; - } - 100% { - background-position: 0 0; - } -} \ No newline at end of file diff --git a/reset.css b/reset.css new file mode 100644 index 0000000..59725c1 --- /dev/null +++ b/reset.css @@ -0,0 +1,47 @@ +* { + box-sizing: border-box; +} +:root { + margin: 0; + padding: 0; +} + +::-moz-selection { + background: rgba(255,255,255, 0.2); +} + +::selection { + background: rgba(255,255,255, 0.2); +} + +html { + background-size: cover; + font-size: 1.2em; +} +body { + margin: 0; + width: 100%; + min-height: 100vh; + padding: 0; +} + +small { + font-size: 0.6rem; +} + +p, h1, h2, h3, h4, h5, h6 { + text-align: center; + margin: 0; +} + +a { + text-decoration: none; +} + +h1 { + font-size: 1.5rem; +} + +h2 { + font-size: 1.1rem; +}