Compare commits
No commits in common. "0314e0bbaa83ca5aeef46aa10702fed9fe46ecdc" and "b7f951b9c7417ceb26e90ef3756b8635451b2f50" have entirely different histories.
0314e0bbaa
...
b7f951b9c7
|
|
@ -38,9 +38,5 @@
|
|||
"typescript-eslint": "^8.20.0",
|
||||
"vite": "^5.4.14",
|
||||
"vitest": "^2.1.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"lucide-svelte": "^0.544.0",
|
||||
"svelte-simple-icons": "^1.0.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
75
pnpm-lock.yaml
generated
|
|
@ -7,13 +7,6 @@ settings:
|
|||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
lucide-svelte:
|
||||
specifier: ^0.544.0
|
||||
version: 0.544.0(svelte@5.19.0)
|
||||
svelte-simple-icons:
|
||||
specifier: ^1.0.3
|
||||
version: 1.0.3
|
||||
devDependencies:
|
||||
'@eslint/compat':
|
||||
specifier: ^1.2.5
|
||||
|
|
@ -23,13 +16,13 @@ importers:
|
|||
version: 9.18.0
|
||||
'@sveltejs/adapter-static':
|
||||
specifier: ^3.0.8
|
||||
version: 3.0.8(@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.19))(svelte@5.19.0)(vite@5.4.19))
|
||||
version: 3.0.8(@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.11))(svelte@5.19.0)(vite@5.4.11))
|
||||
'@sveltejs/kit':
|
||||
specifier: ^2.0.0
|
||||
version: 2.16.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.19))(svelte@5.19.0)(vite@5.4.19)
|
||||
version: 2.16.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.11))(svelte@5.19.0)(vite@5.4.11)
|
||||
'@sveltejs/vite-plugin-svelte':
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.4(svelte@5.19.0)(vite@5.4.19)
|
||||
version: 4.0.4(svelte@5.19.0)(vite@5.4.11)
|
||||
'@tailwindcss/container-queries':
|
||||
specifier: ^0.1.1
|
||||
version: 0.1.1(tailwindcss@3.4.17)
|
||||
|
|
@ -79,8 +72,8 @@ importers:
|
|||
specifier: ^8.20.0
|
||||
version: 8.20.0(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3)
|
||||
vite:
|
||||
specifier: ^5.4.14
|
||||
version: 5.4.19
|
||||
specifier: ^5.4.11
|
||||
version: 5.4.11
|
||||
vitest:
|
||||
specifier: ^2.1.8
|
||||
version: 2.1.8
|
||||
|
|
@ -1056,11 +1049,6 @@ packages:
|
|||
lru-cache@10.4.3:
|
||||
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
|
||||
|
||||
lucide-svelte@0.544.0:
|
||||
resolution: {integrity: sha512-8kBxSivf8SJdEUJRHBpu9bRw0S/qfVK+Yfb92KQnRRBdP425RzT6aQfrIfZctG1oucPVTBQe1ZXgmth/3qVICg==}
|
||||
peerDependencies:
|
||||
svelte: ^3 || ^4 || ^5.0.0-next.42
|
||||
|
||||
magic-string@0.30.17:
|
||||
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
|
||||
|
||||
|
|
@ -1461,9 +1449,6 @@ packages:
|
|||
svelte:
|
||||
optional: true
|
||||
|
||||
svelte-simple-icons@1.0.3:
|
||||
resolution: {integrity: sha512-BmQPPrV9fHMH+BJSf4xBKNP0oW2XCtWizZnfAnlOBn54UWRLWmk8uTt0JRAF5NfS+74DD09oHADAroneC94eFg==}
|
||||
|
||||
svelte@5.19.0:
|
||||
resolution: {integrity: sha512-qvd2GvvYnJxS/MteQKFSMyq8cQrAAut28QZ39ySv9k3ggmhw4Au4Rfcsqva74i0xMys//OhbhVCNfXPrDzL/Bg==}
|
||||
engines: {node: '>=18'}
|
||||
|
|
@ -1554,8 +1539,8 @@ packages:
|
|||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
hasBin: true
|
||||
|
||||
vite@5.4.19:
|
||||
resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==}
|
||||
vite@5.4.11:
|
||||
resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
|
|
@ -1893,13 +1878,13 @@ snapshots:
|
|||
'@rollup/rollup-win32-x64-msvc@4.30.1':
|
||||
optional: true
|
||||
|
||||
'@sveltejs/adapter-static@3.0.8(@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.19))(svelte@5.19.0)(vite@5.4.19))':
|
||||
'@sveltejs/adapter-static@3.0.8(@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.11))(svelte@5.19.0)(vite@5.4.11))':
|
||||
dependencies:
|
||||
'@sveltejs/kit': 2.16.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.19))(svelte@5.19.0)(vite@5.4.19)
|
||||
'@sveltejs/kit': 2.16.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.11))(svelte@5.19.0)(vite@5.4.11)
|
||||
|
||||
'@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.19))(svelte@5.19.0)(vite@5.4.19)':
|
||||
'@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.11))(svelte@5.19.0)(vite@5.4.11)':
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.19.0)(vite@5.4.19)
|
||||
'@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.19.0)(vite@5.4.11)
|
||||
'@types/cookie': 0.6.0
|
||||
cookie: 0.6.0
|
||||
devalue: 5.1.1
|
||||
|
|
@ -1912,27 +1897,27 @@ snapshots:
|
|||
set-cookie-parser: 2.7.1
|
||||
sirv: 3.0.0
|
||||
svelte: 5.19.0
|
||||
vite: 5.4.19
|
||||
vite: 5.4.11
|
||||
|
||||
'@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.19))(svelte@5.19.0)(vite@5.4.19)':
|
||||
'@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.11))(svelte@5.19.0)(vite@5.4.11)':
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.19.0)(vite@5.4.19)
|
||||
'@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.19.0)(vite@5.4.11)
|
||||
debug: 4.4.0
|
||||
svelte: 5.19.0
|
||||
vite: 5.4.19
|
||||
vite: 5.4.11
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.19)':
|
||||
'@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.11)':
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.19))(svelte@5.19.0)(vite@5.4.19)
|
||||
'@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.19.0)(vite@5.4.11))(svelte@5.19.0)(vite@5.4.11)
|
||||
debug: 4.4.0
|
||||
deepmerge: 4.3.1
|
||||
kleur: 4.1.5
|
||||
magic-string: 0.30.17
|
||||
svelte: 5.19.0
|
||||
vite: 5.4.19
|
||||
vitefu: 1.0.5(vite@5.4.19)
|
||||
vite: 5.4.11
|
||||
vitefu: 1.0.5(vite@5.4.11)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
|
|
@ -2040,13 +2025,13 @@ snapshots:
|
|||
chai: 5.1.2
|
||||
tinyrainbow: 1.2.0
|
||||
|
||||
'@vitest/mocker@2.1.8(vite@5.4.19)':
|
||||
'@vitest/mocker@2.1.8(vite@5.4.11)':
|
||||
dependencies:
|
||||
'@vitest/spy': 2.1.8
|
||||
estree-walker: 3.0.3
|
||||
magic-string: 0.30.17
|
||||
optionalDependencies:
|
||||
vite: 5.4.19
|
||||
vite: 5.4.11
|
||||
|
||||
'@vitest/pretty-format@2.1.8':
|
||||
dependencies:
|
||||
|
|
@ -2556,10 +2541,6 @@ snapshots:
|
|||
|
||||
lru-cache@10.4.3: {}
|
||||
|
||||
lucide-svelte@0.544.0(svelte@5.19.0):
|
||||
dependencies:
|
||||
svelte: 5.19.0
|
||||
|
||||
magic-string@0.30.17:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
|
|
@ -2880,8 +2861,6 @@ snapshots:
|
|||
optionalDependencies:
|
||||
svelte: 5.19.0
|
||||
|
||||
svelte-simple-icons@1.0.3: {}
|
||||
|
||||
svelte@5.19.0:
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.3.0
|
||||
|
|
@ -2999,7 +2978,7 @@ snapshots:
|
|||
debug: 4.4.0
|
||||
es-module-lexer: 1.6.0
|
||||
pathe: 1.1.2
|
||||
vite: 5.4.19
|
||||
vite: 5.4.11
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- less
|
||||
|
|
@ -3011,7 +2990,7 @@ snapshots:
|
|||
- supports-color
|
||||
- terser
|
||||
|
||||
vite@5.4.19:
|
||||
vite@5.4.11:
|
||||
dependencies:
|
||||
esbuild: 0.21.5
|
||||
postcss: 8.5.1
|
||||
|
|
@ -3019,14 +2998,14 @@ snapshots:
|
|||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
vitefu@1.0.5(vite@5.4.19):
|
||||
vitefu@1.0.5(vite@5.4.11):
|
||||
optionalDependencies:
|
||||
vite: 5.4.19
|
||||
vite: 5.4.11
|
||||
|
||||
vitest@2.1.8:
|
||||
dependencies:
|
||||
'@vitest/expect': 2.1.8
|
||||
'@vitest/mocker': 2.1.8(vite@5.4.19)
|
||||
'@vitest/mocker': 2.1.8(vite@5.4.11)
|
||||
'@vitest/pretty-format': 2.1.8
|
||||
'@vitest/runner': 2.1.8
|
||||
'@vitest/snapshot': 2.1.8
|
||||
|
|
@ -3042,7 +3021,7 @@ snapshots:
|
|||
tinyexec: 0.3.2
|
||||
tinypool: 1.0.2
|
||||
tinyrainbow: 1.2.0
|
||||
vite: 5.4.19
|
||||
vite: 5.4.11
|
||||
vite-node: 2.1.8
|
||||
why-is-node-running: 2.3.0
|
||||
transitivePeerDependencies:
|
||||
|
|
|
|||
|
|
@ -1,97 +1,79 @@
|
|||
<script>
|
||||
import Project from './project.svelte';
|
||||
import ThemeToggle from './theme.svelte';
|
||||
import TiltCard from './tiltcard.svelte';
|
||||
<div>
|
||||
<span class="text-2xl">Portfolio under construction...</span>
|
||||
<br />
|
||||
|
||||
// Assuming icons for Github, Gitlab, Codeberg (Code), Forgejo (GitBranch)
|
||||
import { Github, Gitlab, Code, GitBranch } from 'lucide-svelte';
|
||||
If you felt disappointed, let it be a practice to control your expectations... But I promise to
|
||||
tidy this place up soon!!! :D
|
||||
<br />
|
||||
|
||||
const repository = {
|
||||
label: 'Forge',
|
||||
url: 'https://git.light7734.com/light7734/light',
|
||||
iconComponent: GitBranch
|
||||
};
|
||||
Anyways, here are some links to all my <span class="text-accent_text"> social handles </span>:
|
||||
<br />
|
||||
<br />
|
||||
|
||||
const mirrors = [
|
||||
{ label: 'Github', url: 'https://github.com/light7734/light', iconComponent: Github },
|
||||
{ label: 'Gitlab', url: 'https://gitlab.com/light7734/light', iconComponent: Gitlab },
|
||||
{ label: 'Codeberg', url: 'https://codeberg.org/light7734/light', iconComponent: Code }
|
||||
];
|
||||
Mail:
|
||||
<a href="mailto:light7734@tuta.io" class="text-blue"> light7734@tuta.io </a>
|
||||
<br />
|
||||
|
||||
const gallery = [
|
||||
'https://placekittens.com/720/480',
|
||||
'https://placekittens.com/720/481',
|
||||
'https://placekittens.com/720/482',
|
||||
'https://placekittens.com/720/483',
|
||||
'https://placekittens.com/720/484',
|
||||
'https://placekittens.com/720/484'
|
||||
];
|
||||
Youtube:
|
||||
<a href="https://www.youtube.com/@light.7734" class="text-blue"> @light.7734 </a>
|
||||
<br />
|
||||
|
||||
const features = ['MSAA', 'SSAO', 'PBR Lighting'];
|
||||
Twitter:
|
||||
<a href="https://x.com/light7734" class="text-blue"> @light7734 </a>
|
||||
<br />
|
||||
|
||||
const languages = [{ name: 'C++23', icon: 'cplusplus.svg' }, { name: 'CMake' }];
|
||||
Bluesky:
|
||||
<a href="https://bsky.app/profile/light7734.bsky.social" class="text-blue"> @light7734 </a>
|
||||
<br />
|
||||
|
||||
const graphicsApis = ['Vulkan', 'Metal', 'DirectX12'];
|
||||
Reddit:
|
||||
<a href="https://www.reddit.com/user/Light7734/" class="text-blue"> u/light7734 </a>
|
||||
<br />
|
||||
|
||||
const cicd = ['Drone', 'Docker'];
|
||||
</script>
|
||||
Itcho.io:
|
||||
<a href="https://light7734.itch.io/" class="text-blue"> light7734 </a>
|
||||
<br />
|
||||
|
||||
<div
|
||||
class="flex min-h-screen bg-gruvboxLight-bg text-gruvboxLight-fg transition-colors duration-300 dark:bg-gruvboxDark-bg dark:text-gruvboxDark-fg"
|
||||
>
|
||||
<div class="flex-1 bg-[#1d2021]"></div>
|
||||
<main class="bg-card relative flex-[10] p-8 transition-all duration-300 ease-out">
|
||||
<div class="absolute right-0 top-0">
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
Discord: @light7734
|
||||
<br />
|
||||
|
||||
<h1>Bio</h1>
|
||||
Discord Community: @light7734
|
||||
<br />
|
||||
|
||||
<br />
|
||||
Telegram Dailies: soon
|
||||
<br />
|
||||
|
||||
<Project
|
||||
title="LIGHT"
|
||||
description_preview="Dependency free, cross-platform, cross-graphics-api, bleeding-edge game engine."
|
||||
description="Dependency free, cross-platform, cross-graphics-api, bleeding-edge game engine."
|
||||
icon="/light.svg"
|
||||
{repository}
|
||||
{mirrors}
|
||||
{gallery}
|
||||
{features}
|
||||
{languages}
|
||||
{graphicsApis}
|
||||
{cicd}
|
||||
/>
|
||||
Instagram: soon
|
||||
<br />
|
||||
|
||||
<br />
|
||||
<Project
|
||||
title="LIGHT"
|
||||
description_preview="Dependency free, cross-platform, cross-graphics-api, bleeding-edge game engine."
|
||||
description="Detailed description here."
|
||||
icon="/light.svg"
|
||||
{repository}
|
||||
{mirrors}
|
||||
{gallery}
|
||||
{features}
|
||||
{languages}
|
||||
{graphicsApis}
|
||||
{cicd}
|
||||
/>
|
||||
</main>
|
||||
<div class="flex-1 bg-[#1d2021]"></div>
|
||||
Forgejo (git repos):
|
||||
<a href="https://git.light7734.com/light7734" class="text-blue"> git.light7734.com </a>
|
||||
<br />
|
||||
|
||||
Codeberg (mirrors):
|
||||
<a href="https://codeberg.org/light7734" class="text-blue"> @light7734 </a>
|
||||
<br />
|
||||
|
||||
Github (mirrors):
|
||||
<a href="https://codeberg.org/light7734" class="text-blue"> @light7734 </a>
|
||||
<br />
|
||||
|
||||
Gitlab (mirrors):
|
||||
<a href="https://gitlab.com/Light7734" class="text-blue"> @light7734 </a>
|
||||
<br />
|
||||
</div>
|
||||
|
||||
<!-- Brief Bio
|
||||
-->
|
||||
|
||||
<!--OPEN SOURCE PROJECTS -->
|
||||
<!-- Description
|
||||
<!-- Brief Dazzle
|
||||
I love teaching! I've learned that it's the most effective way to solidify your knowledge and leave
|
||||
little to no gaps. Dazzle is the collection of my articles teaching a subject in depth. It delves
|
||||
into topics such as rendering, mathematics, guidelines and more. It's just my way of giving back to
|
||||
the community!
|
||||
-->
|
||||
<!-- Gallery
|
||||
<...images...>
|
||||
-->
|
||||
<!-- Technical Details
|
||||
Technology behind Dazzle:
|
||||
|
|
@ -124,6 +106,9 @@ Technology behind Light:
|
|||
OpenGL, Vulkan, Metal, DirectX12
|
||||
CICD:
|
||||
Drone, Docker,
|
||||
|
||||
Prominent vendor libs:
|
||||
EnTT, Glfw3.4, Dear (truly a dear) ImGui,
|
||||
|
||||
Check out the source code on any of the official mirrors or on the main self-hosted repo.
|
||||
Self-hosted with <3 using Forgejo (a fork of Gittea)
|
||||
|
|
|
|||
|
|
@ -1,192 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { ChevronDown, ChevronUp, ExternalLink } from 'lucide-svelte';
|
||||
import TiltCard from './tiltcard.svelte';
|
||||
|
||||
import { Github, Gitlab, Code, GitBranch } from 'lucide-svelte';
|
||||
|
||||
interface ProjectLink {
|
||||
label: string;
|
||||
url: string;
|
||||
iconComponent: any;
|
||||
}
|
||||
|
||||
interface Language {
|
||||
name: string;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
export let title: string;
|
||||
export let description_preview: string;
|
||||
export let description: string;
|
||||
export let icon: string;
|
||||
export let repository: ProjectLink = { label: 'Forgejo', url: '', iconComponent: GitBranch };
|
||||
export let mirrors: ProjectLink[] = [
|
||||
{ label: 'Github', url: '', iconComponent: Github },
|
||||
{ label: 'Gitlab', url: '', iconComponent: Gitlab },
|
||||
{ label: 'Codeberg', url: '', iconComponent: Code }
|
||||
];
|
||||
export let gallery: string[] = [];
|
||||
export let features: string[] = [];
|
||||
export let languages: Language[] = [];
|
||||
export let graphicsApis: string[] = [];
|
||||
export let cicd: string[] = [];
|
||||
|
||||
let expansionStage = 0; // 0: collapsed, 1: description, 2: gallery, 3: source code
|
||||
const MAX_STAGE = 3;
|
||||
|
||||
function toggleExpansion() {
|
||||
expansionStage = expansionStage >= MAX_STAGE ? 0 : expansionStage + 1;
|
||||
}
|
||||
|
||||
import { slide } from 'svelte/transition';
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="bg-card border-border relative mx-auto w-full max-w-2xl rounded-lg border transition-all duration-300 ease-out hover:scale-[1.01] hover:shadow-[5px_5px_5px_#000000]"
|
||||
>
|
||||
<div class="p-6">
|
||||
<div class="mb-4 flex items-center gap-4">
|
||||
<div class="flex-shrink-0">
|
||||
<TiltCard imageSrc={icon} imageAlt="{title} icon" width="256px" height="256px" />
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<TiltCard imageSrc="/light_text.svg" imageAlt="{title} icon" width="auto" height="auto" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-muted-foreground leading-relaxed">
|
||||
{expansionStage >= 1 ? description : description_preview}
|
||||
</p>
|
||||
|
||||
{#if expansionStage >= 1}
|
||||
<div class="py-4" transition:slide={{ duration: 300 }}>
|
||||
{#if features.length > 0 || languages.length > 0 || graphicsApis.length > 0 || cicd.length > 0}
|
||||
{#if features.length > 0}
|
||||
<h3 class="text-muted-foreground mb-3 text-sm font-semibold uppercase tracking-wide">
|
||||
Features
|
||||
</h3>
|
||||
<ul class="text-muted-foreground mb-2 list-disc pl-5">
|
||||
{#each features as feature}
|
||||
<li>{feature}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
<h4 class="mb-1 font-medium">Technology behind {title}:</h4>
|
||||
{#if languages.length > 0}
|
||||
<h5 class="mb-1 text-sm">Languages:</h5>
|
||||
<div class="mb-2 flex flex-wrap gap-2">
|
||||
{#each languages as lang}
|
||||
<span class="flex items-center gap-1">
|
||||
{#if lang.icon}
|
||||
<img src={lang.icon} alt="{lang.name} icon" class="ivert h-4 w-4" />
|
||||
{/if}
|
||||
{lang.name}
|
||||
</span>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{#if graphicsApis.length > 0}
|
||||
<h5 class="mb-1 text-sm">Graphics APIs:</h5>
|
||||
<div class="mb-2 flex flex-wrap gap-2">
|
||||
{#each graphicsApis as api}
|
||||
<span>{api}</span>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{#if cicd.length > 0}
|
||||
<h5 class="mb-1 text-sm">CICD:</h5>
|
||||
<div class="mb-2 flex flex-wrap gap-2">
|
||||
{#each cicd as tool}
|
||||
<span>{tool}</span>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if expansionStage >= 2 && gallery.length > 0}
|
||||
<div transition:slide={{ duration: 300 }}>
|
||||
<h3 class="text-muted-foreground mb-3 text-sm font-semibold uppercase tracking-wide">
|
||||
Gallery
|
||||
</h3>
|
||||
<div class="mb-4 grid grid-cols-3 gap-2">
|
||||
{#each gallery as img}
|
||||
<img src={img} alt="{title} screenshot" class="rounded object-cover" />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if expansionStage >= 3}
|
||||
<div transition:slide={{ duration: 300 }}>
|
||||
<div class="border-border border-t pt-4">
|
||||
<div class="flex items-start justify-start gap-0">
|
||||
<div class="flex-none">
|
||||
<h3 class="text-muted-foreground mb-2 text-sm font-semibold uppercase tracking-wide">
|
||||
Repository
|
||||
</h3>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<a
|
||||
href={repository.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-accent-foreground flex items-center gap-1 transition-colors duration-200 hover:underline"
|
||||
>
|
||||
<svelte:component this={repository.iconComponent} class="h-4 w-4" />
|
||||
{repository.label}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-border mx-4 h-8 self-center border-l"></div>
|
||||
<div class="flex-none">
|
||||
<h3 class="text-muted-foreground mb-2 text-sm font-semibold uppercase tracking-wide">
|
||||
Mirrors
|
||||
</h3>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
{#each mirrors as link}
|
||||
<a
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-accent-foreground flex items-center gap-1 transition-colors duration-200 hover:underline"
|
||||
>
|
||||
<svelte:component this={link.iconComponent} class="h-4 w-4" />
|
||||
{link.label}
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<button
|
||||
on:click={toggleExpansion}
|
||||
class="bg-muted/50 hover:bg-muted text-muted-foreground hover:text-foreground border-border group flex w-full items-center justify-center gap-2 rounded-b-lg border-t px-6 py-3 transition-colors duration-200"
|
||||
>
|
||||
{#if expansionStage >= MAX_STAGE}
|
||||
<ChevronUp
|
||||
class="h-4 w-16 transition-transform duration-200 group-hover:translate-y-[-2px]"
|
||||
/>
|
||||
{:else}
|
||||
<ChevronDown
|
||||
class="h-30 w-30 transition-transform duration-200 group-hover:translate-y-[2px]"
|
||||
/>
|
||||
<span class="font-bold">
|
||||
{#if expansionStage === 0}
|
||||
FEATURES
|
||||
{:else if expansionStage === 1}
|
||||
GALLERY
|
||||
{:else if expansionStage === 2}
|
||||
SOURCE
|
||||
{/if}
|
||||
</span>
|
||||
<ChevronDown
|
||||
class="h-30 w-30 transition-transform duration-200 group-hover:translate-y-[2px]"
|
||||
/>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
import { Sun, Moon } from 'lucide-svelte';
|
||||
const theme = writable<'light' | 'dark'>('light');
|
||||
|
||||
onMount(() => {
|
||||
// Load from localStorage if exists
|
||||
const stored = localStorage.getItem('theme');
|
||||
if (stored === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
theme.set('dark');
|
||||
}
|
||||
});
|
||||
|
||||
function toggleTheme() {
|
||||
theme.update((current) => {
|
||||
const next = current === 'light' ? 'dark' : 'light';
|
||||
if (next === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
localStorage.setItem('theme', next);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<button
|
||||
on:click={toggleTheme}
|
||||
class="text-gruvboxLight-fg dark:text-gruvboxDark-fg rounded-md px-4 py-2 transition-all duration-300 ease-out hover:scale-[1.05] hover:drop-shadow-[2px_2px_1px_#000000]"
|
||||
>
|
||||
{#if $theme === 'light'}
|
||||
<Moon class="size-8" />
|
||||
{/if}
|
||||
|
||||
{#if $theme === 'dark'}
|
||||
<Sun class="size-8" />
|
||||
{/if}
|
||||
</button>
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
<script lang="ts">
|
||||
export let imageSrc: string;
|
||||
export let imageAlt: string = 'Card image';
|
||||
export let width: string = '300px';
|
||||
export let height: string = '400px';
|
||||
|
||||
let cardElement: HTMLDivElement;
|
||||
let rotateX = 0;
|
||||
let rotateY = 0;
|
||||
let isHovered = false;
|
||||
|
||||
// Derived shadow offsets
|
||||
let shadowX = 0;
|
||||
let shadowY = 0;
|
||||
let shadowBlur = 20;
|
||||
|
||||
function handleMouseMove(event: MouseEvent) {
|
||||
if (!cardElement) return;
|
||||
|
||||
const rect = cardElement.getBoundingClientRect();
|
||||
const x = event.clientX - rect.left;
|
||||
const y = event.clientY - rect.top;
|
||||
|
||||
const centerX = rect.width / 2;
|
||||
const centerY = rect.height / 2;
|
||||
|
||||
// Calculate rotation based on cursor position (max tilt of 10 degrees)
|
||||
rotateY = ((x - centerX) / centerX) * 10 * 2;
|
||||
rotateX = ((centerY - y) / centerY) * 10 * 2;
|
||||
|
||||
// Make shadow move opposite to tilt for a realistic lighting effect
|
||||
shadowX = -rotateY * 0.7; // exaggerate slightly
|
||||
shadowY = rotateX * 0.7;
|
||||
}
|
||||
|
||||
function handleMouseEnter() {
|
||||
isHovered = true;
|
||||
}
|
||||
|
||||
function handleMouseLeave() {
|
||||
isHovered = false;
|
||||
rotateX = 0;
|
||||
rotateY = 0;
|
||||
shadowX = 0;
|
||||
shadowY = 0;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
bind:this={cardElement}
|
||||
class="cursor-pointer"
|
||||
class:scale-[1.03]={isHovered}
|
||||
style="
|
||||
width: {width};
|
||||
height: {height};
|
||||
perspective: 1000px;
|
||||
filter: drop-shadow({shadowX}px {shadowY}px 0px rgba(0, 0, 0, 0.5));
|
||||
"
|
||||
on:mousemove={handleMouseMove}
|
||||
on:mouseenter={handleMouseEnter}
|
||||
on:mouseleave={handleMouseLeave}
|
||||
role="img"
|
||||
aria-label={imageAlt}
|
||||
>
|
||||
<img
|
||||
src={imageSrc}
|
||||
alt={imageAlt}
|
||||
class="h-full w-full rounded-xl object-cover transition-transform duration-100 ease-out"
|
||||
style="
|
||||
transform: rotateX({rotateX}deg) rotateY({rotateY}deg);
|
||||
transform-style: preserve-3d;
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -1 +0,0 @@
|
|||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>C++</title><path d="M22.394 6c-.167-.29-.398-.543-.652-.69L12.926.22c-.509-.294-1.34-.294-1.848 0L2.26 5.31c-.508.293-.923 1.013-.923 1.6v10.18c0 .294.104.62.271.91.167.29.398.543.652.69l8.816 5.09c.508.293 1.34.293 1.848 0l8.816-5.09c.254-.147.485-.4.652-.69.167-.29.27-.616.27-.91V6.91c.003-.294-.1-.62-.268-.91zM12 19.11c-3.92 0-7.109-3.19-7.109-7.11 0-3.92 3.19-7.11 7.11-7.11a7.133 7.133 0 016.156 3.553l-3.076 1.78a3.567 3.567 0 00-3.08-1.78A3.56 3.56 0 008.444 12 3.56 3.56 0 0012 15.555a3.57 3.57 0 003.08-1.778l3.078 1.78A7.135 7.135 0 0112 19.11zm7.11-6.715h-.79v.79h-.79v-.79h-.79v-.79h.79v-.79h.79v.79h.79zm2.962 0h-.79v.79h-.79v-.79h-.79v-.79h.79v-.79h.79v.79h.79z"/></svg>
|
||||
|
Before Width: | Height: | Size: 764 B |
|
|
@ -1,57 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="512"
|
||||
height="256"
|
||||
viewBox="0 0 135.46667 67.733334"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:export-filename="light_text.svg"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||
sodipodi:docname="drawing.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="px"
|
||||
inkscape:zoom="4.1228676"
|
||||
inkscape:cx="335.20359"
|
||||
inkscape:cy="230.30087"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1368"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:39.5424px;font-family:'Noto Sans Elbasan';-inkscape-font-specification:'Noto Sans Elbasan';text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#e21a41;fill-opacity:1;stroke:#000000;stroke-width:13.1808;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0"
|
||||
x="12.127329"
|
||||
y="50.100418"
|
||||
id="text1"
|
||||
transform="scale(1.0765584,0.92888597)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan1"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'XP Ziba';-inkscape-font-specification:'XP Ziba';fill:#e21a41;fill-opacity:1;stroke:#000000;stroke-width:13.1808;stroke-opacity:0"
|
||||
x="12.127329"
|
||||
y="50.100418">LIGHT</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB |
BIN
static/light.png
|
Before Width: | Height: | Size: 6.9 KiB |
|
|
@ -1,79 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="200"
|
||||
height="200"
|
||||
viewBox="0 0 52.916667 52.916669"
|
||||
version="1.1"
|
||||
id="svg5998"
|
||||
sodipodi:docname="light.svg"
|
||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||
inkscape:export-filename="light.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview10"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.1083899"
|
||||
inkscape:cx="153.37563"
|
||||
inkscape:cy="221.94356"
|
||||
inkscape:window-width="1130"
|
||||
inkscape:window-height="1269"
|
||||
inkscape:window-x="26"
|
||||
inkscape:window-y="23"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg5998">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid2988"
|
||||
originx="0"
|
||||
originy="0"
|
||||
spacingy="1"
|
||||
spacingx="1"
|
||||
units="mm" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs5995" />
|
||||
<g
|
||||
id="g3561"
|
||||
transform="matrix(1.0702951,0,0,1.0725059,5.8605666,5.8179937)">
|
||||
<path
|
||||
style="fill:none;stroke:#e21a41;stroke-width:2.11667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.8;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers;stop-color:#000000"
|
||||
d="M 19.245009,12.226594 9.8870095,0.52916664 H 28.602909 Z"
|
||||
id="path1118"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#e21a41;stroke-width:2.11667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.8;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers;stop-color:#000000"
|
||||
d="M 19.245009,19.245046 9.8870095,7.5476166 0.52910948,19.245046 c 6.23860002,0 18.83849952,-1.05e-4 18.71589952,0 z"
|
||||
id="path1120"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#e21a41;stroke-width:2.11667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.8;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers;stop-color:#000000"
|
||||
d="M 0.52910948,19.245046 19.245009,37.960915 V 19.245046 Z"
|
||||
id="path1122"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#e21a41;stroke-width:2.11667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.8;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers;stop-color:#000000"
|
||||
d="m 37.960809,19.245046 -18.7158,18.715869 V 19.245046 Z"
|
||||
id="path1124"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#e21a41;stroke-width:2.11667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.8;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers;stop-color:#000000"
|
||||
d="m 37.960809,19.245046 -9.3579,-11.6974294 -9.3579,11.6974294 c 6.2386,0 18.8385,-1.05e-4 18.7158,0 z"
|
||||
id="path1126"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="512"
|
||||
height="256"
|
||||
viewBox="0 0 135.46667 67.733334"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
id="layer1">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:39.5424px;font-family:'Noto Sans Elbasan';-inkscape-font-specification:'Noto Sans Elbasan';text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#e21a41;fill-opacity:1;stroke:#000000;stroke-width:13.1808;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0"
|
||||
x="12.127329"
|
||||
y="50.100418"
|
||||
id="text1"
|
||||
transform="scale(1.0765584,0.92888597)"><tspan
|
||||
id="tspan1"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'XP Ziba';-inkscape-font-specification:'XP Ziba';fill:#e21a41;fill-opacity:1;stroke:#000000;stroke-width:13.1808;stroke-opacity:0"
|
||||
x="12.127329"
|
||||
y="50.100418">LIGHT</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
BIN
static/pfp.jpg
|
Before Width: | Height: | Size: 620 KiB |
|
|
@ -3,51 +3,28 @@ import typography from '@tailwindcss/typography';
|
|||
import type { Config } from 'tailwindcss';
|
||||
|
||||
export default {
|
||||
darkMode: 'class', // important for theme switching
|
||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
// Gruvbox Light
|
||||
gruvboxLight: {
|
||||
bg: '#fbf1c7',
|
||||
fg: '#3c3836',
|
||||
primary: '#458588',
|
||||
secondary: '#b16286',
|
||||
accent: '#d79921',
|
||||
neutral: '#a89984',
|
||||
muted: '#7c6f64',
|
||||
red: '#cc241d',
|
||||
green: '#98971a',
|
||||
blue: '#458588',
|
||||
yellow: '#d79921',
|
||||
orange: '#d65d0e',
|
||||
purple: '#b16286',
|
||||
aqua: '#689d6a'
|
||||
},
|
||||
extend: {},
|
||||
colors: {
|
||||
foundation: '#282828',
|
||||
primary: '#282828',
|
||||
secondary: '#000000',
|
||||
accent: '#ff0000',
|
||||
|
||||
// Gruvbox Dark
|
||||
gruvboxDark: {
|
||||
bg: '#282828',
|
||||
fg: '#ebdbb2',
|
||||
primary: '#83a598',
|
||||
secondary: '#d3869b',
|
||||
accent: '#fabd2f',
|
||||
neutral: '#928374',
|
||||
muted: '#7c6f64',
|
||||
red: '#fb4934',
|
||||
green: '#b8bb26',
|
||||
blue: '#83a598',
|
||||
yellow: '#fabd2f',
|
||||
orange: '#fe8019',
|
||||
purple: '#d3869b',
|
||||
aqua: '#8ec07c'
|
||||
}
|
||||
}
|
||||
neutral: '#000000',
|
||||
|
||||
primary_text: '#fbf1c7',
|
||||
muted_text: '#a89984',
|
||||
accent_text: '#fb4934',
|
||||
|
||||
red: '#000000',
|
||||
green: '#000000',
|
||||
blue: '#83a598',
|
||||
yellow: '#000000'
|
||||
}
|
||||
},
|
||||
|
||||
plugins: [typography, containerQueries]
|
||||
} satisfies Config;
|
||||
|
||||
|
|
|
|||