An interactive case study showing how I think, design, and debug using HTML, CSS, and JavaScript.
Most portfolios only show the final result. I wanted to show the decision-making process behind building a real website.
How should this project be approached?
This navigation menu breaks on mobile due to a missing CSS class. Try to debug it.
Common frontend issues recreated and fixed using DOM inspection, CSS corrections, and JavaScript state updates.
Small UI components built with reusable CSS and JavaScript state. Toggle interactions to see how behavior changes.
A clean card component with header and content.
Cards can display structured information.
This project is built with accessibility and performance in mind, even without frameworks.
Live projects built with vanilla HTML, CSS, and JavaScript. Click to see them in action.
Complete portfolio showcase with case studies, skills, and projects.
Interactive restaurant site with menu gallery, online ordering, and reservation system.
Full-featured ecommerce platform with product catalog, shopping cart, and checkout flow.
Explore more case studies, projects, and detailed breakdowns of my work and process.
This site is built for speed and accessibility. Here are the current metrics:
Reusable patterns and real-world solutions you can adopt immediately.
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, { threshold: 0.2 });
document.querySelectorAll('.lazy').forEach(el => {
observer.observe(el);
});
function debounce(fn, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn(...args), delay);
};
}
const handleResize = debounce(() => {
console.log('Window resized');
}, 300);
function setWithExpiry(key, value, ttl) {
const item = {
value: value,
expiry: Date.now() + ttl
};
localStorage.setItem(key, JSON.stringify(item));
}
function getWithExpiry(key) {
const item = JSON.parse(localStorage.getItem(key));
if (Date.now() > item.expiry) {
localStorage.removeItem(key);
return null;
}
return item.value;
}
Interactive demonstrations of modern layout techniques.
Smooth, performant animations using CSS transforms and transitions.
Real-world form patterns with client-side validation.
Patterns for better perceived performance during data loading.
WCAG 2.1 AA compliance patterns demonstrated throughout this site.
Unit tests and E2E examples from my projects.
test('debounce delays function execution', (done) => {
let callCount = 0;
const fn = debounce(() => callCount++, 100);
fn();
fn();
fn();
setTimeout(() => {
expect(callCount).toBe(1);
done();
}, 150);
});
describe('Form Validation', () => {
it('shows error on invalid email', () => {
cy.get('#emailInput').type('invalid');
cy.get('button[type="submit"]').click();
cy.get('#emailError').should('be.visible');
});
});
The technologies and methodologies I specialize in.