@@ -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 >
0 commit comments