* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
line-height: 1.6;
overflow-x: hidden;
}
/* Demo Background */
.demo-background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
.bg-gradient {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
opacity: 0.9;
}
.bg-shapes {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.shape {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
animation: float 6s ease-in-out infinite;
}
.shape-1 {
width: 200px;
height: 200px;
top: 20%;
left: 10%;
animation-delay: 0s;
}
.shape-2 {
width: 150px;
height: 150px;
top: 60%;
right: 15%;
animation-delay: 2s;
}
.shape-3 {
width: 100px;
height: 100px;
bottom: 20%;
left: 60%;
animation-delay: 4s;
}
@keyframes float {
0%, 100% {
transform: translateY(0px) rotate(0deg);
}
50% {
transform: translateY(-20px) rotate(180deg);
}
}
/* Main Content */
.main-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 2rem;
text-align: center;
color: white;
}
.main-content h1 {
font-size: 3rem;
margin-bottom: 1rem;
font-weight: 700;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
.main-content p {
font-size: 1.2rem;
margin-bottom: 2rem;
opacity: 0.9;
max-width: 600px;
}
.demo-btn {
padding: 12px 24px;
background: rgba(255, 255, 255, 0.2);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 12px;
color: white;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
backdrop-filter: blur(10px);
transition: all 0.3s ease;
}
.demo-btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
}
/* Cookie Banner */
.cookie-banner {
position: fixed;
bottom: 2rem;
left: 50%;
transform: translateX(-50%) translateY(100px);
width: 90%;
max-width: 500px;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 20px;
padding: 1.5rem;
z-index: 1000;
opacity: 0;
visibility: hidden;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.cookie-banner.show {
opacity: 1;
visibility: visible;
transform: translateX(-50%) translateY(0);
}
.cookie-content {
display: flex;
align-items: flex-start;
gap: 1rem;
position: relative;
}
.cookie-icon {
flex-shrink: 0;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.2);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
color: white;
margin-top: 0.25rem;
}
.cookie-text {
flex: 1;
color: white;
}
.cookie-text h3 {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 0.5rem;
color: white;
}
.cookie-text p {
font-size: 0.9rem;
line-height: 1.5;
opacity: 0.9;
margin-bottom: 1rem;
}
.cookie-actions {
display: flex;
gap: 0.75rem;
flex-wrap: wrap;
}
.btn {
padding: 10px 20px;
border: none;
border-radius: 12px;
font-size: 0.9rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
min-width: 80px;
}
.btn-secondary {
background: rgba(255, 255, 255, 0.1);
color: white;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.btn-secondary:hover {
background: rgba(255, 255, 255, 0.2);
transform: translateY(-1px);
}
.btn-primary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
}
.btn-shine {
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
transition: left 0.5s ease;
}
.btn-primary:hover .btn-shine {
left: 100%;
}
.cookie-close {
position: absolute;
top: 1rem;
right: 1rem;
width: 32px;
height: 32px;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 8px;
color: white;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
opacity: 0.7;
}
.cookie-close:hover {
background: rgba(255, 255, 255, 0.2);
opacity: 1;
transform: rotate(90deg);
}
.cookie-backdrop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.1);
backdrop-filter: blur(2px);
z-index: 999;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
}
.cookie-backdrop.show {
opacity: 1;
visibility: visible;
}
/* Responsive Design */
@media (max-width: 768px) {
.cookie-banner {
bottom: 1rem;
left: 1rem;
right: 1rem;
width: auto;
max-width: none;
transform: translateY(100px);
padding: 1.25rem;
}
.cookie-banner.show {
transform: translateY(0);
}
.cookie-content {
flex-direction: column;
gap: 1rem;
}
.cookie-icon {
align-self: flex-start;
}
.cookie-actions {
justify-content: stretch;
}
.btn {
flex: 1;
min-width: auto;
}
.main-content h1 {
font-size: 2rem;
}
.main-content p {
font-size: 1rem;
}
}
@media (max-width: 480px) {
.cookie-actions {
flex-direction: column;
}
.btn {
width: 100%;
}
}
/* Animation for better performance */
@media (prefers-reduced-motion: reduce) {
.cookie-banner,
.btn,
.cookie-close,
.shape {
transition: none;
animation: none;
}
}
class GlassmorphismCookieBanner {
constructor(options = {}) {
this.options = {
autoShow: true,
showDelay: 1000,
storageKey: 'cookieConsent',
onAccept: null,
onDecline: null,
onClose: null,
...options
};
this.banner = null;
this.backdrop = null;
this.isVisible = false;
this.init();
}
init() {
this.banner = document.getElementById('cookieBanner');
this.backdrop = document.getElementById('cookieBackdrop');
if (!this.banner || !this.backdrop) {
console.error('Cookie banner elements not found');
return;
}
this.setupEventListeners();
this.checkStoredConsent();
if (this.options.autoShow && !this.hasConsent()) {
setTimeout(() => this.show(), this.options.showDelay);
}
}
setupEventListeners() {
// Keyboard navigation
document.addEventListener('keydown', (e) => {
if (this.isVisible && e.key === 'Escape') {
this.hide();
}
});
// Backdrop click
this.backdrop.addEventListener('click', () => {
this.hide();
});
// Focus trap
this.banner.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
this.handleTabNavigation(e);
}
});
}
handleTabNavigation(e) {
const focusableElements = this.banner.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const firstElement = focusableElements[0];
const lastElement = focusableElements[focusableElements.length - 1];
if (e.shiftKey) {
if (document.activeElement === firstElement) {
e.preventDefault();
lastElement.focus();
}
} else {
if (document.activeElement === lastElement) {
e.preventDefault();
firstElement.focus();
}
}
}
show() {
if (this.isVisible) return;
this.isVisible = true;
this.backdrop.classList.add('show');
// Small delay for backdrop animation
setTimeout(() => {
this.banner.classList.add('show');
this.focusFirstElement();
}, 100);
// Add body scroll lock
document.body.style.overflow = 'hidden';
}
hide() {
if (!this.isVisible) return;
this.isVisible = false;
this.banner.classList.remove('show');
setTimeout(() => {
this.backdrop.classList.remove('show');
}, 200);
// Remove body scroll lock
document.body.style.overflow = '';
if (this.options.onClose) {
this.options.onClose();
}
}
accept() {
this.setConsent(true);
this.hide();
if (this.options.onAccept) {
this.options.onAccept();
}
this.showNotification('Cookies accepted! Thank you.', 'success');
}
decline() {
this.setConsent(false);
this.hide();
if (this.options.onDecline) {
this.options.onDecline();
}
this.showNotification('Cookie preferences saved.', 'info');
}
setConsent(accepted) {
const consent = {
accepted,
timestamp: Date.now(),
version: '1.0'
};
localStorage.setItem(this.options.storageKey, JSON.stringify(consent));
}
hasConsent() {
const stored = localStorage.getItem(this.options.storageKey);
return stored !== null;
}
checkStoredConsent() {
const stored = localStorage.getItem(this.options.storageKey);
if (stored) {
try {
const consent = JSON.parse(stored);
// Check if consent is still valid (e.g., not older than 1 year)
const oneYear = 365 * 24 * 60 * 60 * 1000;
if (Date.now() - consent.timestamp > oneYear) {
localStorage.removeItem(this.options.storageKey);
return false;
}
return true;
} catch (e) {
localStorage.removeItem(this.options.storageKey);
return false;
}
}
return false;
}
focusFirstElement() {
const firstButton = this.banner.querySelector('button');
if (firstButton) {
firstButton.focus();
}
}
showNotification(message, type = 'info') {
const notification = document.createElement('div');
notification.className = `notification notification-${type}`;
notification.innerHTML = `
<div class="notification-content">
<span>${message}</span>
<button class="notification-close" onclick="this.parentElement.parentElement.remove()">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none">
<path d="M10.5 3.5L3.5 10.5M3.5 3.5l7 7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</button>
</div>
`;
// Add notification styles
const style = document.createElement('style');
style.textContent = `
.notification {
position: fixed;
top: 2rem;
right: 2rem;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 12px;
padding: 1rem;
color: white;
z-index: 10000;
animation: slideInRight 0.3s ease;
max-width: 300px;
}
.notification-content {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
}
.notification-close {
background: none;
border: none;
color: white;
cursor: pointer;
padding: 4px;
border-radius: 4px;
opacity: 0.7;
transition: opacity 0.2s ease;
}
.notification-close:hover {
opacity: 1;
}
.notification-success {
border-color: rgba(34, 197, 94, 0.3);
background: rgba(34, 197, 94, 0.1);
}
.notification-info {
border-color: rgba(59, 130, 246, 0.3);
background: rgba(59, 130, 246, 0.1);
}
@keyframes slideInRight {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@media (max-width: 768px) {
.notification {
top: 1rem;
right: 1rem;
left: 1rem;
max-width: none;
}
}
`;
if (!document.querySelector('#notification-styles')) {
style.id = 'notification-styles';
document.head.appendChild(style);
}
document.body.appendChild(notification);
// Auto remove after 5 seconds
setTimeout(() => {
if (notification.parentElement) {
notification.style.animation = 'slideInRight 0.3s ease reverse';
setTimeout(() => notification.remove(), 300);
}
}, 5000);
}
// Public methods
reset() {
localStorage.removeItem(this.options.storageKey);
this.show();
}
getConsent() {
const stored = localStorage.getItem(this.options.storageKey);
if (stored) {
try {
return JSON.parse(stored);
} catch (e) {
return null;
}
}
return null;
}
}
// Global functions for HTML onclick handlers
function showCookieBanner() {
if (window.cookieBanner) {
window.cookieBanner.show();
}
}
function acceptCookies() {
if (window.cookieBanner) {
window.cookieBanner.accept();
}
}
function declineCookies() {
if (window.cookieBanner) {
window.cookieBanner.decline();
}
}
function hideCookieBanner() {
if (window.cookieBanner) {
window.cookieBanner.hide();
}
}
// Initialize when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
window.cookieBanner = new GlassmorphismCookieBanner({
autoShow: false, // Set to true for auto-show
onAccept: () => {
console.log('Cookies accepted!');
// Add your analytics or tracking code here
},
onDecline: () => {
console.log('Cookies declined!');
// Handle declined cookies
}
});
});