Compare commits

..

No commits in common. "0314e0bbaa83ca5aeef46aa10702fed9fe46ecdc" and "b7f951b9c7417ceb26e90ef3756b8635451b2f50" have entirely different histories.

14 changed files with 98 additions and 633 deletions

View file

@ -38,9 +38,5 @@
"typescript-eslint": "^8.20.0", "typescript-eslint": "^8.20.0",
"vite": "^5.4.14", "vite": "^5.4.14",
"vitest": "^2.1.8" "vitest": "^2.1.8"
},
"dependencies": {
"lucide-svelte": "^0.544.0",
"svelte-simple-icons": "^1.0.3"
} }
} }

75
pnpm-lock.yaml generated
View file

@ -7,13 +7,6 @@ settings:
importers: 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: devDependencies:
'@eslint/compat': '@eslint/compat':
specifier: ^1.2.5 specifier: ^1.2.5
@ -23,13 +16,13 @@ importers:
version: 9.18.0 version: 9.18.0
'@sveltejs/adapter-static': '@sveltejs/adapter-static':
specifier: ^3.0.8 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': '@sveltejs/kit':
specifier: ^2.0.0 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': '@sveltejs/vite-plugin-svelte':
specifier: ^4.0.0 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': '@tailwindcss/container-queries':
specifier: ^0.1.1 specifier: ^0.1.1
version: 0.1.1(tailwindcss@3.4.17) version: 0.1.1(tailwindcss@3.4.17)
@ -79,8 +72,8 @@ importers:
specifier: ^8.20.0 specifier: ^8.20.0
version: 8.20.0(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3) version: 8.20.0(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3)
vite: vite:
specifier: ^5.4.14 specifier: ^5.4.11
version: 5.4.19 version: 5.4.11
vitest: vitest:
specifier: ^2.1.8 specifier: ^2.1.8
version: 2.1.8 version: 2.1.8
@ -1056,11 +1049,6 @@ packages:
lru-cache@10.4.3: lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} 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: magic-string@0.30.17:
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
@ -1461,9 +1449,6 @@ packages:
svelte: svelte:
optional: true optional: true
svelte-simple-icons@1.0.3:
resolution: {integrity: sha512-BmQPPrV9fHMH+BJSf4xBKNP0oW2XCtWizZnfAnlOBn54UWRLWmk8uTt0JRAF5NfS+74DD09oHADAroneC94eFg==}
svelte@5.19.0: svelte@5.19.0:
resolution: {integrity: sha512-qvd2GvvYnJxS/MteQKFSMyq8cQrAAut28QZ39ySv9k3ggmhw4Au4Rfcsqva74i0xMys//OhbhVCNfXPrDzL/Bg==} resolution: {integrity: sha512-qvd2GvvYnJxS/MteQKFSMyq8cQrAAut28QZ39ySv9k3ggmhw4Au4Rfcsqva74i0xMys//OhbhVCNfXPrDzL/Bg==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -1554,8 +1539,8 @@ packages:
engines: {node: ^18.0.0 || >=20.0.0} engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true hasBin: true
vite@5.4.19: vite@5.4.11:
resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==}
engines: {node: ^18.0.0 || >=20.0.0} engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -1893,13 +1878,13 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.30.1': '@rollup/rollup-win32-x64-msvc@4.30.1':
optional: true 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: 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: 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 '@types/cookie': 0.6.0
cookie: 0.6.0 cookie: 0.6.0
devalue: 5.1.1 devalue: 5.1.1
@ -1912,27 +1897,27 @@ snapshots:
set-cookie-parser: 2.7.1 set-cookie-parser: 2.7.1
sirv: 3.0.0 sirv: 3.0.0
svelte: 5.19.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: 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 debug: 4.4.0
svelte: 5.19.0 svelte: 5.19.0
vite: 5.4.19 vite: 5.4.11
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - 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: 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 debug: 4.4.0
deepmerge: 4.3.1 deepmerge: 4.3.1
kleur: 4.1.5 kleur: 4.1.5
magic-string: 0.30.17 magic-string: 0.30.17
svelte: 5.19.0 svelte: 5.19.0
vite: 5.4.19 vite: 5.4.11
vitefu: 1.0.5(vite@5.4.19) vitefu: 1.0.5(vite@5.4.11)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -2040,13 +2025,13 @@ snapshots:
chai: 5.1.2 chai: 5.1.2
tinyrainbow: 1.2.0 tinyrainbow: 1.2.0
'@vitest/mocker@2.1.8(vite@5.4.19)': '@vitest/mocker@2.1.8(vite@5.4.11)':
dependencies: dependencies:
'@vitest/spy': 2.1.8 '@vitest/spy': 2.1.8
estree-walker: 3.0.3 estree-walker: 3.0.3
magic-string: 0.30.17 magic-string: 0.30.17
optionalDependencies: optionalDependencies:
vite: 5.4.19 vite: 5.4.11
'@vitest/pretty-format@2.1.8': '@vitest/pretty-format@2.1.8':
dependencies: dependencies:
@ -2556,10 +2541,6 @@ snapshots:
lru-cache@10.4.3: {} lru-cache@10.4.3: {}
lucide-svelte@0.544.0(svelte@5.19.0):
dependencies:
svelte: 5.19.0
magic-string@0.30.17: magic-string@0.30.17:
dependencies: dependencies:
'@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/sourcemap-codec': 1.5.0
@ -2880,8 +2861,6 @@ snapshots:
optionalDependencies: optionalDependencies:
svelte: 5.19.0 svelte: 5.19.0
svelte-simple-icons@1.0.3: {}
svelte@5.19.0: svelte@5.19.0:
dependencies: dependencies:
'@ampproject/remapping': 2.3.0 '@ampproject/remapping': 2.3.0
@ -2999,7 +2978,7 @@ snapshots:
debug: 4.4.0 debug: 4.4.0
es-module-lexer: 1.6.0 es-module-lexer: 1.6.0
pathe: 1.1.2 pathe: 1.1.2
vite: 5.4.19 vite: 5.4.11
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- less - less
@ -3011,7 +2990,7 @@ snapshots:
- supports-color - supports-color
- terser - terser
vite@5.4.19: vite@5.4.11:
dependencies: dependencies:
esbuild: 0.21.5 esbuild: 0.21.5
postcss: 8.5.1 postcss: 8.5.1
@ -3019,14 +2998,14 @@ snapshots:
optionalDependencies: optionalDependencies:
fsevents: 2.3.3 fsevents: 2.3.3
vitefu@1.0.5(vite@5.4.19): vitefu@1.0.5(vite@5.4.11):
optionalDependencies: optionalDependencies:
vite: 5.4.19 vite: 5.4.11
vitest@2.1.8: vitest@2.1.8:
dependencies: dependencies:
'@vitest/expect': 2.1.8 '@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/pretty-format': 2.1.8
'@vitest/runner': 2.1.8 '@vitest/runner': 2.1.8
'@vitest/snapshot': 2.1.8 '@vitest/snapshot': 2.1.8
@ -3042,7 +3021,7 @@ snapshots:
tinyexec: 0.3.2 tinyexec: 0.3.2
tinypool: 1.0.2 tinypool: 1.0.2
tinyrainbow: 1.2.0 tinyrainbow: 1.2.0
vite: 5.4.19 vite: 5.4.11
vite-node: 2.1.8 vite-node: 2.1.8
why-is-node-running: 2.3.0 why-is-node-running: 2.3.0
transitivePeerDependencies: transitivePeerDependencies:

View file

@ -1,97 +1,79 @@
<script> <div>
import Project from './project.svelte'; <span class="text-2xl">Portfolio under construction...</span>
import ThemeToggle from './theme.svelte'; <br />
import TiltCard from './tiltcard.svelte';
// Assuming icons for Github, Gitlab, Codeberg (Code), Forgejo (GitBranch) If you felt disappointed, let it be a practice to control your expectations... But I promise to
import { Github, Gitlab, Code, GitBranch } from 'lucide-svelte'; tidy this place up soon!!! :D
<br />
const repository = { Anyways, here are some links to all my <span class="text-accent_text"> social handles </span>:
label: 'Forge', <br />
url: 'https://git.light7734.com/light7734/light', <br />
iconComponent: GitBranch
};
const mirrors = [ Mail:
{ label: 'Github', url: 'https://github.com/light7734/light', iconComponent: Github }, <a href="mailto:light7734@tuta.io" class="text-blue"> light7734@tuta.io </a>
{ label: 'Gitlab', url: 'https://gitlab.com/light7734/light', iconComponent: Gitlab }, <br />
{ label: 'Codeberg', url: 'https://codeberg.org/light7734/light', iconComponent: Code }
];
const gallery = [ Youtube:
'https://placekittens.com/720/480', <a href="https://www.youtube.com/@light.7734" class="text-blue"> @light.7734 </a>
'https://placekittens.com/720/481', <br />
'https://placekittens.com/720/482',
'https://placekittens.com/720/483',
'https://placekittens.com/720/484',
'https://placekittens.com/720/484'
];
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']; Itcho.io:
</script> <a href="https://light7734.itch.io/" class="text-blue"> light7734 </a>
<br />
<div Discord: @light7734
class="flex min-h-screen bg-gruvboxLight-bg text-gruvboxLight-fg transition-colors duration-300 dark:bg-gruvboxDark-bg dark:text-gruvboxDark-fg" <br />
>
<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>
<h1>Bio</h1> Discord Community: @light7734
<br />
<br /> Telegram Dailies: soon
<br />
<Project Instagram: soon
title="LIGHT" <br />
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}
/>
<br /> Forgejo (git repos):
<Project <a href="https://git.light7734.com/light7734" class="text-blue"> git.light7734.com </a>
title="LIGHT" <br />
description_preview="Dependency free, cross-platform, cross-graphics-api, bleeding-edge game engine."
description="Detailed description here." Codeberg (mirrors):
icon="/light.svg" <a href="https://codeberg.org/light7734" class="text-blue"> @light7734 </a>
{repository} <br />
{mirrors}
{gallery} Github (mirrors):
{features} <a href="https://codeberg.org/light7734" class="text-blue"> @light7734 </a>
{languages} <br />
{graphicsApis}
{cicd} Gitlab (mirrors):
/> <a href="https://gitlab.com/Light7734" class="text-blue"> @light7734 </a>
</main> <br />
<div class="flex-1 bg-[#1d2021]"></div>
</div> </div>
<!-- Brief Bio <!-- Brief Bio
--> -->
<!--OPEN SOURCE PROJECTS --> <!--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 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 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 into topics such as rendering, mathematics, guidelines and more. It's just my way of giving back to
the community! the community!
--> -->
<!-- Gallery <!-- Gallery
<...images...>
--> -->
<!-- Technical Details <!-- Technical Details
Technology behind Dazzle: Technology behind Dazzle:
@ -124,6 +106,9 @@ Technology behind Light:
OpenGL, Vulkan, Metal, DirectX12 OpenGL, Vulkan, Metal, DirectX12
CICD: CICD:
Drone, Docker, 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. 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) Self-hosted with <3 using Forgejo (a fork of Gittea)

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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

View file

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

View file

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

View file

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 KiB

View file

@ -3,51 +3,28 @@ import typography from '@tailwindcss/typography';
import type { Config } from 'tailwindcss'; import type { Config } from 'tailwindcss';
export default { export default {
darkMode: 'class', // important for theme switching
content: ['./src/**/*.{html,js,svelte,ts}'], content: ['./src/**/*.{html,js,svelte,ts}'],
theme: { theme: {
extend: { extend: {},
colors: { colors: {
// Gruvbox Light foundation: '#282828',
gruvboxLight: { primary: '#282828',
bg: '#fbf1c7', secondary: '#000000',
fg: '#3c3836', accent: '#ff0000',
primary: '#458588',
secondary: '#b16286',
accent: '#d79921',
neutral: '#a89984',
muted: '#7c6f64',
red: '#cc241d',
green: '#98971a',
blue: '#458588',
yellow: '#d79921',
orange: '#d65d0e',
purple: '#b16286',
aqua: '#689d6a'
},
// Gruvbox Dark neutral: '#000000',
gruvboxDark: {
bg: '#282828', primary_text: '#fbf1c7',
fg: '#ebdbb2', muted_text: '#a89984',
primary: '#83a598', accent_text: '#fb4934',
secondary: '#d3869b',
accent: '#fabd2f', red: '#000000',
neutral: '#928374', green: '#000000',
muted: '#7c6f64', blue: '#83a598',
red: '#fb4934', yellow: '#000000'
green: '#b8bb26',
blue: '#83a598',
yellow: '#fabd2f',
orange: '#fe8019',
purple: '#d3869b',
aqua: '#8ec07c'
}
}
} }
}, },
plugins: [typography, containerQueries] plugins: [typography, containerQueries]
} satisfies Config; } satisfies Config;