diff --git a/assets/css/main.css b/assets/css/main.css
index a62dcee..fa1999b 100644
--- a/assets/css/main.css
+++ b/assets/css/main.css
@@ -2868,7 +2868,8 @@ a:focus-visible {
margin-top: 60px;
}
-.related-articles h2 {
+.related-articles h2,
+.related-articles h3 {
font-size: 2rem;
font-weight: 600;
margin-bottom: 40px;
@@ -2876,6 +2877,14 @@ a:focus-visible {
text-align: center;
}
+/* Handle both aside and section elements */
+aside.related-articles {
+ padding: 40px 0;
+ background: #f8f9fa;
+ border-top: 1px solid #e1e5e9;
+ margin-top: 40px;
+}
+
.related-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
@@ -2898,23 +2907,42 @@ a:focus-visible {
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
}
-.related-card h3 {
+.related-card h3,
+.related-card h4 {
font-size: 1.3rem;
font-weight: 600;
margin-bottom: 15px;
line-height: 1.3;
}
-.related-card h3 a {
+.related-card h3 a,
+.related-card h4 a {
color: #1a1a1a;
text-decoration: none;
transition: color 0.3s ease;
}
-.related-card h3 a:hover {
+.related-card h3 a:hover,
+.related-card h4 a:hover {
color: #179e83;
}
+.related-card .category {
+ background: #179e83;
+ color: white;
+ padding: 4px 12px;
+ border-radius: 20px;
+ font-size: 0.8rem;
+ font-weight: 500;
+ display: inline-block;
+ margin-bottom: 12px;
+}
+
+.related-card span.category {
+ display: inline-block;
+ margin-bottom: 12px;
+}
+
.related-card p {
color: #666;
line-height: 1.6;
@@ -3230,4 +3258,247 @@ a:focus-visible {
font-size: 11px;
padding: 4px 8px;
}
+}
+
+/* Technology Showcase Section */
+.technology-showcase {
+ padding: 80px 0;
+ background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
+ position: relative;
+}
+
+.technology-showcase::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: url('data:image/svg+xml, ');
+ opacity: 0.3;
+ pointer-events: none;
+}
+
+.technology-showcase .container {
+ position: relative;
+ z-index: 1;
+}
+
+.technology-showcase h2 {
+ text-align: center;
+ margin-bottom: 50px;
+ color: #1a202c;
+ font-size: 2.5rem;
+ font-weight: 700;
+ background: linear-gradient(135deg, #144784 0%, #179e83 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.tech-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+ gap: 30px;
+ max-width: 1000px;
+ margin: 0 auto;
+}
+
+.tech-card {
+ background: white;
+ padding: 40px 30px;
+ border-radius: 16px;
+ text-align: center;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
+ transition: all 0.3s ease;
+ border: 1px solid #e2e8f0;
+ position: relative;
+ overflow: hidden;
+}
+
+.tech-card::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 4px;
+ background: linear-gradient(135deg, #144784 0%, #179e83 100%);
+ transform: scaleX(0);
+ transition: transform 0.3s ease;
+}
+
+.tech-card:hover::before {
+ transform: scaleX(1);
+}
+
+.tech-card:hover {
+ transform: translateY(-8px);
+ box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
+ border-color: #cbd5e0;
+}
+
+.tech-icon {
+ font-size: 3rem;
+ margin-bottom: 20px;
+ display: block;
+ line-height: 1;
+ filter: grayscale(0.2);
+ transition: all 0.3s ease;
+}
+
+.tech-card:hover .tech-icon {
+ transform: scale(1.1);
+ filter: grayscale(0);
+}
+
+.tech-card h3 {
+ color: #1a202c;
+ font-size: 1.5rem;
+ font-weight: 600;
+ margin: 0 0 15px 0;
+ transition: color 0.3s ease;
+}
+
+.tech-card:hover h3 {
+ color: #144784;
+}
+
+.tech-card p {
+ color: #64748b;
+ font-size: 1rem;
+ line-height: 1.6;
+ margin: 0;
+ font-weight: 500;
+}
+
+/* Responsive Design for Technology Showcase */
+@media (max-width: 768px) {
+ .technology-showcase {
+ padding: 60px 0;
+ }
+
+ .technology-showcase h2 {
+ font-size: 2rem;
+ margin-bottom: 40px;
+ }
+
+ .tech-grid {
+ grid-template-columns: 1fr;
+ gap: 20px;
+ }
+
+ .tech-card {
+ padding: 30px 20px;
+ }
+
+ .tech-icon {
+ font-size: 2.5rem;
+ margin-bottom: 15px;
+ }
+
+ .tech-card h3 {
+ font-size: 1.3rem;
+ }
+}
+
+/* Capabilities Grid (used in project-types.php) */
+.capabilities-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 40px;
+ margin: 40px 0;
+}
+
+.capability-card {
+ background: white;
+ padding: 30px;
+ border-radius: 12px;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
+ border-left: 4px solid #179e83;
+ transition: all 0.3s ease;
+ position: relative;
+ overflow: hidden;
+}
+
+.capability-card:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
+ border-left-color: #144784;
+}
+
+.capability-card h3 {
+ color: #1a202c;
+ font-size: 1.3rem;
+ font-weight: 600;
+ margin: 0 0 15px 0;
+ transition: color 0.3s ease;
+}
+
+.capability-card:hover h3 {
+ color: #144784;
+}
+
+.capability-card p {
+ color: #64748b;
+ line-height: 1.6;
+ margin: 0 0 20px 0;
+}
+
+.capability-card ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.capability-card li {
+ color: #4a5568;
+ margin: 8px 0;
+ padding-left: 20px;
+ position: relative;
+ font-size: 0.95rem;
+}
+
+.capability-card li::before {
+ content: '✓';
+ position: absolute;
+ left: 0;
+ color: #179e83;
+ font-weight: bold;
+ font-size: 1rem;
+}
+
+/* Technology badges/tags styling */
+.tech-tag {
+ display: inline-block;
+ background: linear-gradient(135deg, #144784 0%, #179e83 100%);
+ color: white;
+ padding: 6px 12px;
+ border-radius: 20px;
+ font-size: 0.9rem;
+ margin: 4px 8px 4px 0;
+ font-weight: 500;
+ transition: all 0.3s ease;
+}
+
+.tech-tag:hover {
+ transform: scale(1.05);
+ box-shadow: 0 2px 8px rgba(20, 71, 132, 0.3);
+}
+
+/* Responsive design for capabilities grid */
+@media (max-width: 768px) {
+ .capabilities-grid {
+ grid-template-columns: 1fr;
+ gap: 20px;
+ margin: 30px 0;
+ }
+
+ .capability-card {
+ padding: 25px 20px;
+ }
+
+ .capability-card h3 {
+ font-size: 1.2rem;
+ }
}
\ No newline at end of file
diff --git a/assets/js/main.js b/assets/js/main.js
index 70ab531..7c4a530 100644
--- a/assets/js/main.js
+++ b/assets/js/main.js
@@ -614,4 +614,126 @@ document.addEventListener('DOMContentLoaded', function() {
console.log('UK Data Services website initialized successfully');
console.log('Performance optimizations: Lazy loading, WebP support, and preloading enabled');
+
+ // Universal Blog Pagination System
+ initializeBlogPagination();
+
+ function initializeBlogPagination() {
+ const paginationContainer = document.querySelector('.blog-pagination');
+ const articlesGrid = document.querySelector('.articles-grid');
+
+ if (!paginationContainer || !articlesGrid) {
+ return; // No pagination on this page
+ }
+
+ const prevButton = paginationContainer.querySelector('button:first-child');
+ const nextButton = paginationContainer.querySelector('button:last-child');
+ const paginationInfo = paginationContainer.querySelector('.pagination-info');
+
+ if (!prevButton || !nextButton || !paginationInfo) {
+ return; // Invalid pagination structure
+ }
+
+ // Get current page from URL or default to 1
+ const urlParams = new URLSearchParams(window.location.search);
+ let currentPage = parseInt(urlParams.get('page')) || 1;
+
+ // Get all articles on the page
+ const allArticles = Array.from(articlesGrid.querySelectorAll('.article-card'));
+ const articlesPerPage = 6;
+ const totalPages = Math.ceil(allArticles.length / articlesPerPage);
+
+ // If we have actual multiple pages of content, use the original pagination logic
+ // Otherwise, implement client-side pagination
+ if (totalPages <= 1) {
+ // Hide pagination if not needed
+ paginationContainer.style.display = 'none';
+ return;
+ }
+
+ function renderPage(page) {
+ // Hide all articles
+ allArticles.forEach(article => {
+ article.style.display = 'none';
+ });
+
+ // Show articles for current page
+ const startIndex = (page - 1) * articlesPerPage;
+ const endIndex = startIndex + articlesPerPage;
+
+ for (let i = startIndex; i < endIndex && i < allArticles.length; i++) {
+ allArticles[i].style.display = 'block';
+ allArticles[i].style.animation = 'fadeInUp 0.6s ease forwards';
+ }
+
+ // Update pagination info
+ paginationInfo.textContent = `Page ${page} of ${totalPages}`;
+
+ // Update button states
+ prevButton.disabled = (page <= 1);
+ nextButton.disabled = (page >= totalPages);
+
+ // Update URL without page reload
+ const newUrl = new URL(window.location);
+ if (page > 1) {
+ newUrl.searchParams.set('page', page);
+ } else {
+ newUrl.searchParams.delete('page');
+ }
+ window.history.replaceState({}, '', newUrl);
+
+ // Scroll to articles section
+ articlesGrid.scrollIntoView({
+ behavior: 'smooth',
+ block: 'start'
+ });
+ }
+
+ // Event listeners
+ prevButton.addEventListener('click', function(e) {
+ e.preventDefault();
+ if (currentPage > 1) {
+ currentPage--;
+ renderPage(currentPage);
+ }
+ });
+
+ nextButton.addEventListener('click', function(e) {
+ e.preventDefault();
+ if (currentPage < totalPages) {
+ currentPage++;
+ renderPage(currentPage);
+ }
+ });
+
+ // Initialize first page
+ renderPage(currentPage);
+
+ // Add CSS animation for article transitions
+ const style = document.createElement('style');
+ style.textContent = `
+ @keyframes fadeInUp {
+ from {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
+ .article-card {
+ transition: opacity 0.3s ease, transform 0.3s ease;
+ }
+
+ .article-card[style*="display: none"] {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+ `;
+ document.head.appendChild(style);
+
+ console.log(`Blog pagination initialized: ${totalPages} pages, ${allArticles.length} articles`);
+ }
});
\ No newline at end of file
diff --git a/blog/articles/data-automation-strategies-uk-businesses.php b/blog/articles/data-automation-strategies-uk-businesses.php
index 9795466..3c8895f 100644
--- a/blog/articles/data-automation-strategies-uk-businesses.php
+++ b/blog/articles/data-automation-strategies-uk-businesses.php
@@ -213,19 +213,19 @@ $og_image = "https://ukdataservices.co.uk/assets/images/icon-automation.svg";
Related Articles
-
-
+
+
+
+ Business Intelligence
+ 1 June 2025
+
+
+ Learn the principles of creating intuitive, actionable BI dashboards that drive strategic decision-making across your organisation.
+
+
+
+
+
+ Business Intelligence
+ 28 May 2025
+
+
+ Build machine learning models to predict and prevent customer churn using advanced analytics techniques and behavioral data.
+
+
+
+
+
+ Business Intelligence
+ 25 May 2025
+
+
+ Implement real-time data processing and analytics using modern streaming platforms for immediate business insights.
+
+
+
+
+
+ Business Intelligence
+ 22 May 2025
+
+
+ Master complex SQL queries, window functions, and optimization strategies for large-scale data analytics projects.
+
+
+
+
+
+ Business Intelligence
+ 18 May 2025
+
+
+ How a UK manufacturing company streamlined operations using automated data collection and real-time analytics.
+
+
+
+
+
+ Business Intelligence
+ 15 May 2025
+
+
+ Optimize database performance for large-scale analytics workloads with indexing strategies and query optimization.
+
+
+
+
+
+ Business Intelligence
+ 12 May 2025
+
+
+ See how a major UK retailer used competitive intelligence to optimize pricing and increase market share by 15%.
+
+
+
+
+
+ Business Intelligence
+ 8 May 2025
+
+
+ Comprehensive analysis of UK fintech trends using advanced data collection and market intelligence techniques.
+
+
diff --git a/blog/categories/data-analytics.php b/blog/categories/data-analytics.php
index 510f15c..f2d74b2 100644
--- a/blog/categories/data-analytics.php
+++ b/blog/categories/data-analytics.php
@@ -222,6 +222,19 @@ $og_image = "https://ukdataservices.co.uk/assets/images/blog/data-analytics-cate
Read →
+
+
+
+ Data Analytics
+ 2 June 2025
+
+
+ Master real-time data analytics with streaming technologies. Learn to build scalable streaming pipelines for instant insights and automated decision-making.
+
+
+
+
+
+ Technology
+ 23 May 2025
+
+
+ Comprehensive guide to the latest Python tools and frameworks for building robust data pipelines in enterprise environments.
+
+
+
+
+
+ Web Scraping
+ 20 May 2025
+
+
+ Master advanced rate limiting techniques to ensure respectful and sustainable web scraping operations.
+
+
+
+
+
+ Technology
+ 18 May 2025
+
+
+ Deploy and scale web scraping applications using Kubernetes with best practices for production environments.
+
+
+
+
+
+ Legal & Compliance
+ 15 May 2025
+
+
+ Navigate UK cookie regulations and ensure compliant data collection practices in your web applications.
+
+
+
+
+
+ Industry Insights
+ 12 May 2025
+
+
+ Essential insights into the UK e-commerce market using comprehensive data analysis and market intelligence.
+
+
+
+
+
+ Case Studies
+ 10 May 2025
+
+
+ How a UK research institution improved data collection efficiency by 60% using automated web scraping solutions.
+
+
@@ -479,208 +557,7 @@ $og_image = "https://ukdataservices.co.uk/assets/images/blog-og-image.png";
});
}
- // Blog pagination functionality
- const paginationButtons = document.querySelectorAll('.blog-pagination button');
- const paginationInfo = document.querySelector('.pagination-info');
- const articlesGrid = document.querySelector('.articles-grid');
-
- if (paginationButtons.length > 0 && articlesGrid) {
- let currentPage = 1;
- const totalPages = 5; // Update this based on actual article count
- const articlesPerPage = 6;
-
- // All articles data (in real implementation, this would come from a database)
- const allArticles = [
- // Current articles from page 1
- {
- category: 'Web Scraping',
- date: '2025-06-01',
- dateTime: '2025-06-01',
- title: 'Scraping JavaScript-Heavy Sites: Advanced Techniques',
- description: 'Master the challenges of extracting data from dynamic websites using modern browser automation and rendering techniques.',
- readTime: '6 min read',
- link: 'articles/javascript-heavy-sites-scraping.php'
- },
- {
- category: 'Data Analytics',
- date: '2025-05-29',
- dateTime: '2025-05-29',
- title: 'Building Robust Data Quality Validation Pipelines',
- description: 'Implement comprehensive data validation systems to ensure accuracy and reliability in your data processing workflows.',
- readTime: '9 min read',
- link: 'articles/data-quality-validation-pipelines.php'
- },
- {
- category: 'Case Studies',
- date: '2025-05-27',
- dateTime: '2025-05-27',
- title: 'Financial Services Data Transformation Success Story',
- description: 'How a leading UK investment firm automated their market data collection and reduced analysis time by 75%.',
- readTime: '7 min read',
- link: 'articles/financial-services-data-transformation.php'
- },
- {
- category: 'Technology',
- date: '2025-05-25',
- dateTime: '2025-05-25',
- title: 'Cloud-Native Scraping Architecture for Enterprise Scale',
- description: 'Design scalable, resilient web scraping infrastructure using modern cloud technologies and containerization.',
- readTime: '11 min read',
- link: 'articles/cloud-native-scraping-architecture.php'
- },
- {
- category: 'Industry Insights',
- date: '2025-05-22',
- dateTime: '2025-05-22',
- title: 'UK Property Market: Data-Driven Investment Insights',
- description: 'Leverage comprehensive property data analysis to identify emerging investment opportunities across UK markets.',
- readTime: '8 min read',
- link: 'articles/uk-property-market-data-trends.php'
- },
- {
- category: 'Legal & Compliance',
- date: '2025-05-20',
- dateTime: '2025-05-20',
- title: 'GDPR Data Minimisation: Best Practices for Data Teams',
- description: 'Implement effective data minimisation strategies that comply with GDPR requirements while maintaining analytical value.',
- readTime: '6 min read',
- link: 'articles/gdpr-data-minimisation-practices.php'
- },
- // Page 2 articles
- {
- category: 'Data Analytics',
- date: '2025-05-23',
- dateTime: '2025-05-23',
- title: 'Predictive Analytics for Customer Churn Prevention',
- description: 'Build machine learning models to predict and prevent customer churn using advanced analytics techniques and behavioral data.',
- readTime: '13 min read',
- link: 'articles/predictive-analytics-customer-churn.php'
- },
- {
- category: 'Data Analytics',
- date: '2025-05-20',
- dateTime: '2025-05-20',
- title: 'Advanced SQL Techniques for Data Analytics',
- description: 'Master complex SQL queries, window functions, and optimization strategies for large-scale data analytics projects.',
- readTime: '14 min read',
- link: 'articles/sql-analytics-advanced-techniques.php'
- },
- {
- category: 'Data Analytics',
- date: '2025-05-18',
- dateTime: '2025-05-18',
- title: 'Real-Time Analytics with Streaming Data Platforms',
- description: 'Implement real-time data processing and analytics using modern streaming platforms like Apache Kafka and Apache Flink.',
- readTime: '12 min read',
- link: 'articles/real-time-analytics-streaming.php'
- },
- {
- category: 'Web Scraping',
- date: '2025-05-16',
- dateTime: '2025-05-16',
- title: 'Handling CAPTCHAs in Web Scraping: Professional Techniques',
- description: 'Learn professional techniques for handling CAPTCHAs in web scraping operations with ethical approaches and automated solutions.',
- readTime: '10 min read',
- link: 'articles/handling-captchas-scraping.php'
- },
- {
- category: 'Web Scraping',
- date: '2025-05-15',
- dateTime: '2025-05-15',
- title: 'Python Scrapy for Enterprise: Complete Implementation Guide',
- description: 'Master Scrapy framework for enterprise-scale web scraping with advanced configurations, monitoring, and deployment strategies.',
- readTime: '15 min read',
- link: 'articles/python-scrapy-enterprise-guide.php'
- },
- {
- category: 'Technology',
- date: '2025-05-12',
- dateTime: '2025-05-12',
- title: 'Selenium vs Playwright: Comprehensive Comparison for 2025',
- description: 'Detailed comparison of browser automation tools covering performance, features, and real-world applications.',
- readTime: '11 min read',
- link: 'articles/selenium-vs-playwright-comparison.php'
- }
- ];
-
- function renderArticles(page) {
- const startIndex = (page - 1) * articlesPerPage;
- const endIndex = startIndex + articlesPerPage;
- const pageArticles = allArticles.slice(startIndex, endIndex);
-
- articlesGrid.innerHTML = pageArticles.map(article => `
-
-
- ${article.category}
- ${article.date}
-
-
- ${article.description}
-
-
${article.readTime}
-
Read →
-
-
- `).join('');
- }
-
- function updatePagination() {
- paginationInfo.textContent = `Page ${currentPage} of ${totalPages}`;
-
- // Update Previous button
- const prevButton = paginationButtons[0];
- if (currentPage <= 1) {
- prevButton.disabled = true;
- prevButton.textContent = 'Previous';
- } else {
- prevButton.disabled = false;
- prevButton.textContent = 'Previous';
- }
-
- // Update Next button
- const nextButton = paginationButtons[1];
- if (currentPage >= totalPages) {
- nextButton.disabled = true;
- nextButton.textContent = 'Next';
- } else {
- nextButton.disabled = false;
- nextButton.textContent = 'Next';
- }
- }
-
- // Previous button click handler
- paginationButtons[0].addEventListener('click', function() {
- if (currentPage > 1) {
- currentPage--;
- renderArticles(currentPage);
- updatePagination();
-
- // Scroll to articles section
- document.querySelector('.blog-recent').scrollIntoView({
- behavior: 'smooth',
- block: 'start'
- });
- }
- });
-
- // Next button click handler
- paginationButtons[1].addEventListener('click', function() {
- if (currentPage < totalPages) {
- currentPage++;
- renderArticles(currentPage);
- updatePagination();
-
- // Scroll to articles section
- document.querySelector('.blog-recent').scrollIntoView({
- behavior: 'smooth',
- block: 'start'
- });
- }
- });
-
- // Initialize pagination
- updatePagination();
- }
+ // Pagination is now handled by the universal pagination system in main.js
});