Skip to content

Commit c5aa6dd

Browse files
committed
refactor: audit, debloat, and polish codebase
- Remove @fontsource/geist-sans, eslint + all plugins, @astrojs/sitemap, globals - Add static public/sitemap.xml as zero-dep replacement - Swap Google Fonts to non-blocking media=print/onload load strategy - Slim tsconfig.json, astro.config.mjs (drop onwarn hack, empty integrations) - Drop COLOR constants from animations.ts, inline hex values at callsites - Remove EASE.EXPO_IN unused key - Move all GSAP initial states from Tailwind classes to gsap.set() calls - Convert fromTo -> to throughout (Hero, About, Footer, Projects) - Unify isMobile if/else branches in About, Footer (drop mobile fallbacks) - Consolidate Projects.astro mobile/desktop branching into single if/else - Flatten InteractiveCursor STATES object into direct if/else in updateCursor - Remove dead null guard after ! assertions in Header and InteractiveCursor - Remove redundant cursor alias variables in InteractiveCursor - Drop unused group, class? prop, and JSX section comments - Add will-change: transform to cursor, hero-line, hero-title for GPU hints - Add og:site_name, twitter:title, twitter:description, robots, theme-color - Add link rel=sitemap, fix schema jobTitle to Full-Stack Web Developer - Fix EASE.EXPO_IN reference in Header menu closed state - Remove stale eslint-disable comment from Layout.astro
1 parent 5143af3 commit c5aa6dd

17 files changed

Lines changed: 215 additions & 894 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ A high-performance, cinematic personal portfolio website featuring advanced moti
44

55
## Overview
66

7-
- **Stack**: [Astro](https://astro.build), [Tailwind CSS v4](https://tailwindcss.com), [GSAP](https://greensock.com/gsap), [Lenis](https://lenis.studiofreight.com/).
7+
- **Stack**: [Astro](https://astro.build), [Tailwind CSS v4](https://tailwindcss.com), [GSAP](https://greensock.com/gsap).
88
- **Design**: Cinematic dark mode (`#050505`), animated grain, and fluid typography.
99
- **Performance**: Zero-runtime JS overhead where possible, smooth scrolling, and optimized assets.
1010

astro.config.mjs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
1-
import sitemap from '@astrojs/sitemap';
21
import tailwindcss from '@tailwindcss/vite';
32
import { defineConfig } from 'astro/config';
43

5-
// Astro-internal module paths whose unused-import warnings can be safely ignored.
6-
const SUPPRESSED_IDS = [
7-
'@astrojs/internal-helpers/remote',
8-
'node_modules/astro/dist/assets/utils/remotePattern.js',
9-
'node_modules/astro/dist/assets/services/service.js',
10-
];
11-
124
// https://astro.build/config
135
export default defineConfig({
146
site: 'https://dacrab.github.io',
@@ -24,19 +16,9 @@ export default defineConfig({
2416
vite: {
2517
build: {
2618
sourcemap: false,
27-
rollupOptions: {
28-
onwarn(warning, defaultHandler) {
29-
if (
30-
(warning.code === 'UNUSED_EXTERNAL_IMPORT' || warning.code === 'UNUSED_IMPORT') &&
31-
typeof warning.id === 'string' &&
32-
SUPPRESSED_IDS.some((id) => warning.id.includes(id))
33-
) return;
34-
defaultHandler(warning);
35-
},
36-
},
3719
},
3820
plugins: [tailwindcss()],
3921
css: { devSourcemap: false },
4022
},
41-
integrations: [sitemap()],
23+
integrations: [],
4224
});

bun.lock

Lines changed: 74 additions & 566 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

eslint.config.mjs

Lines changed: 0 additions & 60 deletions
This file was deleted.

package.json

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,17 @@
66
"dev": "astro dev",
77
"build": "astro build",
88
"preview": "astro preview",
9-
"lint": "eslint .",
10-
"fix": "eslint . --fix",
11-
"ci": "bun run lint && bun x astro check && bun run build"
9+
"ci": "bun x astro check && bun run build"
1210
},
1311
"dependencies": {
14-
"@astrojs/sitemap": "^3.7.0",
15-
"@fontsource/geist-sans": "^5.2.5",
1612
"@tailwindcss/vite": "^4.2.1",
17-
"astro": "5.18.0",
13+
"astro": "6.0.2",
1814
"gsap": "^3.14.2",
1915
"tailwindcss": "^4.2.1"
2016
},
2117
"devDependencies": {
22-
"@astrojs/check": "^0.9.6",
18+
"@astrojs/check": "0.9.7",
2319
"@types/node": "^25.3.5",
24-
"eslint": "^10.0.3",
25-
"eslint-plugin-astro": "^1.6.0",
26-
"eslint-plugin-jsx-a11y": "^6.10.2",
27-
"eslint-plugin-simple-import-sort": "^12.1.1",
28-
"globals": "^17.4.0",
29-
"typescript": "^5.9.3",
30-
"typescript-eslint": "^8.56.1"
20+
"typescript": "^5.9.3"
3121
}
3222
}

public/sitemap.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3+
<url>
4+
<loc>https://dacrab.github.io/</loc>
5+
<changefreq>monthly</changefreq>
6+
<priority>1.0</priority>
7+
</url>
8+
</urlset>

src/components/About.astro

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -49,34 +49,19 @@
4949

5050
<script>
5151
import gsap from 'gsap';
52+
import { DURATION, EASE } from '../utils/animations';
5253

53-
import { DURATION, EASE, isMobile } from '../utils/animations';
54+
gsap.set('.about-heading', { opacity: 0, scale: 0.95 });
55+
gsap.set('.about-text', { opacity: 0, y: 30 });
56+
gsap.set('.about-stack li', { opacity: 0, x: 20 });
57+
gsap.set('.about-contact', { opacity: 0, y: 20 });
5458

55-
if (isMobile) {
56-
gsap.fromTo('#about',
57-
{ opacity: 0 },
58-
{ opacity: 1, duration: 0.5, ease: EASE.DEFAULT,
59-
scrollTrigger: { trigger: '#about', start: 'top 85%', once: true } },
60-
);
61-
} else {
62-
gsap.timeline({
63-
defaults: { ease: EASE.DEFAULT },
64-
scrollTrigger: { trigger: '#about', start: 'top 65%', once: true },
65-
})
66-
.fromTo('.about-heading',
67-
{ opacity: 0, scale: 0.95 },
68-
{ opacity: 1, scale: 1, duration: DURATION.SLOWER })
69-
.fromTo('.about-text',
70-
{ opacity: 0, y: 30 },
71-
{ opacity: 1, y: 0, duration: DURATION.SLOWER },
72-
'-=0.4')
73-
.fromTo('.about-stack li',
74-
{ opacity: 0, x: 20 },
75-
{ opacity: 1, x: 0, duration: DURATION.MEDIUM, stagger: 0.1 },
76-
'-=0.4')
77-
.fromTo('.about-contact',
78-
{ opacity: 0, y: 20 },
79-
{ opacity: 1, y: 0, duration: DURATION.SLOW },
80-
'-=0.2');
81-
}
59+
gsap.timeline({
60+
defaults: { ease: EASE.DEFAULT },
61+
scrollTrigger: { trigger: '#about', start: 'top 70%', once: true },
62+
})
63+
.to('.about-heading', { opacity: 1, scale: 1, duration: DURATION.SLOWER })
64+
.to('.about-text', { opacity: 1, y: 0, duration: DURATION.SLOWER }, '-=0.4')
65+
.to('.about-stack li', { opacity: 1, x: 0, duration: DURATION.MEDIUM, stagger: 0.1 }, '-=0.4')
66+
.to('.about-contact', { opacity: 1, y: 0, duration: DURATION.SLOW }, '-=0.2');
8267
</script>

src/components/BrowserMockup.astro

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@ interface Props {
66
src: ImageMetadata;
77
alt: string;
88
url?: string;
9-
class?: string;
109
}
1110
12-
const { src, alt, url, class: className } = Astro.props;
11+
const { src, alt, url } = Astro.props;
1312
---
1413

15-
<div class:list={['browser-mockup group relative', className]}>
14+
<div class="browser-mockup group relative">
1615
<!-- Browser Chrome -->
1716
<div class="flex items-center gap-2 rounded-t-lg bg-zinc-800 px-4 py-3">
1817
<div class="flex gap-1.5">

src/components/Footer.astro

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const socials = [
1212
<div
1313
class="mx-auto flex w-full max-w-[90vw] flex-col items-center justify-between gap-8 md:flex-row md:items-end"
1414
>
15-
<p class="footer-name crab-trigger pointer-events-auto text-center text-[12vw] leading-none font-bold tracking-tighter text-zinc-900 transition-colors duration-500 select-none hover:text-zinc-800 md:text-left">
15+
<p class="footer-name crab-trigger pointer-events-auto text-center text-[12vw] leading-none font-bold tracking-tighter text-zinc-900 transition-colors select-none hover:text-zinc-800 md:text-left">
1616
KAVOURAS
1717
</p>
1818

@@ -36,21 +36,15 @@ const socials = [
3636

3737
<script>
3838
import gsap from 'gsap';
39+
import { DURATION, EASE } from '../utils/animations';
3940

40-
import { DURATION, EASE, isMobile } from '../utils/animations';
41+
gsap.set('.footer-name', { opacity: 0, y: 40 });
42+
gsap.set('.footer-links', { opacity: 0, y: 20 });
4143

42-
if (isMobile) {
43-
gsap.fromTo('.footer-section',
44-
{ opacity: 0 },
45-
{ opacity: 1, duration: 0.5, ease: EASE.DEFAULT,
46-
scrollTrigger: { trigger: '.footer-section', start: 'top 90%', once: true } },
47-
);
48-
} else {
49-
gsap.timeline({
50-
defaults: { ease: EASE.DEFAULT },
51-
scrollTrigger: { trigger: '.footer-section', start: 'top 90%', once: true },
52-
})
53-
.fromTo('.footer-name', { opacity: 0, y: 40 }, { opacity: 1, y: 0, duration: DURATION.SLOWER })
54-
.fromTo('.footer-links', { opacity: 0, y: 20 }, { opacity: 1, y: 0, duration: DURATION.SLOW }, '-=0.4');
55-
}
44+
gsap.timeline({
45+
defaults: { ease: EASE.DEFAULT },
46+
scrollTrigger: { trigger: '.footer-section', start: 'top 90%', once: true },
47+
})
48+
.to('.footer-name', { opacity: 1, y: 0, duration: DURATION.SLOWER })
49+
.to('.footer-links', { opacity: 1, y: 0, duration: DURATION.SLOW }, '-=0.4');
5650
</script>

src/components/Header.astro

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ const links = [
1111
<a
1212
href="#hero-section"
1313
aria-label="Back to top"
14-
class="header-reveal magnetic inline-block -translate-y-full text-sm font-bold tracking-widest uppercase opacity-0"
14+
class="header-reveal magnetic inline-block text-sm font-bold tracking-widest uppercase"
1515
>
1616
Vaggelis <span class="crab-trigger inline-block">Kavouras</span>
1717
</a>
1818

1919
<button
2020
id="menu-toggle"
21-
class="header-reveal group relative z-50 flex h-8 w-12 -translate-y-full cursor-pointer flex-col items-end justify-center gap-1.5 opacity-0 mix-blend-difference"
21+
class="header-reveal relative z-50 flex h-8 w-12 cursor-pointer flex-col items-end justify-center gap-1.5 mix-blend-difference"
2222
aria-label="Toggle Menu"
2323
aria-expanded="false"
2424
aria-controls="menu-overlay"
@@ -37,17 +37,17 @@ const links = [
3737
<ul class="flex flex-col items-center gap-8">
3838
{
3939
links.map((link) => (
40-
<li class="menu-item translate-y-8 opacity-0">
40+
<li class="menu-item">
4141
<a
4242
href={link.href}
43-
class="magnetic group relative inline-block text-4xl font-bold tracking-tighter uppercase md:text-6xl"
43+
class="magnetic inline-block text-4xl font-bold tracking-tighter uppercase md:text-6xl"
4444
>
4545
{link.label}
4646
</a>
4747
</li>
4848
))
4949
}
50-
<li class="menu-item translate-y-8 opacity-0">
50+
<li class="menu-item">
5151
<div class="mt-8 flex flex-col items-center gap-4">
5252
<span class="text-sm font-medium tracking-widest text-zinc-500 uppercase">Resume</span>
5353
<div class="flex gap-4">
@@ -77,16 +77,17 @@ const links = [
7777

7878
<script>
7979
import gsap from 'gsap';
80+
import { DURATION, EASE } from '../utils/animations';
8081

81-
import { DURATION, EASE } from '../utils/animations';
82-
83-
const menuToggle = document.getElementById('menu-toggle');
84-
const menuOverlay = document.getElementById('menu-overlay');
82+
const menuToggle = document.getElementById('menu-toggle')!;
83+
const menuOverlay = document.getElementById('menu-overlay')!;
8584
const menuItems = document.querySelectorAll('.menu-item');
86-
const topBar = document.getElementById('bar-top');
87-
const bottomBar = document.getElementById('bar-bottom');
85+
const topBar = document.getElementById('bar-top')!;
86+
const bottomBar = document.getElementById('bar-bottom')!;
8887
let isMenuOpen = false;
8988

89+
gsap.set('.header-reveal', { y: -40, opacity: 0 });
90+
gsap.set('.menu-item', { y: 20, opacity: 0 });
9091
gsap.to('.header-reveal', {
9192
y: 0,
9293
opacity: 1,
@@ -96,10 +97,6 @@ import { DURATION, EASE } from '../utils/animations';
9697
delay: 0.3,
9798
});
9899

99-
if (!menuToggle || !menuOverlay || !topBar || !bottomBar) {
100-
throw new Error('Header: required menu elements not found');
101-
}
102-
103100
menuToggle.addEventListener('mouseenter', () => {
104101
if (isMenuOpen) return;
105102
gsap.to(topBar, { width: '75%', duration: DURATION.DEFAULT, ease: EASE.DEFAULT, overwrite: 'auto' });
@@ -115,15 +112,15 @@ import { DURATION, EASE } from '../utils/animations';
115112
const MENU = {
116113
open: {
117114
body: 'hidden',
118-
overlay: { x: '0%', duration: DURATION.SLOWER, ease: EASE.EXPO_IN_OUT },
115+
overlay: { x: 0, duration: DURATION.SLOWER, ease: EASE.EXPO_IN_OUT },
119116
items: { y: 0, opacity: 1, duration: 1, stagger: 0.1, delay: DURATION.MEDIUM, ease: EASE.EXPO },
120117
topBar: { rotate: 45, y: 4, width: '100%', duration: DURATION.MEDIUM, ease: EASE.EXPO },
121118
bottomBar: { rotate: -45, y: -4, width: '100%', duration: DURATION.MEDIUM, ease: EASE.EXPO },
122119
},
123120
closed: {
124121
body: '',
125122
overlay: { x: '100%', duration: DURATION.SLOWER, ease: EASE.EXPO_IN_OUT },
126-
items: { y: 20, opacity: 0, duration: DURATION.MEDIUM, ease: EASE.EXPO_IN },
123+
items: { y: 20, opacity: 0, duration: DURATION.MEDIUM, ease: EASE.EXPO },
127124
topBar: { rotate: 0, y: 0, width: '100%', duration: DURATION.MEDIUM, ease: EASE.EXPO },
128125
bottomBar: { rotate: 0, y: 0, width: '75%', duration: DURATION.MEDIUM, ease: EASE.EXPO },
129126
},

0 commit comments

Comments
 (0)