Backup database and code changes - 2025-06-08 18:36:00
1
assets/css/main.min.css
vendored
Normal file
BIN
assets/images/certificate-icon.webp
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
assets/images/chart-icon.webp
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
assets/images/client-gambling-commission.webp
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
assets/images/client-gdp.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
assets/images/client-homesupply.webp
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
assets/images/client-incite.webp
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
assets/images/client-pragma.webp
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
assets/images/client-replay.webp
Normal file
|
After Width: | Height: | Size: 964 B |
BIN
assets/images/favicon-original.webp
Normal file
|
After Width: | Height: | Size: 434 B |
BIN
assets/images/rocket-icon.webp
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
assets/images/ukds-main-logo.webp
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
@@ -736,4 +736,75 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
console.log(`Blog pagination initialized: ${totalPages} pages, ${allArticles.length} articles`);
|
||||
}
|
||||
|
||||
// Viewport-based Image Loading Optimization
|
||||
function initializeViewportImageLoading() {
|
||||
// Intersection Observer for lazy loading optimization
|
||||
const imageObserver = new IntersectionObserver((entries, observer) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
const img = entry.target;
|
||||
|
||||
// Load high-quality version when in viewport
|
||||
if (img.dataset.src) {
|
||||
img.src = img.dataset.src;
|
||||
img.removeAttribute('data-src');
|
||||
}
|
||||
|
||||
// Load WebP for supported browsers
|
||||
if (img.dataset.webp && supportsWebP()) {
|
||||
img.src = img.dataset.webp;
|
||||
}
|
||||
|
||||
observer.unobserve(img);
|
||||
}
|
||||
});
|
||||
}, {
|
||||
rootMargin: '50px 0px',
|
||||
threshold: 0.01
|
||||
});
|
||||
|
||||
// Observe all images with data-src
|
||||
document.querySelectorAll('img[data-src]').forEach(img => {
|
||||
imageObserver.observe(img);
|
||||
});
|
||||
|
||||
// WebP support detection
|
||||
function supportsWebP() {
|
||||
return new Promise(resolve => {
|
||||
const webP = new Image();
|
||||
webP.onload = webP.onerror = () => resolve(webP.height === 2);
|
||||
webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Touch Target Optimization for Mobile
|
||||
function optimizeTouchTargets() {
|
||||
const minTouchSize = 44; // 44px minimum touch target
|
||||
|
||||
// Check and optimize button sizes
|
||||
document.querySelectorAll('button, .btn, a[role="button"]').forEach(element => {
|
||||
const rect = element.getBoundingClientRect();
|
||||
if (rect.width < minTouchSize || rect.height < minTouchSize) {
|
||||
element.style.minWidth = minTouchSize + 'px';
|
||||
element.style.minHeight = minTouchSize + 'px';
|
||||
element.style.display = 'inline-flex';
|
||||
element.style.alignItems = 'center';
|
||||
element.style.justifyContent = 'center';
|
||||
}
|
||||
});
|
||||
|
||||
// Add touch-friendly spacing
|
||||
document.querySelectorAll('.nav-menu a, .social-links a').forEach(element => {
|
||||
element.style.padding = '12px 16px';
|
||||
element.style.margin = '4px';
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize optimizations
|
||||
initializeViewportImageLoading();
|
||||
if ('ontouchstart' in window) {
|
||||
optimizeTouchTargets();
|
||||
}
|
||||
});
|
||||