updated site including discord

This commit is contained in:
liyunze 2025-11-01 01:32:44 +11:00
parent a7f3531b9c
commit 389b1388be
8 changed files with 221 additions and 270 deletions

View file

@ -10,19 +10,16 @@ import Line from "../global/NetworkLine.astro";
<Card primaryColor="#F6DFD8" className="animate-fadeIn"> <Card primaryColor="#F6DFD8" className="animate-fadeIn">
<div class="px-4 py-4 md:px-8 md:py-8"> <div class="px-4 py-4 md:px-8 md:py-8">
<div class="mb-3 flex w-full flex-col justify-start gap-1"> <div class="mb-3 flex w-full flex-col justify-start gap-1">
<h2 class="text-xl font-bold"> <h2 class="text-xl font-bold">Full Stack Developer</h2>
Full Stack Developer (Contract)
</h2>
<h3 class="font-bold">@ Hyson Horizon</h3> <h3 class="font-bold">@ Hyson Horizon</h3>
<h3>Dec 2024 - Present</h3> <h3>Dec 2024 - Present</h3>
</div> </div>
<hr class="mb-3 w-full" /> <hr class="mb-3 w-full" />
<p class="mb-3"> <p class="mb-3">
Led implementation of frontend development of websites. Led implementation of frontend development, while also
Efficiently translated designs into code, while ensuring developing and intergating a CMS on the backend for
maintainability, accessibility and performance. Actively website development. Actively contributing to LLM
researching and developing for LLM integration into product research and development.
product.
</p> </p>
<h3 class="mb-1 text-lg font-bold">Relevant skills:</h3> <h3 class="mb-1 text-lg font-bold">Relevant skills:</h3>
<div <div
@ -31,9 +28,10 @@ import Line from "../global/NetworkLine.astro";
<ul class="list-inside list-disc"> <ul class="list-inside list-disc">
<li>NextJS</li> <li>NextJS</li>
<li>React</li> <li>React</li>
<li>Astro</li> <li>Payload CMS</li>
</ul> </ul>
<ul class="list-inside list-disc"> <ul class="list-inside list-disc">
<li>Astro</li>
<li>Typescript</li> <li>Typescript</li>
<li>TailwindCSS</li> <li>TailwindCSS</li>
</ul> </ul>
@ -94,12 +92,13 @@ import Line from "../global/NetworkLine.astro";
> >
<ul class="list-inside list-disc"> <ul class="list-inside list-disc">
<li>WordPress & PHP</li> <li>WordPress & PHP</li>
<li>Typescript</li> <li>NextJS</li>
<li>TailwindCSS</li> <li>React</li>
</ul> </ul>
<ul class="list-inside list-disc"> <ul class="list-inside list-disc">
<li>Adobe XD</li> <li>Adobe XD</li>
<li>NextJS & React</li> <li>Typescript</li>
<li>TailwindCSS</li>
</ul> </ul>
</div> </div>
</div> </div>

View file

@ -1,7 +1,8 @@
--- ---
type Props = { type Props = {
href?: string; href?: string;
primaryColor: string; primaryColor?: string;
shadowColor?: string;
bgColor?: string; bgColor?: string;
scaleOnHover?: boolean; scaleOnHover?: boolean;
pixelHeight?: string; pixelHeight?: string;
@ -11,6 +12,7 @@ type Props = {
const { const {
href, href,
primaryColor, primaryColor,
shadowColor = "rgb(12,12,12)",
bgColor = "var(--color-secondary)", bgColor = "var(--color-secondary)",
scaleOnHover = false, scaleOnHover = false,
pixelHeight = "70px", pixelHeight = "70px",
@ -36,7 +38,7 @@ const {
{ {
!href && ( !href && (
<div <div
class="card z-10 mb-0" class="card z-10 mb-0 rounded-xl shadow-xl"
class:list={[{ scale: scaleOnHover }, className]} class:list={[{ scale: scaleOnHover }, className]}
> >
<div class="card-content"> <div class="card-content">
@ -47,7 +49,7 @@ const {
} }
</> </>
<style define:vars={{ primaryColor, bgColor, pixelHeight }}> <style define:vars={{ bgColor, pixelHeight, shadowColor }}>
* { * {
box-sizing: border-box; box-sizing: border-box;
} }
@ -60,50 +62,15 @@ const {
} }
.card { .card {
height: inherit; background: #1c1c1c;
position: relative; background: linear-gradient(
background-color: var(--bgColor); 135deg,
border: 1px solid rgb(255 255 255 / 10%); rgba(18, 18, 18, 1) 0%,
border-radius: 1.5rem; rgba(30, 30, 30, 1) 33%,
rgba(25, 25, 25, 1) 66%,
rgba(19, 19, 19, 1) 100%
);
--tw-shadow-color: var(--shadowColor);
padding: 0.5rem; padding: 0.5rem;
} }
.card:after {
content: "";
height: var(--pixelHeight);
width: 1px;
position: absolute;
left: -1px;
top: 65%;
transition: top, opacity;
transition-duration: 600ms;
transition-timing-function: ease;
background: linear-gradient(
transparent,
var(--primaryColor),
transparent
);
opacity: 0;
}
/* .card:hover:after {
top: 25%;
opacity: 1;
} */
.card.scale {
transition: transform 0.5s ease;
}
.card.scale:hover {
transform: scale(1.05);
}
.card-content {
display: flex;
flex-direction: column;
gap: 1rem;
background-position: 50% 50%;
background-size: 1.1rem 1.1rem;
}
</style> </style>

View file

@ -7,7 +7,7 @@ import { Image } from "astro:assets";
--- ---
<div class="w-[90%] md:w-[600px] lg:w-1/2"> <div class="w-[90%] md:w-[600px] lg:w-1/2">
<Card primaryColor="#BEADFA" className="animate-fadeIn"> <Card shadowColor="rgb(4, 57, 57)" className="animate-fadeIn">
<div id="intro" class="flex h-fit flex-col text-white"> <div id="intro" class="flex h-fit flex-col text-white">
<div class="w-full px-5 pt-10 pb-2 lg:px-10"> <div class="w-full px-5 pt-10 pb-2 lg:px-10">
<div class="flex h-20 flex-row"> <div class="flex h-20 flex-row">

View file

@ -115,11 +115,7 @@ const leftProject = position == "left";
{ {
tags.map((tag) => ( tags.map((tag) => (
<div <div
class="my-1 mr-1 w-fit rounded-full px-3 py-1 transition-colors duration-300" class="my-1 mr-1 w-fit rounded-full px-3 py-1 transition-colors duration-300 text-white bg-secondary"
style={`
background-color: ${tag.bgColor || "black"};
color: ${tag.textColor || "white"};
`}
> >
{tag.text} {tag.text}
</div> </div>

View file

@ -1,176 +1,172 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte"; import { onMount } from "svelte";
interface Tag { interface Tag {
text: string; text: string;
textColor: string; textColor: string;
bgColor: string; bgColor: string;
} }
interface Props { interface Props {
position?: "left" | "right"; position?: "left" | "right";
image_src: string; image_src: string;
image_alt: string; image_alt: string;
video_src: string; video_src: string;
title: string; title: string;
description: string; description: string;
tags?: Tag[]; tags?: Tag[];
} }
let { let {
position = "left", position = "left",
image_src, image_src,
image_alt, image_alt,
video_src, video_src,
title, title,
description, description,
tags = [], tags = [],
}: Props = $props(); }: Props = $props();
const positionLeft = position == "left"; const positionLeft = position == "left";
onMount(() => { onMount(() => {
const videos = document.querySelectorAll<HTMLVideoElement>(".playable"); const videos = document.querySelectorAll<HTMLVideoElement>(".playable");
let userInteracted = false; let userInteracted = false;
const handleUserInteraction = () => { const handleUserInteraction = () => {
userInteracted = true; userInteracted = true;
document.removeEventListener("click", handleUserInteraction); document.removeEventListener("click", handleUserInteraction);
document.removeEventListener("keydown", handleUserInteraction); document.removeEventListener("keydown", handleUserInteraction);
}; };
document.addEventListener("click", handleUserInteraction); document.addEventListener("click", handleUserInteraction);
document.addEventListener("keydown", handleUserInteraction); document.addEventListener("keydown", handleUserInteraction);
videos.forEach((video) => { videos.forEach((video) => {
// Ensure the video element supports play and pause methods // Ensure the video element supports play and pause methods
if ( if (
typeof video.play === "function" && typeof video.play === "function" &&
typeof video.pause === "function" typeof video.pause === "function"
) { ) {
video.addEventListener("mouseenter", () => { video.addEventListener("mouseenter", () => {
if (userInteracted) { if (userInteracted) {
video.volume = 0.2; video.volume = 0.2;
video.muted = false; video.muted = false;
video.play(); video.play();
} else { } else {
video.volume = 0; video.volume = 0;
video.muted = true; video.muted = true;
video.play(); video.play();
} }
}); });
video.addEventListener("mouseleave", () => { video.addEventListener("mouseleave", () => {
video.pause(); video.pause();
video.currentTime = 0; video.currentTime = 0;
}); });
// Check if the screen width is less than or equal to 768px (mobile screen size) // Check if the screen width is less than or equal to 768px (mobile screen size)
if (window.innerWidth <= 768) { if (window.innerWidth <= 768) {
video.muted = true; video.muted = true;
video.autoplay = true; video.autoplay = true;
video.loop = true; video.loop = true;
video.play(); video.play();
} }
} }
}); });
}); });
</script> </script>
<div <div
class="mb-10 flex h-fit w-full flex-col justify-center px-10 lg:flex-row lg:px-20" class="mb-10 flex h-fit w-full flex-col justify-center px-10 lg:flex-row lg:px-20"
class:lg:flex-row={positionLeft} class:lg:flex-row={positionLeft}
class:lg:flex-row-reverse={!positionLeft} class:lg:flex-row-reverse={!positionLeft}
> >
<div <div
class="image-container relative mb-5 flex aspect-video w-full [perspective:200px] lg:mr-5 lg:mb-0 lg:ml-auto lg:w-1/2" class="image-container relative mb-5 flex aspect-video w-full [perspective:200px] lg:mr-5 lg:mb-0 lg:ml-auto lg:w-1/2"
> >
<img <img
src={image_src} src={image_src}
alt={image_alt} alt={image_alt}
class="background-img absolute class="background-img absolute
top-1/2 top-1/2
left-1/2 max-w-full rounded-xl border-2 left-1/2 max-w-full rounded-xl border-2
border-solid border-white border-solid border-white
opacity-40 opacity-40
{positionLeft ? 'left' : 'right'}" {positionLeft ? 'left' : 'right'}"
width="700" width="700"
/> />
<!-- svelte-ignore a11y_media_has_caption --> <!-- svelte-ignore a11y_media_has_caption -->
<video <video
width="700" width="700"
class="playable frontfacing-vid absolute class="playable frontfacing-vid absolute
top-1/2 left-1/2 max-w-full rounded-xl top-1/2 left-1/2 max-w-full rounded-xl
border-2 border-2
border-solid border-white border-solid border-white
opacity-100 opacity-100
{positionLeft ? 'left' : 'right'}" {positionLeft ? 'left' : 'right'}"
> >
<source src={video_src} type="video/webm" /> <source src={video_src} type="video/webm" />
</video> </video>
</div> </div>
<div <div
class="flex h-fit w-full flex-col items-center justify-center lg:h-[340px] lg:w-1/2 lg:px-10 class="flex h-fit w-full flex-col items-center justify-center lg:h-[340px] lg:w-1/2 lg:px-10
{positionLeft ? 'lg:items-start' : 'lg:items-end'}" {positionLeft ? 'lg:items-start' : 'lg:items-end'}"
> >
<h2 <h2
class="mb-5 text-center text-3xl font-bold class="mb-5 text-center text-3xl font-bold
{positionLeft ? 'lg:text-left' : 'lg:text-right'}" {positionLeft ? 'lg:text-left' : 'lg:text-right'}"
> >
{title} {title}
</h2> </h2>
<p <p
class="max-w-lg text-center text-xl text-balance lg:max-w-none class="max-w-lg text-center text-xl text-balance lg:max-w-none
{positionLeft ? 'lg:text-left' : 'lg:text-right'}" {positionLeft ? 'lg:text-left' : 'lg:text-right'}"
> >
{description} {description}
</p> </p>
<div <div
class="mt-5 flex w-full flex-row flex-wrap justify-center class="mt-5 flex w-full flex-row flex-wrap justify-center
{positionLeft ? 'lg:justify-start' : 'lg:justify-end'}" {positionLeft ? 'lg:justify-start' : 'lg:justify-end'}"
> >
{#each tags as tag} {#each tags as tag}
<div <div
class="my-1 mr-1 w-fit class="bg-secondary my-1 mr-1
rounded-full px-3 py-1 w-fit rounded-full px-3
transition-colors duration-300" py-1 text-white transition-colors duration-300"
style={` >
background-color: ${tag.bgColor || "black"}; {tag.text}
color: ${tag.textColor || "white"}; </div>
`} {/each}
> </div>
{tag.text} </div>
</div>
{/each}
</div>
</div>
</div> </div>
<style> <style>
.background-img.left { .background-img.left {
transform: translateX(calc(-50% + 25px)) translateY(calc(-50% + 5px)) transform: translateX(calc(-50% + 25px)) translateY(calc(-50% + 5px))
translateZ(-50px) rotateY(5deg); translateZ(-50px) rotateY(5deg);
} }
.background-img.right { .background-img.right {
transform: translateX(calc(-50%)) translateY(calc(-50% + 5px)) transform: translateX(calc(-50%)) translateY(calc(-50% + 5px))
translateZ(-50px) rotateY(-3deg); translateZ(-50px) rotateY(-3deg);
} }
.frontfacing-vid.left { .frontfacing-vid.left {
transform: translateX(calc(-50% + 35px)) translateY(calc(-50%)) transform: translateX(calc(-50% + 35px)) translateY(calc(-50%))
translateZ(-50px) rotateY(5deg); translateZ(-50px) rotateY(5deg);
} }
.frontfacing-vid.right { .frontfacing-vid.right {
transform: translateX(calc(-50% - 10px)) translateY(-50%) transform: translateX(calc(-50% - 10px)) translateY(-50%)
translateZ(-50px) rotateY(-3deg); translateZ(-50px) rotateY(-3deg);
} }
.image-container:hover .frontfacing-vid, .image-container:hover .frontfacing-vid,
.image-container:hover .background-img { .image-container:hover .background-img {
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
} }
</style> </style>

View file

@ -33,9 +33,7 @@ const { title, tags, primaryColor, className = "" } = Astro.props;
{ {
tags?.map((tag, index) => ( tags?.map((tag, index) => (
<div <div
class={`tag-${index} my-1 mr-1 w-fit cursor-default rounded-full px-3 py-1 transition-colors duration-300`} class={`tag-${index} my-1 mr-1 w-fit cursor-default rounded-full bg-[#303030] px-3 py-1 text-white transition-colors duration-300`}
style={`--tag-bg: ${tag.bgColor || "#000"}; --tag-text: ${tag.textColor || "#ffffff"};
--tag-hover-text: ${tag.hoverTextColor || "#ffffff"}`}
> >
{tag.text} {tag.text}
</div> </div>
@ -45,10 +43,3 @@ const { title, tags, primaryColor, className = "" } = Astro.props;
</div> </div>
</Card> </Card>
</div> </div>
<style>
[class*="tag-"] {
background-color: var(--tag-bg);
color: var(--tag-text);
}
</style>

View file

@ -9,5 +9,5 @@ import InfoLayout from "../layouts/InfoLayout.astro";
/> />
<script is:inline> <script is:inline>
window.location.href = "https://discord.gg/UnHyHkhbga"; window.location.href = "https://discord.gg/F5efU63Prz";
</script> </script>

View file

@ -1,74 +1,76 @@
@import "tailwindcss"; @import "tailwindcss";
@theme { @theme {
--color-html: #b11700; --color-html: #b11700;
--color-typescript: #3178c6; --color-typescript: #3178c6;
--color-svelte: #b11700; --color-svelte: #b11700;
--color-react: #00d8ff; --color-react: #00d8ff;
--color-wordpress: #21759b; --color-wordpress: #21759b;
--color-htmx: #3366cc; --color-htmx: #3366cc;
--color-tailwind: #07b6d4; --color-tailwind: #07b6d4;
--color-python: #3776ab; --color-python: #3776ab;
--color-csharp: #672079; --color-csharp: #672079;
--color-java: #ed8b00; --color-java: #ed8b00;
--color-kotlin: #7f52ff; --color-kotlin: #7f52ff;
--color-php: #3d5694; --color-php: #3d5694;
--color-go: #006080; --color-go: #006080;
--color-rust: #b11700; --color-rust: #b11700;
--color-postgresql: #4479a1; --color-postgresql: #4479a1;
--color-mysql: #1d6998; --color-mysql: #1d6998;
--color-mongodb: #09934e; --color-mongodb: #09934e;
--color-opencv: #10652f; --color-opencv: #10652f;
--color-win32api: #0078d4; --color-win32api: #0078d4;
--color-primary: #fafafa; --color-primary: #fafafa;
--color-secondary: #1d1c20; --color-secondary: #1d1c20;
--animate-fadeIn: fadeIn 0.5s ease-in-out; --animate-fadeIn: fadeIn 0.5s ease-in-out;
--animate-fadeUp: fadeUp 0.5s ease-in-out; --animate-fadeUp: fadeUp 0.5s ease-in-out;
--animate-glow: glow 2s ease infinite; --animate-glow: glow 2s ease infinite;
@keyframes fadeIn { /* --gradient-primary: */
0% {
opacity: 0;
}
100% { @keyframes fadeIn {
opacity: 100%; 0% {
} opacity: 0;
} }
@keyframes fadeUp { 100% {
0% { opacity: 100%;
opacity: 0; }
translate: 0px 10px; }
}
50% { @keyframes fadeUp {
opacity: 100%; 0% {
translate: 0px 0px; opacity: 0;
} translate: 0px 10px;
} }
@keyframes glow { 50% {
0% { opacity: 100%;
scale: 1; translate: 0px 0px;
opacity: 100%; }
} }
100% {
scale: 4; @keyframes glow {
opacity: 5%; 0% {
} scale: 1;
} opacity: 100%;
}
100% {
scale: 4;
opacity: 5%;
}
}
} }
.view-fadeUp { .view-fadeUp {
translate: 0px 30px; translate: 0px 30px;
opacity: 0; opacity: 0;
transition: all 0.5s ease; transition: all 0.5s ease;
} }
.view-appear { .view-appear {
translate: 0px 0px; translate: 0px 0px;
opacity: 100%; opacity: 100%;
} }