mirror of
https://github.com/liyunze-coding/RythonDev.git
synced 2026-11-06 19:03:33 +00:00
Compare commits
No commits in common. "f862d50668fd2e5647408105127e0cadf5fca711" and "e71eb0ae9993ae6b534c736bb7a00f6e7be2c320" have entirely different histories.
f862d50668
...
e71eb0ae99
13 changed files with 87 additions and 270 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
<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;"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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 |
|
|
@ -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,
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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(
|
|
||||||
"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",
|
|
||||||
theme === "dark"
|
|
||||||
? "border-white/10 bg-neutral-950/85 text-white"
|
|
||||||
: "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
|
|
||||||
className={cn(
|
|
||||||
"grid size-8 place-items-center rounded-lg text-sm font-black",
|
|
||||||
theme === "dark"
|
|
||||||
? "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} />
|
<ThemeToggle theme={theme} onToggle={toggleTheme} />
|
||||||
<button
|
<div
|
||||||
ref={hamburgerRef}
|
ref={hamburgerRef}
|
||||||
type="button"
|
className="flex rounded-full px-1 py-1 md:hidden [&>div]:rounded-full [&>div_div]:bg-current!"
|
||||||
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
|
<HamburgerCross
|
||||||
className="relative block h-4 w-5"
|
toggle={setHamburgerOpen}
|
||||||
aria-hidden="true"
|
toggled={hamburgerOpen}
|
||||||
>
|
></HamburgerCross>
|
||||||
<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">
|
|
||||||
{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}
|
{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>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue