Compare commits

..

No commits in common. "f862d50668fd2e5647408105127e0cadf5fca711" and "e71eb0ae9993ae6b534c736bb7a00f6e7be2c320" have entirely different histories.

13 changed files with 87 additions and 270 deletions

View file

@ -1,21 +1,21 @@
<a <a
class="sticky top-5 left-5 ml-10 flex w-fit items-center justify-center gap-2 rounded-lg bg-white py-1 pr-5 pl-2 text-xl" class="sticky left-5 top-5 ml-10 flex w-fit items-center justify-center gap-2 rounded-lg bg-white py-1 pl-2 pr-5 text-xl"
href="/blog" href="/blog"
style="color: black; text-decoration: none;" style="color: black; text-decoration: none;"
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
viewBox="0 0 24 24" viewBox="0 0 24 24"
stroke-width="1.5" stroke-width="1.5"
stroke="currentColor" stroke="currentColor"
class="size-5" class="size-5"
> >
<path <path
stroke-linecap="round" stroke-linecap="round"
stroke-linejoin="round" stroke-linejoin="round"
d="M15.75 19.5 8.25 12l7.5-7.5"></path> d="M15.75 19.5 8.25 12l7.5-7.5"></path>
</svg> </svg>
Back Back
</a> </a>

View file

@ -3,7 +3,6 @@ import { Image } from "astro:assets";
import Socials from "../socials/Socials.astro"; import Socials from "../socials/Socials.astro";
import pfp_new from "../images/pfp_new_medium.webp"; import pfp_new from "../images/pfp_new_medium.webp";
import pfp_light from "../images/pfp_light.webp";
import Card from "../global/Card.astro"; import Card from "../global/Card.astro";
--- ---
@ -18,13 +17,7 @@ import Card from "../global/Card.astro";
<Image <Image
src={pfp_new} src={pfp_new}
alt="Profile picture" alt="Profile picture"
class="profile-image-dark border-accent aspect-square rounded-full border-2 border-solid object-cover" class="border-accent aspect-square rounded-full border-2 border-solid object-cover"
width={150}
/>
<Image
src={pfp_light}
alt="Profile picture"
class="profile-image-light border-accent hidden aspect-square rounded-full border-2 border-solid object-cover"
width={150} width={150}
/> />
</div> </div>
@ -65,14 +58,6 @@ import Card from "../global/Card.astro";
</div> </div>
<style> <style>
:global(html[data-theme="light"]) .profile-image-dark {
display: none;
}
:global(html[data-theme="light"]) .profile-image-light {
display: block;
}
#title { #title {
background: linear-gradient( background: linear-gradient(
90deg, 90deg,

View file

@ -3,7 +3,6 @@ import Card from "../global/Card.astro";
import Socials from "../socials/Socials.astro"; import Socials from "../socials/Socials.astro";
import Greeting from "./Greeting.svelte"; import Greeting from "./Greeting.svelte";
import pfp_new from "../images/pfp_new.webp"; import pfp_new from "../images/pfp_new.webp";
import pfp_light from "../images/pfp_light.webp";
import { Image } from "astro:assets"; import { Image } from "astro:assets";
--- ---
@ -21,15 +20,7 @@ import { Image } from "astro:assets";
alt="Ryan" alt="Ryan"
width="80" width="80"
height="80" height="80"
class="profile-image-dark max-w-full rounded-full bg-[#505050]" class="max-w-full rounded-full bg-[#505050]"
loading="eager"
/>
<Image
src={pfp_light}
alt="Ryan"
width="80"
height="80"
class="profile-image-light hidden max-w-full rounded-full bg-[#505050]"
loading="eager" loading="eager"
/> />
</div> </div>
@ -40,53 +31,7 @@ import { Image } from "astro:assets";
> >
Ryan Lee Ryan Lee
</div> </div>
<div <div class="w-full text-xl">Full Stack Developer</div>
class="flex flex-row items-start justify-start gap-3 text-sm"
>
<div
class="flex flex-row items-center justify-start gap-1"
>
<svg
class="size-4"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M20.25 14.15v4.25c0 1.094-.787 2.036-1.872 2.18-2.087.277-4.216.42-6.378.42s-4.291-.143-6.378-.42c-1.085-.144-1.872-1.086-1.872-2.18v-4.25m16.5 0a2.18 2.18 0 0 0 .75-1.661V8.706c0-1.081-.768-2.015-1.837-2.175a48.114 48.114 0 0 0-3.413-.387m4.5 8.006c-.194.165-.42.295-.673.38A23.978 23.978 0 0 1 12 15.75c-2.648 0-5.195-.429-7.577-1.22a2.016 2.016 0 0 1-.673-.38m0 0A2.18 2.18 0 0 1 3 12.489V8.706c0-1.081.768-2.015 1.837-2.175a48.111 48.111 0 0 1 3.413-.387m7.5 0V5.25A2.25 2.25 0 0 0 13.5 3h-3a2.25 2.25 0 0 0-2.25 2.25v.894m7.5 0a48.667 48.667 0 0 0-7.5 0M12 12.75h.008v.008H12v-.008Z"
></path>
</svg>
<div>Full Stack Developer</div>
</div>
<div
class="flex flex-row items-center justify-start gap-1"
>
<svg
class="size-4"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15 10.5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
></path>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1 1 15 0Z"
></path>
</svg>
<div>Malaysia</div>
</div>
</div>
</div> </div>
</div> </div>
<div id="uwu" class="hidden items-center justify-center"> <div id="uwu" class="hidden items-center justify-center">
@ -101,12 +46,12 @@ import { Image } from "astro:assets";
<Greeting client:load />! <Greeting client:load />!
</div> </div>
<p class="text-left"> <p class="text-left">
I am a content creator and software developer, building I am a Malaysian computer science graduate working
software for 100+ content creators, garnering 4,000+ on various projects in Malaysia. I develop software
followers across platforms. I worked as a developer at 3+ for streamers and content creators, while also
companies in Malaysia and Australia, and looking for my next making tech tutorials in programming.
role after graduation.
</p> </p>
<div class="mt-8 flex flex-row items-center justify-center"> <div class="mt-8 flex flex-row items-center justify-center">
<Socials /> <Socials />
</div> </div>
@ -116,14 +61,6 @@ import { Image } from "astro:assets";
</div> </div>
<style> <style>
:global(html[data-theme="light"]) .profile-image-dark {
display: none;
}
:global(html[data-theme="light"]) .profile-image-light {
display: block;
}
#name { #name {
background: linear-gradient( background: linear-gradient(
90deg, 90deg,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

View file

@ -7,18 +7,18 @@ import GoRyve from "../images/projects/goryve.webp";
<div class="flex h-fit flex-col items-center pt-20 [perspective:1000px]"> <div class="flex h-fit flex-col items-center pt-20 [perspective:1000px]">
<div class="w-full max-w-[1440px]"> <div class="w-full max-w-[1440px]">
<Project <Project
position="left" position="left"
image={TwitchPlays} image={TwitchPlays}
alt="Twitch Plays X" alt="Twitch Plays X"
href="https://git.rython.dev/rythondev/TwitchPlaysX" href="https://git.rython.dev/rythondev/TwitchPlaysX"
title="Twitch Plays X" title="Twitch Plays X"
description={`Allow Twitch chatters to play games such as Pokemon! description={`Allow Twitch chatters to play games such as Pokemon!
Chatters can enter messages such as "up up down down left Chatters can enter messages such as "up up down down left
right B A" and the Python program will trigger the right B A" and the Python program will trigger the
corresponding keypresses.`} corresponding keypresses.`}
tags={["win32API", "Python"]} tags={["win32API", "Python"]}
/> />
<VideoProject <VideoProject
image_src="/images/projects/chess-opencv.webp" image_src="/images/projects/chess-opencv.webp"
image_alt="computer vision chess bot" image_alt="computer vision chess bot"
@ -35,15 +35,15 @@ import GoRyve from "../images/projects/goryve.webp";
client:visible client:visible
/> />
<Project <Project
position="left" position="left"
image={GoRyve} image={GoRyve}
alt="GoRyve" alt="GoRyve"
href="https://goryve.app/" href="https://goryve.app/"
title="GoRyve" title="GoRyve"
label="Visit Site" label="Visit Site"
description={`Notify your community when you or your friends go live, configured separately! Share a pool of 10 free slots between your Twitch accounts and your friends'.`} description={`Notify your community when you or your friends go live, configured separately! Share a pool of 10 free slots between your Twitch accounts and your friends'.`}
tags={["Rust", "Poise", "SQLite", "Forgejo Actions"]} tags={["Rust", "Poise", "SQLite", "Forgejo Actions"]}
/> />
<VideoProject <VideoProject
client:visible client:visible
image_src="/images/projects/aim-lab.webp" image_src="/images/projects/aim-lab.webp"

View file

@ -44,9 +44,7 @@ const renderLayer = (
isLight isLight
? "project-image-light hidden border-gray-300" ? "project-image-light hidden border-gray-300"
: "project-image-dark border-gray-800", : "project-image-dark border-gray-800",
isBackground isBackground ? "background-img opacity-40" : "frontfacing-img opacity-100",
? "background-img opacity-40"
: "frontfacing-img opacity-100",
isBackground && isLight ? "brightness-75" : "", isBackground && isLight ? "brightness-75" : "",
side, side,
] ]

View file

@ -87,11 +87,7 @@
{/if} {/if}
{/snippet} {/snippet}
{@render renderLayer( {@render renderLayer("image", "background-img", "opacity-40 brightness-75")}
"image",
"background-img",
"opacity-40 brightness-75",
)}
{@render renderLayer("video", "frontfacing-vid", "opacity-100")} {@render renderLayer("video", "frontfacing-vid", "opacity-100")}
</div> </div>
<div <div

View file

@ -1,7 +1,7 @@
<div class="flex flex-row items-center justify-center gap-3"> <div class="flex flex-row items-center justify-center gap-3">
<a href="https://git.rython.dev/" target="_blank"> <a href="https://git.rython.dev/" target="_blank">
<div <div
class="flex h-8 w-8 items-center justify-center rounded-full bg-white transition-[filter,background-color] duration-150 hover:bg-[#089cff] hover:invert" class="flex h-8 w-8 items-center justify-center rounded-full bg-white transition-[filter,background-color] duration-150 hover:invert hover:bg-[#089cff]"
> >
<img <img
src="/images/socials/forgejo.svg" src="/images/socials/forgejo.svg"

View file

@ -1,5 +1,6 @@
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { AnimatePresence, motion } from "motion/react"; import { AnimatePresence, motion } from "motion/react";
import { Cross as HamburgerCross } from "hamburger-react";
import { useEffect, useState, useRef } from "react"; import { useEffect, useState, useRef } from "react";
declare module "react" { declare module "react" {
@ -22,7 +23,7 @@ export const HoverNavigation = ({
const [activeIndex, setActiveIndex] = useState<number | null>(null); const [activeIndex, setActiveIndex] = useState<number | null>(null);
const [hamburgerOpen, setHamburgerOpen] = useState(false); const [hamburgerOpen, setHamburgerOpen] = useState(false);
const [theme, setTheme] = useState<"light" | "dark">("dark"); const [theme, setTheme] = useState<"light" | "dark">("dark");
const hamburgerRef = useRef<HTMLButtonElement>(null); const hamburgerRef = useRef<HTMLDivElement>(null);
const menuRef = useRef<HTMLDivElement>(null); const menuRef = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
@ -116,26 +117,9 @@ export const HoverNavigation = ({
} }
}; };
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") setHamburgerOpen(false);
};
document.addEventListener("mousedown", handleClickOutside); document.addEventListener("mousedown", handleClickOutside);
document.addEventListener("keydown", handleKeyDown);
return () => { return () => {
document.removeEventListener("mousedown", handleClickOutside); document.removeEventListener("mousedown", handleClickOutside);
document.removeEventListener("keydown", handleKeyDown);
};
}, [hamburgerOpen]);
useEffect(() => {
if (!hamburgerOpen) return;
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = "hidden";
return () => {
document.body.style.overflow = previousOverflow;
}; };
}, [hamburgerOpen]); }, [hamburgerOpen]);
@ -203,63 +187,16 @@ export const HoverNavigation = ({
</div> </div>
</div> </div>
</div> </div>
<div <div className="theme-surface bg-secondary/50 fixed top-5 left-1/2 z-50 flex w-4/5 -translate-x-1/2 items-center justify-end rounded-full border-2 border-solid border-gray-700 pr-5 backdrop-blur-xl lg:hidden">
className={cn( <ThemeToggle theme={theme} onToggle={toggleTheme} />
"fixed top-4 right-4 left-4 z-50 flex h-16 items-center justify-between rounded-[1.25rem] border px-3 shadow-[0_12px_40px_rgba(0,0,0,0.16)] backdrop-blur-2xl transition-colors md:hidden", <div
theme === "dark" ref={hamburgerRef}
? "border-white/10 bg-neutral-950/85 text-white" className="flex rounded-full px-1 py-1 md:hidden [&>div]:rounded-full [&>div_div]:bg-current!"
: "border-black/10 bg-white/85 text-neutral-950",
)}
>
<a
href="/#home"
onClick={() => setHamburgerOpen(false)}
className="flex items-center gap-2.5 rounded-xl px-2 py-2 font-semibold tracking-tight"
aria-label="Go to home"
> >
<span <HamburgerCross
className={cn( toggle={setHamburgerOpen}
"grid size-8 place-items-center rounded-lg text-sm font-black", toggled={hamburgerOpen}
theme === "dark" ></HamburgerCross>
? "bg-white text-neutral-950"
: "bg-neutral-950 text-white",
)}
>
RL
</span>
<span className="text-sm opacity-65">Portfolio</span>
</a>
<div className="flex items-center gap-1">
<ThemeToggle theme={theme} onToggle={toggleTheme} />
<button
ref={hamburgerRef}
type="button"
onClick={() => setHamburgerOpen((open) => !open)}
aria-expanded={hamburgerOpen}
aria-controls="mobile-navigation"
aria-label={hamburgerOpen ? "Close menu" : "Open menu"}
className={cn(
"group grid size-11 cursor-pointer place-items-center rounded-xl transition-all active:scale-95",
theme === "dark"
? "bg-white text-neutral-950"
: "bg-neutral-950 text-white",
)}
>
<span
className="relative block h-4 w-5"
aria-hidden="true"
>
<span
className={`absolute top-0 right-0 h-0.5 w-5 rounded-full bg-current transition-all duration-300 ${hamburgerOpen ? "translate-y-[7px] -rotate-45" : ""}`}
/>
<span
className={`absolute top-[7px] right-0 h-0.5 rounded-full bg-current transition-all duration-300 ${hamburgerOpen ? "w-0 opacity-0" : "w-3.5"}`}
/>
<span
className={`absolute top-[14px] right-0 h-0.5 w-5 rounded-full bg-current transition-all duration-300 ${hamburgerOpen ? "-translate-y-[7px] rotate-45" : ""}`}
/>
</span>
</button>
</div> </div>
</div> </div>
@ -268,68 +205,33 @@ export const HoverNavigation = ({
{hamburgerOpen && ( {hamburgerOpen && (
<motion.div <motion.div
ref={menuRef} ref={menuRef}
id="mobile-navigation" initial={{ opacity: 0, scale: 0.95 }}
initial={{ opacity: 0, y: -12 }} animate={{ opacity: 1, scale: 1 }}
animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, scale: 0.95 }}
exit={{ opacity: 0, y: -12 }} transition={{ duration: 0.2 }}
transition={{ className="theme-surface bg-secondary/50 fixed top-24 right-0 left-1/2 z-40 w-4/5 -translate-x-1/2 rounded-2xl py-2 backdrop-blur-xl md:hidden"
duration: 0.25,
ease: [0.22, 1, 0.36, 1],
}}
className={cn(
"fixed inset-0 z-40 flex flex-col overflow-hidden px-5 pt-28 pb-7 transition-colors md:hidden",
theme === "dark"
? "bg-neutral-950 text-white"
: "bg-[#f4f3ef] text-neutral-950",
)}
> >
<nav <nav aria-label="Mobile Navigation">
aria-label="Mobile Navigation" <ul className="flex flex-col gap-2">
className="relative flex flex-1 items-center"
>
<ul className="w-full">
{items.map((item, idx) => ( {items.map((item, idx) => (
<motion.li <motion.li
key={item?.link} key={item?.link}
initial={{ opacity: 0, x: -24 }} initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, x: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ transition={{
delay: 0.06 + idx * 0.055, delay: idx * 0.1,
duration: 0.35, duration: 0.3,
}} }}
className={cn( className="rounded-2xl px-3"
"border-b last:border-b-0",
theme === "dark"
? "border-white/10"
: "border-black/10",
)}
> >
<a <a
href={item?.link} href={item?.link}
className="group flex items-center gap-4 py-4" className="block rounded-lg px-4 py-3 text-center text-lg transition-colors"
onClick={() => onClick={() =>
setHamburgerOpen(false) setHamburgerOpen(false)
} }
> >
<span className="w-6 text-xs font-medium opacity-35"> {item.label}
{String(idx + 1).padStart(
2,
"0",
)}
</span>
<span className="flex-1 text-[clamp(2rem,11vw,3.25rem)] leading-none font-semibold tracking-[-0.055em]">
{item.label}
</span>
<span
className={cn(
"grid size-9 place-items-center rounded-full border text-lg transition-all group-hover:rotate-[-45deg]",
theme === "dark"
? "border-white/20 group-hover:bg-white group-hover:text-neutral-950"
: "border-black/20 group-hover:bg-neutral-950 group-hover:text-white",
)}
>
↗
</span>
</a> </a>
</motion.li> </motion.li>
))} ))}

View file

@ -28,8 +28,7 @@ import { ClientRouter } from "astro:transitions";
const theme = const theme =
savedTheme === "light" || savedTheme === "dark" savedTheme === "light" || savedTheme === "dark"
? savedTheme ? savedTheme
: window.matchMedia("(prefers-color-scheme: light)") : window.matchMedia("(prefers-color-scheme: light)").matches
.matches
? "light" ? "light"
: "dark"; : "dark";

View file

@ -3,11 +3,11 @@ import InfoLayout from "../layouts/InfoLayout.astro";
--- ---
<InfoLayout <InfoLayout
title="RythonDev Discord Server" title="RythonDev Discord Server"
description="Come join Ryan's Room for tech support or chaotic vibes!" description="Come join Ryan's Room for tech support or chaotic vibes!"
metaURL="https://rython.dev/discord" metaURL="https://rython.dev/discord"
/> />
<script is:inline> <script is:inline>
window.location.href = "https://discord.gg/F5efU63Prz"; window.location.href = "https://discord.gg/F5efU63Prz";
</script> </script>

View file

@ -3,12 +3,12 @@ import InfoLayout from "../layouts/InfoLayout.astro";
--- ---
<InfoLayout <InfoLayout
title="RythonDev's Software Dev + Coworking Stream" title="RythonDev's Software Dev + Coworking Stream"
description="Come sit at the table with us! We can chill, nerd out, and enjoy good vibes together!" description="Come sit at the table with us! We can chill, nerd out, and enjoy good vibes together!"
thumbnail="/images/stream-live-thumbnail.webp" thumbnail="/images/stream-live-thumbnail.webp"
metaURL="https://rython.dev/live" metaURL="https://rython.dev/live"
/> />
<script is:inline> <script is:inline>
window.location.href = "https://www.twitch.tv/rythondev"; window.location.href = "https://www.twitch.tv/rythondev";
</script> </script>

View file

@ -3,12 +3,12 @@ import InfoLayout from "../layouts/InfoLayout.astro";
--- ---
<InfoLayout <InfoLayout
title="OnlyFans" title="OnlyFans"
description="UWU 💦 NYA MEOW SEXY TIME 🕓 ! RYAN IS 😗♻ HERE 🚢💪 TO 💦✌ EAT 😩🗣 YOUR 👉 TOES 👣 NOM NOM JUST KIDDING UWU 💦" description="UWU 💦 NYA MEOW SEXY TIME 🕓 ! RYAN IS 😗♻ HERE 🚢💪 TO 💦✌ EAT 😩🗣 YOUR 👉 TOES 👣 NOM NOM JUST KIDDING UWU 💦"
metaURL="https://rython.dev/onlyfans" metaURL="https://rython.dev/onlyfans"
thumbnail="/images/of-logo-b.webp" thumbnail="/images/of-logo-b.webp"
/> />
<script is:inline> <script is:inline>
window.location.href = "https://youtu.be/dQw4w9WgXcQ"; window.location.href = "https://youtu.be/dQw4w9WgXcQ";
</script> </script>