feat: light mode

This commit is contained in:
trafficlunar 2026-02-22 14:12:17 +00:00
parent efdb3102ae
commit eca7077915
9 changed files with 101 additions and 21 deletions

View file

@ -98,7 +98,7 @@
});
</script>
<div class="relative transition-all duration-300 delay-200 starting:opacity-0 starting:translate-y-4">
<div class="relative transition-[translate,opacity] duration-300 delay-200 starting:opacity-0 starting:translate-y-4">
<div class="flex justify-center items-center absolute -top-2 right-2 z-0">
<div class="w-4 h-4 rounded-full {online ? 'bg-green' : 'bg-red'}"></div>
<div class="w-4 h-4 rounded-full absolute animate-duration-2s animate-delay-2s {online ? 'bg-green animate-ping' : 'bg-red'}"></div>

View file

@ -26,7 +26,7 @@
});
</script>
<div class="relative transition-all duration-300 delay-100 starting:opacity-0 starting:translate-y-4">
<div class="relative transition-[translate,opacity] duration-300 delay-100 starting:opacity-0 starting:translate-y-4">
<div class="flex justify-center items-center absolute -top-2 right-2 z-0">
<div class="w-4 h-4 rounded-full {playing ? 'bg-green' : 'bg-red'}"></div>
<div class="w-4 h-4 rounded-full absolute animate-duration-2s animate-delay-2s {playing ? 'bg-green animate-ping' : 'bg-red'}"></div>

View file

@ -133,7 +133,7 @@
</div>
{/snippet}
<div class="grid grid-cols-2 gap-4 max-sm:grid-cols-1 transition-all duration-300 delay-300 starting:opacity-0 starting:translate-y-4">
<div class="grid grid-cols-2 gap-4 max-sm:grid-cols-1 transition-[translate,opacity] duration-300 delay-300 starting:opacity-0 starting:translate-y-4">
{@render projectColumn(leftColumn)}
{@render projectColumn(rightColumn)}
</div>

View file

@ -0,0 +1,31 @@
<script lang="ts">
let isDarkMode = $state(true);
function onClick() {
const toggle = () => {
isDarkMode = !isDarkMode;
document.documentElement.dataset.theme = isDarkMode ? "dark" : "light";
};
if (!document.startViewTransition) toggle();
document.startViewTransition(toggle);
}
</script>
<button onclick={onClick} aria-label="Toggle dark mode" class="absolute top-8 right-8 cursor-pointer">
{#if isDarkMode}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="size-12"
><path
fill="currentColor"
d="M12 1.992a10 10 0 1 0 9.236 13.838c.341-.82-.476-1.644-1.298-1.31a6.5 6.5 0 0 1-6.864-10.787l.077-.08c.551-.63.113-1.653-.758-1.653h-.266l-.068-.006z"
/></svg
>
{:else}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="size-12"
><path
fill="currentColor"
d="M12 19a1 1 0 0 1 .993.883L13 20v1a1 1 0 0 1-1.993.117L11 21v-1a1 1 0 0 1 1-1m6.313-2.09l.094.083l.7.7a1 1 0 0 1-1.32 1.497l-.094-.083l-.7-.7a1 1 0 0 1 1.218-1.567zm-11.306.083a1 1 0 0 1 .083 1.32l-.083.094l-.7.7a1 1 0 0 1-1.497-1.32l.083-.094l.7-.7a1 1 0 0 1 1.414 0M4 11a1 1 0 0 1 .117 1.993L4 13H3a1 1 0 0 1-.117-1.993L3 11zm17 0a1 1 0 0 1 .117 1.993L21 13h-1a1 1 0 0 1-.117-1.993L20 11zM6.213 4.81l.094.083l.7.7a1 1 0 0 1-1.32 1.497l-.094-.083l-.7-.7A1 1 0 0 1 6.11 4.74zm12.894.083a1 1 0 0 1 .083 1.32l-.083.094l-.7.7a1 1 0 0 1-1.497-1.32l.083-.094l.7-.7a1 1 0 0 1 1.414 0M12 2a1 1 0 0 1 .993.883L13 3v1a1 1 0 0 1-1.993.117L11 4V3a1 1 0 0 1 1-1m0 5a5 5 0 1 1-4.995 5.217L7 12l.005-.217A5 5 0 0 1 12 7"
/></svg
>
{/if}
</button>

View file

@ -16,7 +16,7 @@ import DockerIcon from "../assets/icons/coding/docker.svg";
import LinuxIcon from "../assets/icons/coding/linux.svg";
---
<section class="mb-0! transition-all duration-300 delay-200 starting:opacity-0 starting:translate-y-4">
<section class="mb-0! transition-[translate,opacity] duration-300 delay-200 starting:opacity-0 starting:translate-y-4">
<legend>tools</legend>
<!-- separator -->
@ -26,9 +26,7 @@ import LinuxIcon from "../assets/icons/coding/linux.svg";
<hr class="grow border-surface0" />
</div>
<div
class="flex flex-wrap gap-1 mb-4 *:bg-surface0/50 *:shadow *:border *:border-surface1/50 *:rounded-md *:p-1.5 *:text-sm *:flex *:items-center *:gap-1.5"
>
<div class="flex flex-wrap gap-1 mb-4 *:bg-surface0/50 *:shadow *:border *:border-surface1/50 *:rounded-md *:p-1.5 *:text-sm *:flex *:items-center *:gap-1.5">
<div>
<VSCodiumIcon class="size-5" />
<span>VSCodium</span>
@ -46,9 +44,7 @@ import LinuxIcon from "../assets/icons/coding/linux.svg";
<hr class="grow border-surface0" />
</div>
<div
class="flex flex-wrap gap-1 mb-4 *:bg-surface0/50 *:shadow *:border *:border-surface1/50 *:rounded-md *:p-1.5 *:text-sm *:flex *:items-center *:gap-1.5"
>
<div class="flex flex-wrap gap-1 mb-4 *:bg-surface0/50 *:shadow *:border *:border-surface1/50 *:rounded-md *:p-1.5 *:text-sm *:flex *:items-center *:gap-1.5">
<div>
<TypeScriptIcon class="size-5" />
<span>TypeScript</span>
@ -78,9 +74,7 @@ import LinuxIcon from "../assets/icons/coding/linux.svg";
<hr class="grow border-surface0" />
</div>
<div
class="flex flex-wrap gap-1 mb-4 *:bg-surface0/50 *:shadow *:border *:border-surface1/50 *:rounded-md *:p-1.5 *:text-sm *:flex *:items-center *:gap-1.5"
>
<div class="flex flex-wrap gap-1 mb-4 *:bg-surface0/50 *:shadow *:border *:border-surface1/50 *:rounded-md *:p-1.5 *:text-sm *:flex *:items-center *:gap-1.5">
<div>
<SvelteIcon class="size-5" />
<span>Svelte</span>

View file

@ -6,6 +6,7 @@ import "../style.css";
import { Image } from "astro:assets";
import ThemeButton from "../components/ThemeButton.svelte";
import Socials from "../components/Socials.astro";
import Clock from "../components/Clock.svelte";
import Online from "../components/Online.svelte";
@ -15,11 +16,10 @@ import Footer from "../components/Footer.astro";
import KawaiiLogo from "../assets/kawaii.svg";
import TrafficConeAlt from "../assets/traffic-cone-alt.svg";
import Lunar from "../assets/lunar.svg";
import ProfilePicture from "../../public/pfp.webp";
---
<html lang="en">
<html lang="en" data-theme="dark">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
@ -71,10 +71,10 @@ import ProfilePicture from "../../public/pfp.webp";
</head>
<body class="bg-base text-text flex flex-col items-center px-8">
<a href="/" aria-label="trafficlunar logo" transition:persist>
<KawaiiLogo class="w-full h-48 mt-16 drop-shadow-md transition-transform duration-300 hover:rotate-2 hover:scale-105" />
<KawaiiLogo class="w-full h-50 mt-16 pb-1.5 drop-shadow-md transition-transform duration-300 hover:rotate-2 hover:scale-105" />
</a>
<Lunar aria-hidden class="absolute top-8 right-8 size-12 animate-avoid hover:animate-running not-hover:animate-pause" />
<ThemeButton client:only />
<div class="max-w-4xl w-full grid grid-cols-5 gap-4 py-8 max-[60rem]:grid-cols-1">
<div class="flex flex-col max-[32rem]:flex-row lg:flex-col items-center gap-6 sm:gap-8 lg:gap-8 justify-center md:justify-start" transition:persist>
@ -86,7 +86,7 @@ import ProfilePicture from "../../public/pfp.webp";
height="160"
alt="profile picture"
decoding="async"
class="rounded-full animate-spin animate-duration-2s hover:animate-running not-hover:animate-pause max-h-40 max-w-40 min-h-40 min-w-40"
class="rounded-full drop-shadow-md animate-spin animate-duration-2s hover:animate-running not-hover:animate-pause max-h-40 max-w-40 min-h-40 min-w-40"
/>
</a>

View file

@ -5,7 +5,9 @@ import EightyEightyThirtyOne from "../components/88x31.svelte";
---
<Layout>
<section class="mb-0! transition-all duration-300 delay-100 starting:opacity-0 starting:translate-y-4 text-[0.938rem] [&_img]:w-[88px] [&_img]:h-[31px]">
<section
class="mb-0! transition-[translate,opacity] duration-300 delay-100 starting:opacity-0 starting:translate-y-4 text-[0.938rem] [&_img]:w-[88px] [&_img]:h-[31px]"
>
<legend>buttons</legend>
<p class="mb-1">

View file

@ -10,7 +10,7 @@ import LocationIcon from "../assets/icons/location.svg";
---
<Layout>
<section class="transition-all duration-300 delay-100 starting:opacity-0 starting:translate-y-4 text-[0.938rem]">
<section class="transition-[translate,opacity] duration-300 delay-100 starting:opacity-0 starting:translate-y-4 text-[0.938rem]">
<legend>about</legend>
<p>
Hey! I'm <strong class="text-peach">trafficlunar</strong>. I'm a <Age client:only /> year old self-proclaimed full-stack developer.
@ -45,7 +45,9 @@ import LocationIcon from "../assets/icons/location.svg";
<Tools />
<div class="flex items-center gap-4 text-subtext0 text-sm font-medium my-4 transition-all duration-300 delay-250 starting:opacity-0 starting:translate-y-4">
<div
class="flex items-center gap-4 text-subtext0 text-sm font-medium my-4 transition-[translate,opacity] duration-300 delay-250 starting:opacity-0 starting:translate-y-4"
>
<hr class="grow border-surface1" />
<span>projects</span>
<hr class="grow border-surface1" />

View file

@ -19,6 +19,39 @@
}
}
/* Catppuccin Latte */
--color-rosewater: #dc8a78;
--color-flamingo: #dd7878;
--color-pink: #ea76cb;
--color-mauve: #8839ef;
--color-red: #d20f39;
--color-maroon: #e64553;
--color-peach: #fe640b;
--color-yellow: #df8e1d;
--color-green: #40a02b;
--color-teal: #179287;
--color-sky: #04a5e5;
--color-sapphire: #209fb5;
--color-blue: #1e66f5;
--color-lavender: #7287fd;
--color-text: #4c4f69;
--color-subtext1: #5c5f77;
--color-subtext0: #6c6f85;
--color-overlay2: #7c7f93;
--color-overlay1: #8c8fa1;
--color-overlay0: #9ca0b0;
--color-surface2: #acb0be;
--color-surface1: #bcc0cc;
--color-surface0: #ccd0da;
--color-base: #eff1f5;
--color-mantle: #e6e9ef;
--color-crust: #dce0e8;
--color-base-darker: #eceef3;
--color-peach-darker: #ebcec1;
}
html[data-theme="dark"] {
/* Catppuccin Frappe */
--color-rosewater: #f2d5cf;
--color-flamingo: #eebebe;
@ -121,3 +154,21 @@ section legend::after {
[data-tooltip]:hover::after {
@apply opacity-100 scale-100;
}
/* Theme switching transition */
::view-transition-new(root) {
mask: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><circle cx="40" cy="0" r="20" fill="white"/></svg>') right top / 0
no-repeat;
animation: scale 1s;
animation-fill-mode: both;
}
::view-transition-old(root) {
animation: none;
}
@keyframes scale {
to {
mask-size: 250vmax;
}
}