Skip to content

Commit e57036f

Browse files
committed
feat: add easter egg glitch effect to ui
Signed-off-by: r3drun3 <simone.ragonesi@protonmail.com>
1 parent 451a0f8 commit e57036f

File tree

4 files changed

+144
-6
lines changed

4 files changed

+144
-6
lines changed

src/components/Header.astro

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,39 @@
55
<span class="text-2xl font-bold text-accent">DarkVectr</span>
66
</h1>
77
<ul class="hidden md:flex space-x-6">
8-
<li>
8+
<li class="opacity-0">
99
<a
1010
href="#about"
1111
class="text-foreground border-b-2 border-transparent hover:text-accent hover:border-accent pb-1 transition-all duration-200 ease-in-out"
1212
>
1313
About
1414
</a>
1515
</li>
16-
<li>
16+
<li class="opacity-0">
1717
<a
1818
href="#services"
1919
class="text-foreground border-b-2 border-transparent hover:text-accent hover:border-accent pb-1 transition-all duration-200 ease-in-out"
2020
>
2121
Services
2222
</a>
2323
</li>
24-
<li>
24+
<li class="opacity-0">
2525
<a
2626
href="#approach"
2727
class="text-foreground border-b-2 border-transparent hover:text-accent hover:border-accent pb-1 transition-all duration-200 ease-in-out"
2828
>
2929
Approach
3030
</a>
3131
</li>
32-
<li>
32+
<li class="opacity-0">
3333
<a
3434
href="#opensource"
3535
class="text-foreground border-b-2 border-transparent hover:text-accent hover:border-accent pb-1 transition-all duration-200 ease-in-out"
3636
>
3737
Open Source
3838
</a>
3939
</li>
40-
<li>
40+
<li class="opacity-0">
4141
<a
4242
href="#contact"
4343
class="text-foreground border-b-2 border-transparent hover:text-accent hover:border-accent pb-1 transition-all duration-200 ease-in-out"

src/layouts/Base.astro

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,82 @@ import Footer from '../components/Footer.astro';
4242
50% { opacity: 0.05; transform: scale(1.2); }
4343
100% { opacity: 0.2; transform: scale(1); }
4444
}
45+
:root {
46+
--glitch-offset-x: 8px;
47+
--glitch-offset-y: -8px;
48+
--glitch-skew-before: -5deg;
49+
--glitch-skew-middle: -3deg;
50+
--glitch-skew-after: 5deg;
51+
--glitch-hue-before: 10deg;
52+
--glitch-hue-after: -10deg;
53+
--glitch-opacity-before: 0.6;
54+
--glitch-opacity-after: 0.8;
55+
--glitch-stripe-light: 0.1;
56+
--glitch-stripe-thickness: 2px;
57+
--glitch-stripe-gap: 6px;
58+
--glitch-stripe-color: 255,255,255;
59+
--glitch-page-hue: 20deg;
60+
--glitch-page-contrast: 200%;
61+
--glitch-page-brightness: 1.2;
62+
}
63+
#glitch-overlay {
64+
position: fixed;
65+
inset: 0;
66+
pointer-events: none;
67+
z-index: 50;
68+
background: repeating-linear-gradient(
69+
45deg,
70+
rgba(var(--glitch-stripe-color),var(--glitch-stripe-light,0.1)),
71+
rgba(var(--glitch-stripe-color),var(--glitch-stripe-light,0.1)) var(--glitch-stripe-thickness,2px),
72+
transparent var(--glitch-stripe-thickness,2px),
73+
transparent calc(var(--glitch-stripe-thickness,2px) + var(--glitch-stripe-gap,6px))
74+
);
75+
opacity: 0;
76+
}
77+
#glitch-overlay::before,
78+
#glitch-overlay::after {
79+
content: '';
80+
position: absolute;
81+
inset: 0;
82+
background: inherit;
83+
opacity: 0;
84+
}
85+
#glitch-overlay.animate-glitch::before {
86+
animation: glitch-before 0.6s steps(2) forwards;
87+
}
88+
#glitch-overlay.animate-glitch::after {
89+
animation: glitch-after 0.6s steps(2) forwards;
90+
}
91+
@keyframes glitch-before {
92+
0% { opacity: 0; transform: translate(0); filter: hue-rotate(var(--glitch-hue-before,10deg)); }
93+
20% { opacity: var(--glitch-opacity-before,0.6); transform: translate(var(--glitch-offset-x,-8px), var(--glitch-offset-y,-8px)) skew(var(--glitch-skew-before,-5deg)); }
94+
40% { opacity: calc(var(--glitch-opacity-before,0.6) / 2); transform: translate(calc(-1 * var(--glitch-offset-x,-8px)), calc(-1 * var(--glitch-offset-y,-8px))) skew(var(--glitch-skew-after,3deg)); }
95+
60% { opacity: var(--glitch-opacity-before,0.6); transform: translate(calc(-0.5 * var(--glitch-offset-x,-8px)), calc(0.5 * var(--glitch-offset-y,-8px))) skew(var(--glitch-skew-middle,-3deg)); }
96+
80% { opacity: calc(var(--glitch-opacity-before,0.6) / 2); transform: translate(var(--glitch-offset-x,-8px), calc(-0.5 * var(--glitch-offset-y,-8px))) skew(var(--glitch-skew-last,5deg)); }
97+
100% { opacity: 0; transform: translate(0); }
98+
}
99+
@keyframes glitch-after {
100+
0% { opacity: 0; transform: translate(0); filter: hue-rotate(var(--glitch-hue-after,-10deg)); }
101+
20% { opacity: var(--glitch-opacity-after,0.8); transform: translate(calc(var(--glitch-offset-x,8px)), calc(var(--glitch-offset-y,8px))) skew(var(--glitch-skew-after,5deg)); }
102+
40% { opacity: calc(var(--glitch-opacity-after,0.8) / 2); transform: translate(calc(-1 * var(--glitch-offset-x,8px)), calc(-1 * var(--glitch-offset-y,8px))) skew(var(--glitch-skew-before,-5deg)); }
103+
60% { opacity: var(--glitch-opacity-after,0.8); transform: translate(calc(0.5 * var(--glitch-offset-x,8px)), calc(-0.5 * var(--glitch-offset-y,8px))) skew(var(--glitch-skew-middle,3deg)); }
104+
80% { opacity: calc(var(--glitch-opacity-after,0.8) / 2); transform: translate(calc(-0.5 * var(--glitch-offset-x,8px)), calc(0.5 * var(--glitch-offset-y,8px))) skew(var(--glitch-skew-last,-3deg)); }
105+
100% { opacity: 0; transform: translate(0); }
106+
}
107+
108+
html.glitch-shake {
109+
filter: hue-rotate(var(--glitch-page-hue)) contrast(var(--glitch-page-contrast)) brightness(var(--glitch-page-brightness));
110+
}
111+
html.glitch-shake.animate-shake {
112+
animation: glitch-shake 0.5s steps(2) forwards;
113+
}
114+
@keyframes glitch-shake {
115+
0% { transform: translate(0); }
116+
25% { transform: translate(-6px, 6px) skewX(-3deg); }
117+
50% { transform: translate(6px, -6px) skewY(3deg); }
118+
75% { transform: translate(-6px, -6px) skew(-3deg); }
119+
100% { transform: translate(0); }
120+
}
45121
</style>
46122
</head>
47123
<body class="bg-background text-foreground font-sans">
@@ -50,6 +126,7 @@ import Footer from '../components/Footer.astro';
50126
<slot />
51127
</main>
52128
<Footer />
129+
<div id="glitch-overlay"></div>
53130
<script>
54131
const htmlEl = document.documentElement;
55132
const toggle = document.getElementById("theme-toggle");
@@ -137,6 +214,57 @@ import Footer from '../components/Footer.astro';
137214
});
138215
});
139216
}
217+
218+
219+
const navItems = document.querySelectorAll('header nav ul li');
220+
navItems.forEach((el, i) => {
221+
const animation = i % 2 === 0 ? 'slideInLeft' : 'slideInRight';
222+
setTimeout(() => {
223+
el.classList.remove('opacity-0');
224+
el.classList.add(`animate-${animation}`);
225+
}, 150 * i + 200);
226+
});
227+
228+
229+
const glitchEl = document.getElementById('glitch-overlay');
230+
(function glitchLoop() {
231+
const timeout = Math.random() * 6000 + 2000;
232+
setTimeout(() => {
233+
234+
const root = document.documentElement;
235+
root.style.setProperty('--glitch-offset-x', `${(Math.random()*2-1)*10}px`);
236+
root.style.setProperty('--glitch-offset-y', `${(Math.random()*2-1)*10}px`);
237+
root.style.setProperty('--glitch-skew-before', `${(Math.random()*10-5).toFixed(2)}deg`);
238+
root.style.setProperty('--glitch-skew-middle', `${(Math.random()*10-5).toFixed(2)}deg`);
239+
root.style.setProperty('--glitch-skew-after', `${(Math.random()*10-5).toFixed(2)}deg`);
240+
root.style.setProperty('--glitch-hue-before', `${(Math.random()*40-20).toFixed(2)}deg`);
241+
root.style.setProperty('--glitch-hue-after', `${(Math.random()*40-20).toFixed(2)}deg`);
242+
root.style.setProperty('--glitch-opacity-before', `${(Math.random()*0.5+0.3).toFixed(2)}`);
243+
root.style.setProperty('--glitch-opacity-after', `${(Math.random()*0.5+0.3).toFixed(2)}`);
244+
245+
root.style.setProperty('--glitch-page-hue', `${(Math.random()*360).toFixed(1)}deg`);
246+
root.style.setProperty('--glitch-page-contrast', `${(Math.random()*150+150).toFixed(0)}%`);
247+
root.style.setProperty('--glitch-page-brightness', `${(Math.random()*0.7+0.8).toFixed(2)}`);
248+
root.style.setProperty(
249+
'--glitch-stripe-color',
250+
`${Math.floor(Math.random()*256)},${Math.floor(Math.random()*256)},${Math.floor(Math.random()*256)}`
251+
);
252+
root.style.setProperty('--glitch-stripe-light', `${(Math.random()*0.4+0.1).toFixed(2)}`);
253+
root.style.setProperty('--glitch-stripe-thickness', `${Math.floor(Math.random()*6+1)}px`);
254+
root.style.setProperty('--glitch-stripe-gap', `${Math.floor(Math.random()*12+4)}px`);
255+
256+
root.classList.add('glitch-shake', 'animate-shake');
257+
document.documentElement.addEventListener('animationend', () => {
258+
document.documentElement.classList.remove('animate-shake');
259+
}, { once: true });
260+
glitchEl.classList.add('animate-glitch');
261+
glitchEl.addEventListener('animationend', () => {
262+
glitchEl.classList.remove('animate-glitch');
263+
document.documentElement.classList.remove('glitch-shake');
264+
}, { once: true });
265+
glitchLoop();
266+
}, timeout);
267+
})();
140268
});
141269
</script>
142270
</body>

src/pages/index.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import BaseLayout from '../layouts/Base.astro';
2222
<section id="about" class="mb-16 reveal opacity-0" data-animation="slideInUp">
2323
<h3 class="text-2xl font-semibold text-accent mb-4">About DarkVectr</h3>
2424
<p class="text-subtext">
25-
Darkvectr is an independent cybersecurity consultancy specializing in offensive security operations, red teaming, DevSecOps and secure architecture reviews. Founded by seasoned hackers with real-world breach experience, we provide deeply technical assessments designed to mirror modern threats.
25+
Darkvectr (spelled "Dark Vector") is an independent cybersecurity consultancy specializing in offensive security operations, red teaming, DevSecOps and secure architecture reviews. Founded by seasoned hackers with real-world breach experience, we provide deeply technical assessments designed to mirror modern threats.
2626
</p>
2727
</section>
2828

tailwind.config.cjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ module.exports = {
5151
'0%': { opacity: '0', transform: 'translateY(-20px)' },
5252
'100%': { opacity: '1', transform: 'translateY(0)' }
5353
},
54+
slideInLeft: {
55+
'0%': { opacity: '0', transform: 'translateX(-20px)' },
56+
'100%': { opacity: '1', transform: 'translateX(0)' }
57+
},
58+
slideInRight: {
59+
'0%': { opacity: '0', transform: 'translateX(20px)' },
60+
'100%': { opacity: '1', transform: 'translateX(0)' }
61+
},
5462
gradient: {
5563
'0%, 100%': { 'background-position': '0% 50%' },
5664
'50%': { 'background-position': '100% 50%' }
@@ -73,6 +81,8 @@ module.exports = {
7381
fadeIn: 'fadeIn 0.8s ease-out forwards',
7482
slideInUp: 'slideInUp 0.8s ease-out forwards',
7583
slideInDown: 'slideInDown 0.8s ease-out forwards',
84+
slideInLeft: 'slideInLeft 0.8s ease-out forwards',
85+
slideInRight: 'slideInRight 0.8s ease-out forwards',
7686
gradient: 'gradient 8s ease infinite',
7787
typewriter: 'typewriter 3s steps(30) forwards',
7888
blink: 'blink 1s step-end infinite',

0 commit comments

Comments
 (0)