Accessibility fixes and form session expiration fix

- Fix color contrast: change #179e83 to #148069 for WCAG AA compliance
- Add ARIA attributes to mobile nav toggle (aria-expanded, aria-controls)
- Implement focus trap on mobile menu with Escape key support
- Add aria-hidden to decorative hero SVG
- Add ARIA validation to contact form (aria-invalid, aria-describedby)
- Fix touch target sizes (notification close button 48x48px)
- Fix form session expiration by relaxing timestamp validation
- Add cache busting (v1.1.0) to JS/CSS files
- Update service worker cache version to force refresh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
root
2026-01-12 20:22:49 +00:00
parent 5e1401ef14
commit f495ee23c2
8 changed files with 3552 additions and 3383 deletions

View File

@@ -102,9 +102,9 @@ $twitter_card_image = "https://ukdataservices.co.uk/assets/images/ukds-main-logo
<link href="https://fonts.googleapis.com/css2?family=Roboto+Slab:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Lato:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<!-- Resource Preloading for Performance -->
<link rel="preload" href="/assets/css/main.min.css" as="style">
<link rel="preload" href="/assets/css/main.min.css?v=1.1.0" as="style">
<link rel="preload" href="/assets/images/ukds-main-logo.webp" as="image">
<link rel="preload" href="/assets/js/main.min.js" as="script">
<link rel="preload" href="/assets/js/main.min.js?v=1.1.0" as="script">
<!-- Critical CSS for Above-the-Fold -->
<style>
@@ -128,8 +128,8 @@ $twitter_card_image = "https://ukdataservices.co.uk/assets/images/ukds-main-logo
</style>
<!-- Styles -->
<link rel="stylesheet" href="/assets/css/main.min.css" media="print" onload="this.media='all'">
<noscript><link rel="stylesheet" href="assets/css/main.min.css"></noscript>
<link rel="stylesheet" href="/assets/css/main.min.css?v=1.1.0" media="print" onload="this.media='all'">
<noscript><link rel="stylesheet" href="assets/css/main.min.css?v=1.1.0"></noscript>
<!-- Enhanced Local SEO Schema -->
<script type="application/ld+json">
@@ -470,11 +470,11 @@ $twitter_card_image = "https://ukdataservices.co.uk/assets/images/ukds-main-logo
<a href="#contact" class="nav-link">Contact</a>
<a href="/quote" class="nav-link cta-button">Request Consultation</a>
</div>
<div class="nav-toggle" id="nav-toggle">
<button class="nav-toggle" id="nav-toggle" aria-expanded="false" aria-controls="nav-menu" aria-label="Toggle navigation menu">
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</div>
</button>
</div>
</nav>
@@ -506,7 +506,7 @@ $twitter_card_image = "https://ukdataservices.co.uk/assets/images/ukds-main-logo
</div>
<div class="hero-image">
<div class="hero-graphic">
<svg width="500" height="400" viewBox="0 0 500 400" xmlns="http://www.w3.org/2000/svg">
<svg width="500" height="400" viewBox="0 0 500 400" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
<!-- Path definitions for animations -->
<defs>
<path id="extraction-path" d="M290 140 Q350 120 380 160"/>
@@ -1062,25 +1062,28 @@ $twitter_card_image = "https://ukdataservices.co.uk/assets/images/ukds-main-logo
</div>
<div class="contact-form">
<form action="contact-handler.php" method="POST" class="form">
<form action="contact-handler.php" method="POST" class="form" novalidate>
<div class="form-group">
<label for="name">Contact Name *</label>
<input type="text" id="name" name="name" required>
<input type="text" id="name" name="name" required aria-required="true" aria-describedby="name-error" autocomplete="name">
<span id="name-error" class="form-error" role="alert" aria-live="polite"></span>
</div>
<div class="form-group">
<label for="email">Business Email *</label>
<input type="email" id="email" name="email" required>
<input type="email" id="email" name="email" required aria-required="true" aria-describedby="email-error" autocomplete="email">
<span id="email-error" class="form-error" role="alert" aria-live="polite"></span>
</div>
<div class="form-group">
<label for="company">Organisation *</label>
<input type="text" id="company" name="company" required>
<input type="text" id="company" name="company" required aria-required="true" aria-describedby="company-error" autocomplete="organization">
<span id="company-error" class="form-error" role="alert" aria-live="polite"></span>
</div>
<div class="form-group">
<label for="service">Service Interest</label>
<select id="service" name="service">
<select id="service" name="service" aria-describedby="service-error">
<option value="">Please select...</option>
<option value="web-intelligence">Enterprise Web Intelligence & Monitoring</option>
<option value="technology-platform">Advanced Technology Platform Solutions</option>
@@ -1090,11 +1093,13 @@ $twitter_card_image = "https://ukdataservices.co.uk/assets/images/ukds-main-logo
<option value="compliance">Compliance & Security Assessment</option>
<option value="other">Other Requirements</option>
</select>
<span id="service-error" class="form-error" role="alert" aria-live="polite"></span>
</div>
<div class="form-group">
<label for="message">Business Requirements *</label>
<textarea id="message" name="message" rows="5" required placeholder="Please outline your data requirements, business objectives, compliance considerations, and any specific technical specifications..."></textarea>
<textarea id="message" name="message" rows="5" required aria-required="true" aria-describedby="message-error" placeholder="Please outline your data requirements, business objectives, compliance considerations, and any specific technical specifications..."></textarea>
<span id="message-error" class="form-error" role="alert" aria-live="polite"></span>
</div>
<!-- Hidden fields for security -->
@@ -1213,7 +1218,7 @@ $twitter_card_image = "https://ukdataservices.co.uk/assets/images/ukds-main-logo
</footer>
<!-- Scripts -->
<script src="/assets/js/main.min.js"></script>
<script src="/assets/js/main.min.js?v=1.1.0"></script>
<!-- Service Worker Registration -->
<script>