PageSourceSearch

https://acgov.org/government/dotgov.htm

html acgov.org collected 2026-09-24 08:28:01 UTC 30,187 bytes, 705 lines download raw bytes

1<!doctype html>
2<html lang="en-us">
3<head>
4    <title>Dot Gov | Alameda County</title>
5    <meta charset="utf-8">
6    <meta http-equiv="X-UA-Compatible" content="IE=edge">
7    <meta name="viewport" content="width=device-width, initial-scale=1">
8    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
9    <meta name="Description" content="Page with information about connecting with Alameda County.">
10    <meta name="Keywords" content="Alameda County, government, social media, open government, citizen engagement, Facebook, Twitter, Flickr, YouTube, GovDelivery, email subscription, e-Subscription, e-Subscribe, connect, stay connected, get connected,  ">
11    <meta name="Location" content="Alameda County, Bay Area, California, United States">
12    
13    <!-- Google Tag Manager -->
14<script>
vendor: 331 bytes, lines 14-18
14(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
15new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
16j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
17'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
18})(window,document,'script','dataLayer','
18GTM-MW6VWCK
vendor: 3 bytes, line 18
18');
18</script>
18
19<!-- End Google Tag Manager -->
20
21<!-- Bootstrap core CSS -->
22<link href="/acgov-css/bootstrap.min.css" rel="stylesheet">
23
24<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
25<link href="/acgov-css/ie10-viewport-bug-workaround.css" rel="stylesheet">
26
27<!-- Custom styles for this template -->
28<link href="/acgov-css/custom.css" rel="stylesheet">
29
30<!-- Google Material Icons Font -->
31<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
32
33<!-- Background Image Load -->
34<!-- When changing the wallpaper image, keep in mind that it may effect the readability of content since the 
35content div is partially transparent. Adjust the transparency on line 164 of the custom.css file -->
36<script>
37//window.onload = function() {
38//if (window.screen.width > 767) {
39//	document.body.style.backgroundImage = "url('/img/wallpaper-merritt-adj2.jpg')";
40//}
41//}
42
43function submitsearch() {
44	document.getElementById("search-form").submit();
45}
46function goback() {
47	window.history.back();
48}
49</script>
49  
50
51<script> /* NEW TEMP SEARCH BOX */
52  (function() {
53    var cx = '002986915478428468373:0muhvevs3v0';
54    var gcse = document.createElement('script');
55    gcse.type = 'text/javascript';
56    gcse.async = true;
57    gcse.src = 'https://cse.google.com/cse.js?cx=' + cx;
58    var s = document.getElementsByTagName('script')[0];
59    s.parentNode.insertBefore(gcse, s);
60  })();
61</script>
61
62
63
64<style> /* NEW TEMP SEARCH BOX */
65td.gsc-search-button { padding-right: 5px; }
66td.gsib_a {
67  padding:10px;
68}
69.gsc-search-button-v2 {
70    padding: 11px 25px !important;
71    margin: 15px;
72    border-radius: 3px !important;
73}
74.gsc-search-button-v2 svg {
75		width:18px;
76		height:18px;
77}
78/*Media Querry*/
79@media (max-width:767px){
80td.gsc-input { width:20%;}
81}
82</style>
83	
84	<style>
85    	.social-icon {
86			max-width: 75px;
87			margin: 10px;
88		}
89		.info-msg {display: none;}
90				
91    </style>
92</head>
93
94<body>
95	<!-- skip to content -->
96<header>
97	<a href="#content" class="skip-link">Skip to Content</a>
98
99	<!-- Above-the-fold branding -->
100	<div id="acgov-branding" class="container branding">
101		<div class="row container">
102			<div id="acgov-logo" class="col-sm-6 col-xs-12 logo">
103				<a href="/index.htm">
104					<img id="acgovlogo" class="img-responsive acgov-logo" src="/img/acgov-branding2024.png" alt="Alameda County CA acgov Home" />
105				</a>
106			</div>
107			<div id="acgov-tagline" class="col-sm-6 col-xs-12 tagline">
108				<!-- Accessible Translate trigger (top) -->
109				<a id="translate-trigger-top" href="#" role="button" data-toggle="modal" data-target="#modal-trans" aria-haspopup="dialog" aria-controls="modal-trans" aria-expanded="false">
110					<span class="material-icons md-24 trans-icon">&#xE927;</span> Translate
111				</a>
112			</div>
113		</div>
114	</div>
115
116	<!-- Sticky / scrolled branding -->
117	<div id="acgov-branding-scroll" class="container branding" style="display:none;">
118		<div class="row container">
119			<div id="logo-scroll" class="col-sm-2 col-xs-12 logo">
120				<a href="/index.htm">
121					<img class="img-responsive acgov-logo" src="/img/acgov-branding2024.png" alt="ACGOV Logo" />
122				</a>
123			</div>
124			<div id="spacer" class="col-sm-5 col-xs-12 spacer"></div>
125			<div id="tagline-scroll" class="col-sm-5 col-xs-12 tagline-scroll">
126				<!-- Accessible Translate trigger (sticky) -->
127				<a id="translate-trigger-scroll" href="#" role="button" data-toggle="modal" data-target="#modal-trans" aria-haspopup="dialog" aria-controls="modal-trans" aria-expanded="false">
128					<span class="material-icons md-24 trans-icon">&#xE927;</span> Translate
129				</a>
130			</div>
131		</div>
132	</div>
133</header>
134
135<script>
136	// ===== Sticky header behavior (original, now with null-safety) =====
137	window.onscroll = changePos;
138	function changePos() {
139		var branding = document.getElementById("acgov-branding");
140		var brandingscroll = document.getElementById("acgov-branding-scroll");
141		var tagline = document.getElementById("acgov-tagline");
142		var logo = document.getElementById("acgovlogo");
143
144		if (document.documentElement.clientWidth >= 768) {
145			if (window.pageYOffset > 57) {
146				if (branding) branding.style.display = "none";
147				if (brandingscroll) brandingscroll.style.display = "block";
148			} else {
149				if (branding) branding.style.display = "block";
150				if (brandingscroll) brandingscroll.style.display = "none";
151			}
152		} else {
153			if (window.pageYOffset > 57) {
154				if (tagline) tagline.style.display = "none";
155				if (logo) logo.style.maxWidth = "200px";
156			} else {
157				if (tagline) tagline.style.display = "block";
158				if (logo) logo.style.maxWidth = "100%";
159			}
160		}
161	}
162
163	// ===== Accessibility: aria-expanded sync + focus trap for #modal-trans =====
164	document.addEventListener("DOMContentLoaded", function () {
165		var modal = document.getElementById("modal-trans");
166		if (!modal) return; // modal needs to exist
167
168		// Collect both triggers, if present
169		var triggers = [
170			document.getElementById("translate-trigger-top"),
171			document.getElementById("translate-trigger-scroll")
172		].filter(Boolean);
173
174		// Remember which trigger opened the modal (for focus restore + aria state)
175		var lastTrigger = null;
176
177		// When a trigger is clicked, record it as the opener
178		triggers.forEach(function (t) {
179			t.addEventListener("click", function () { lastTrigger = t; }, { capture: true });
180		});
181
182		// Helper: set aria-expanded on all triggers (defaults to "false")
183		function setExpandedForTriggers(value) {
184			triggers.forEach(function (t) {
185				t.setAttribute("aria-expanded", value ? "true" : "false");
186			});
187		}
188
189		// Bootstrap modal events
190		modal.addEventListener("shown.bs.modal", function (evt) {
191			// Prefer the event's relatedTarget (Bootstrap sets it), else use lastTrigger
192			var opener = evt && evt.relatedTarget ? evt.relatedTarget : lastTrigger;
193			// First set all to false, then true on the opener (for accuracy)
194			setExpandedForTriggers(false);
195			if (opener && opener.setAttribute) opener.setAttribute("aria-expanded", "true");
196
197			// Move focus to the first meaningful element inside the modal
198			var focusables = getFocusableElements(modal);
199			if (focusables.length) {
200				var preferred = modal.querySelector('[data-primary], .btn-primary, [data-dismiss="modal"], .close');
201				(preferred && typeof preferred.focus === "function" ? preferred : focusables[0]).focus();
202			}
203
204			// Start focus trap
205			modal.addEventListener("keydown", trapTabKey);
206		});
207
208		modal.addEventListener("hidden.bs.modal", function () {
209			// Reset aria-expanded for all triggers
210			setExpandedForTriggers(false);
211
212			// Stop focus trap
213			modal.removeEventListener("keydown", trapTabKey);
214
215			// Restore focus to the opener, if available
216			if (lastTrigger && typeof lastTrigger.focus === "function") {
217				lastTrigger.focus();
218			}
219			lastTrigger = null;
220		});
221
222		// ===== Focus trap helpers =====
223		function getFocusableElements(container) {
224			var selector = [
225				'a[href]:not([tabindex="-1"])',
226				'area[href]:not([tabindex="-1"])',
227				'input:not([type="hidden"]):not([disabled]):not([tabindex="-1"])',
228				'select:not([disabled]):not([tabindex="-1"])',
229				'textarea:not([disabled]):not([tabindex="-1"])',
230				'button:not([disabled]):not([tabindex="-1"])',
231				'iframe:not([tabindex="-1"])',
232				'audio[controls]:not([tabindex="-1"])',
233				'video[controls]:not([tabindex="-1"])',
234				'[contenteditable]:not([tabindex="-1"])',
235				'[tabindex]:not([tabindex="-1"])'
236			].join(',');
237
238			return Array.prototype.slice.call(container.querySelectorAll(selector))
239				.filter(function (el) {
240					return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0;
241				});
242		}
243
244		function trapTabKey(e) {
245			if (e.key !== "Tab") return;
246
247			var focusables = getFocusableElements(modal);
248			if (!focusables.length) return;
249
250			var first = focusables[0];
251			var last = focusables[focusables.length - 1];
252			var active = document.activeElement;
253
254			if (e.shiftKey) {
255				if (active === first || !modal.contains(active)) {
256					last.focus();
257					e.preventDefault();
258				}
259			} else {
260				if (active === last || !modal.contains(active)) {
261					first.focus();
262					e.preventDefault();
263				}
264			}
265		}
266	});
267</script>
267
268    <div role="search" class="container searchbox">
269<!--<div class="container urgent">
270    <div class="row">
271      <p><i class="material-icons md-48 md-vertical-middle">&#xE000;</i> This is a sample urgent notification box. Please click here for more information: <a href="as">Urgent Link</a></p>
272    </div>
273</div>-->
274    <!-- <div class="container info-msg">
275        <div class="row">
276            <p><span class="material-icons md-48 md-vertical-middle">warning</span><strong>Upcoming Website Outages</strong><br> Due to upcoming maintenance, you may encounter errors when accessing County websites this Sunday, August 10th.<br>We apologize for any inconvenience.</p>
277        </div>
278    </div> -->
279<div class="container info-msg">
280        <div class="row">
281        <p><span class="material-icons md-48 md-vertical-middle">info</span> Alameda County is gradually transitioning our websites to a new .GOV domain name: "alamedacountyca.gov".</br><a href="/government/dotgov.htm">Learn more</a><span class="material-icons md-32 md-vertical-middle">arrow_forward</span></p>
282        </div>
283    </div>
284
285    <div class="row search">
286        <form id="search-form" style="margin: auto; width: 90%;"  method="get" action="https://acsearch.acgov.org/s/search.html?" target="_parent" type="external">
287            <div class="input-group">
288            	<label for="funnelbackinput" class="sr-only">Search</label>
289                
290                <input id="funnelbackinput"  type="search" name="query" class="form-control search-input" placeholder="What can we help you find today?" aria-label="Search">
291                <span class="input-group-addon">
292                    <button type="submit" class="btn search-button" name="btnG" value="Search" aria-label="Submit search">Search</button>
293                </span>
294          </div>
295          <input type="hidden" name="collection" value="acgov" />
296            <input type="hidden" name="profile" value="acgov">
297            <input type="hidden" name="form" value="acgov" />
298       </form>
299    </div>
300</div>
301<!-- skip to content jumplink destination <div> starts here-->
302<div role="main" id="content">
303    <!-- ending </div> is located at begining of footer -->
304    <!-- Google Translate the Pages --------------------------------->
305<div class="modal fade" id="modal-trans" tabindex="-1" role="dialog" aria-modal="true" aria-labelledby="modal-title" aria-describedby="modal-desc">
306    <div class="modal-dialog" role="document">
307        <div class="modal-content">
308            <div class="modal-header">
309
310                <!-- Close button: accessible label + visual "×" -->
311                <button type="button" class="close" data-dismiss="modal" aria-label="Close dialog">
312                    <span aria-hidden="true">&times;</span>
313                    <span class="sr-only">Close</span>
314                </button>
315
316                <!-- Modal title with id referenced by aria-labelledby -->
317                <h3 class="modal-title" id="modal-title">Translate this Page</h3>
318            </div>
319
320            <!-- Body gets an id referenced by aria-describedby -->
321            <div class="modal-body deptinfo" id="modal-desc">
322                <h4>Disclaimer</h4>
323                <p>Translation of pages on ACGOV.org is performed by Google Translate, a third-party service which Alameda County has no control over. The service provides automated computer translations that are only an approximation of the websites’ original content.</p>
324                <p>Alameda County does not warrant the accuracy, reliability, or timeliness of any information translated by Google Translate. These translations should not be considered exact renderings of the original ACGOV.org site. Some portions of the site will not be translated at all, which includes but is not limited to buttons, graphics, photos, and video content.</p>
325
326                <!-- Keep the widget container as its own block (avoid nesting <div> inside <p>) -->
327                <div class="mt-3" id="google_translate_element"></div>
328            </div>
329
330            <!-- Optional footer with an explicit close action for keyboard users -->
331            <div class="modal-footer">
332                <button type="button" class="btn btn-primary" data-dismiss="modal" data-primary>Close</button>
333            </div>
334        </div>
335    </div>
336</div>
337
338<script>
339(function () {
340  var attempts = 0;
341  var maximumAttempts = 60;
342
343  function attachTranslationTracking() {
344    var dropdown = document.querySelector(".goog-te-combo");
345
346    if (!dropdown) {
347      attempts++;
348
349      if (attempts < maximumAttempts) {
350        window.setTimeout(attachTranslationTracking, 500);
351      } else {
352        console.warn("Translation tracking: Google Translate dropdown was not found.");
353      }
354
355      return;
356    }
357
358    if (dropdown.getAttribute("data-siteimprove-tracking") === "true") {
359      return;
360    }
361
362    dropdown.setAttribute("data-siteimprove-tracking", "true");
363
364    dropdown.addEventListener("change", function () {
365      var selectedOption = this.options[this.selectedIndex];
366
367      if (!this.value || !selectedOption) {
368        return;
369      }
370
371      var languageName = selectedOption.text.trim();
372
373      console.log(
374        "Siteimprove translation event:",
375        this.value,
376        languageName
377      );
378
379      window._sz = window._sz || [];
380      window._sz.push([
381        "event",
382        "Translation",
383        "Language selected",
384        languageName
385      ]);
386    });
387
388    console.log("Translation tracking attached.");
389  }
390
391  attachTranslationTracking();
392})();
393</script>
393
394    <div class="container content">
395        <div class="row row-title">
396        	<h1 class="pagetitle">.GOV Transition</h1>
397            <a href="#" data-toggle="modal" data-target="#modal-trans"><span class="material-icons md-48 trans-icon">&#xE927;</span></a>
398        </div>
399        <div class="row regular">
400           	<div class="col-xs-12 col-sm-8 main-column">
401				<p>Alameda County is committed to providing secure and reliable information on our websites. We want you to trust that our websites are the "official" websites of Alameda County. This is the primary reason why we are transitioning our websites to .GOV domain names.</p> <p>Our websites will gradually transition from "acgov.org" to "alamedacountyca.gov". In the meantime, you will see "official" Alameda County websites with both domain names.</p>
402                <h2>What is .GOV?</h2>
403				<p>The .GOV domain name indicates that a website is owned by an official US government organization. The DotGov program examines each request for a .gov domain name to ensure it is from a genuine US-based government or public sector organization.</p>
404            	<h2>Why .GOV?</h2>
405				<h3>Trust</h3>
406                 <p>You are more likely to trust the information on a .GOV website because it has been vetted and approved by a government agency. This is especially important in regard to election results.</p>
407				<h3>Authority</h3>
408				<p>A .GOV website is considered an authoritative source of information, which can increase the website's visibility and ranking in search engines.</p>
409				<h3>Identification</h3>
410				<p>Using a .GOV domain shows we are official.</p>
411				<h3>Credibility</h3>
412				<p>All branches of the United States federal government use a .GOV domain. Information such as Census statistics, Congressional hearings, and Supreme Court rulings would be included in sites with this domain.</p>
413				<h3>Legally Required</h3>
414				<p>California State Assembly Bill No. 1637 requires all local government agencies to use a .GOV domain name no later than January 1, 2029.</p>
415            	<h2>When is this happening?</h2>
416                <p>The transition of all our websites to .GOV domain names will be a long process. We have already launched our first .GOV website with more to come. The transition will also include our employees' official email addresses.</p>
417            </div>              
418    	  	<div class="col-xs-12 col-sm-4 side-column bordered">
419                <div id="related"> 
420                    <h2><span class="material-icons md-36 md-vertical-middle">&#xE157;</span> Related Links</h2>
421                    <ul>
422                        <li><a href="https://get.gov/" class="external-link">Official .GOV Registry</a></li>
423                        
424                    </ul>
425                </div>
426            </div>
427       	</div>
428        <!-- Modal Window -->
429        <div class="modal fade" id="modal-govd" tabindex="-1" role="dialog" aria-label="Email subscription sign-up">
430    		<div class="modal-dialog" role="document">
431        		<div class="modal-content">
432           			<div class="modal-header">
433                		<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
434                		<h3 class="modal-title"><span class="material-icons md-36 md-vertical-middle">&#xE0be;</span> Get Email Updates</h3>
435            		</div>
436                    <div class="modal-body deptinfo">
437                        <form id="GD-snippet-form" action="https://public.govdelivery.com/accounts/CAALAME/subscribers/qualify" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="Og1izipZAapbmVioBvav08Yp6RF2enmpMVaUvFUWIgWjE8h632WdH4pZz4jP0NJoSB6RtqPGddhUnED3QpqZSQ==" />
438                        <input type="hidden" name="topic_id" id="topic_id" value="CAALAME" />
439                        <fieldset>
440                        <div>
441                            Join our email subscription lists and get notified by email when updates happen. To sign up for updates or to access your subscriber preferences, please enter your contact information below.
442                        </div>
443                        <ol class="form">
444                        <li class="email_fields" style="display: block">
445                        <label for="email">Email Address</label>
446                        <input type="text" name="email" id="email" class="long" />
447                        </li>
448                        </ol>
449                        <div class="button_panel">
450                            <input type="submit" name="commit" value="Subscribe" class="form_button" />
451                        </div>
452                        </fieldset>
453                        </form>
454                    </div>
455        		</div>
456     		</div>
457     	</div>
458     </div>
459   <!-- ending of role="main" here-->
460</div>
461
462<!-- footer starts here -->
463<footer class="container-fluid footer">
464	<div class="row text-center">
465        <p>
466            <a class="cu" href="/government/contactus.htm">Contact Us</a> | 
467            <a class="acc" href="/government/accessibility.htm">Accessibility</a> |
468            <a class="la" href="/acspeaks/">Language Access</a> |
469			      <a class="em" href="/emergencysite/">
469Emergencies</a> |
470            <a class="ld" href="/government/legal.htm">Legal/Disclaimers</a> | 
471            <a class="ps" href="/government/legal.htm">Privacy Statement</a> | 
472            <a class="gu" href="/government/guidelines.htm">Website Guidelines</a> | 
473            <a class="sb" href="/government/sb272.htm">SB 272 </a> | 
474            <a class="sm" href="/sitemap.htm">Site Map</a>
475            <br />
476            <a href="https://www.facebook.com/AlamedaCounty" class="external-link"><img class="social-icon" src="/img/facebook200x200.png" alt="facbook icon" /></a>
477                <a href="https://twitter.com/AlamedaCounty" class="external-link"><img class="social-icon" src="/img/twitter200x200.png" alt="Twitter icon" /></a>
478                <a href="https://www.youtube.com/user/AlamedaCountyCA" class="external-link"><img class="social-icon" src="/img/youtube200x200.png" alt="YouTube icon" /></a>
479                <a href="https://www.flickr.com/photos/alamedacounty" class="external-link"><img class="social-icon" src="/img/flickr200x200.png" alt="Flickr icon" /></a>
480                <a href="/government/connected/rss.htm"><img class="social-icon" src="/img/rss200x200.png" alt="RSS icon" /></a>
481                <a href="https://public.govdelivery.com/accounts/CAALAME/subscriber/new" class="external-link"><img class="social-icon" src="/img/govdelivery200x200.png" alt="GovDelivery icon" /></a>
482             <br />   
483            <a href="http://www.adobe.com/go/getreader" class="external-link">
484                <img alt="Get Adobe Reader" style="padding: 10px;" src="/img/get-reader.png" /></a>
485            <br />
486            <span class="material-icons md-18" style="vertical-align:bottom">&#xE90C;</span> 2025 Alameda County
487        </p>
488    </div>
489</footer>
490
491<!-- Bootstrap core JavaScript
492================================================== -->
493<!-- Placed at the end of the document so the pages load faster -->
494
495<script type="text/javascript">
496function googleTranslateElementInit() {
497  new google.translate.TranslateElement({pageLanguage: 'en', includedLanguages: 'af,am,ar,de,es,fa,fr,gu,hi,id,ja,km,ko,pt,ru,so,sw,tl,ur,vi,yo,zh-CN,zh-TW'}, 'google_translate_element');
498}
499</script>
499<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
499
500        
501
502<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
502
503<script>window.jQuery || document.write('
503<script src="/acgov-js/jquery.min.js"><\/script>')</script>
503
504<script src="/acgov-js/bootstrap.min.js"></script>
504
505<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
506<script src="/acgov-js/ie10-viewport-bug-workaround.js"></script>
506
507<!-- Google Analytics code -->
508<script>
vendor: 340 bytes, lines 508-514
508
509	(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
510	(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
511	m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
512	})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
513
514	ga('create', '
514UA-48660008-1
vendor: 44 bytes, lines 514-515
514', 'acgov.org');
515	ga('send', 'pageview');
516</script>
516
517
518
519
520<!-- External Links-->
521<!-- External Link Popup - HTML structure -->
522<div id="external-popup" class="popup-overlay" role="dialog" aria-labelledby="popup-title" aria-hidden="true">
523	<div class="popup-content">
524		<button id="close-external-popup" class="popup-close" aria-label="Close">X</button>
525		<p><img src="/img/external-site-icon.svg" width="50px" alt="External Link" class="popup-icon"></p>
526		<h2 id="popup-title">External Link</h2>
527		<p>You are about to leave an official Alameda County website.
528			Alameda County bears no responsibility for the accuracy, legality, accessibility, or content of the external site or for that of subsequent links.
529			Contact the external site for answers to questions regarding its content.</p>
530		<div class="popup-button-container">
531			<button id="cancel-external" class="popup-button btn btn-default btn-lg">Cancel</button>
532			<button id="continue-external" class="popup-button btn btn-success btn-lg">Continue</button>
533		</div>
534	</div>
535</div>
536
537<!-- External Link Popup JavaScript -->
538<script>
539	document.addEventListener("DOMContentLoaded", function () {
540		const modal = document.getElementById("external-popup");
541		const closeButton = document.getElementById("close-external-popup");
542		const cancelButton = document.getElementById("cancel-external");
543		const continueButton = document.getElementById("continue-external");
544
545		//  CHANGED: store the actual trigger element (the link), not document.activeElement
546		let lastTriggerEl = null;
547
548		let popupShownInSession = sessionStorage.getItem('externalPopupShown') === 'true';
549
550		// (Optional but recommended) Make sure dialog semantics are present
551		if (!modal.hasAttribute('role')) modal.setAttribute('role', 'dialog');
552		if (!modal.hasAttribute('aria-modal')) modal.setAttribute('aria-modal', 'true');
553
554		function getFocusableInModal() {
555			const nodeList = modal.querySelectorAll(
556				"button, [href], input, select, textarea, [tabindex]:not([tabindex='-1'])"
557			);
558			return Array.from(nodeList).filter(el => !el.hasAttribute('disabled') && el.offsetParent !== null);
559		}
560
561		//  CHANGED: accept the trigger element; derive URL from it
562		function openModal(triggerEl) {
563			lastTriggerEl = triggerEl; // <-- save the invoker reliably
564			const externalURL = triggerEl?.href;
565
566			modal.style.display = "block";
567			modal.setAttribute("aria-hidden", "false");
568
569			// Move focus inside the dialog (prefer the close button; fallback to first focusable or modal)
570			const focusables = getFocusableInModal();
571			(closeButton || focusables[0] || modal).focus();
572
573			continueButton.onclick = () => {
574				sessionStorage.setItem('externalPopupShown', 'true');
575				popupShownInSession = true;
576				if (externalURL) window.location.href = externalURL;
577			};
578			cancelButton.onclick = closeModal;
579			closeButton.onclick = closeModal;
580
581			document.addEventListener("keydown", trapTabKey);
582			document.addEventListener("keydown", closeOnEscape);
583
584			// If you want "once per session" behavior on open, keep this:
585			sessionStorage.setItem('externalPopupShown', 'true');
586			popupShownInSession = true;
587		}
588
589		function closeModal() {
590			modal.style.display = "none";
591			modal.setAttribute("aria-hidden", "true");
592
593			document.removeEventListener("keydown", trapTabKey);
594			document.removeEventListener("keydown", closeOnEscape);
595
596			//  CHANGED: restore focus to the invoker on the next frame for VO/Safari reliability
597			if (lastTriggerEl && lastTriggerEl.isConnected) {
598				requestAnimationFrame(() => {
599					try {
600						lastTriggerEl.focus({ preventScroll: false });
601					} catch (_) {
602						// Silent fallback
603						lastTriggerEl.focus();
604					}
605				});
606			}
607		}
608
609		function trapTabKey(e) {
610			if (e.key !== "Tab") return;
611
612			const focusableElements = getFocusableInModal();
613			if (!focusableElements.length) return;
614
615			const firstElement = focusableElements[0];
616			const lastElement = focusableElements[focusableElements.length - 1];
617
618			if (e.shiftKey && document.activeElement === firstElement) {
619				lastElement.focus();
620				e.preventDefault();
621			} else if (!e.shiftKey && document.activeElement === lastElement) {
622				firstElement.focus();
623				e.preventDefault();
624			}
625		}
626
627		function closeOnEscape(e) {
628			if (e.key === "Escape") {
629				e.preventDefault();
630				closeModal();
631			}
632		}
633
634		function setupExternalLinks() {
635			document.querySelectorAll('a.external-link').forEach(link => {
636				if (link.children.length === 1 && link.querySelector("button, img, span.material-icons, i.material-icons")) {
637					link.classList.add("hide-icon");
638				}
639
640				//  CHANGED: pass the actual link as the trigger
641				link.addEventListener('click', function (e) {
642					e.preventDefault();
643					openModal(link); // was openModal(link.href)
644				});
645
646				//  CHANGED: nested clickable children also pass the link as trigger
647				link.querySelectorAll("button, img").forEach(element => {
648					element.addEventListener("click", function (e) {
649						e.preventDefault();
650						openModal(link); // was openModal(link.href)
651					});
652				});
653
654				// ARIA hint that this opens a dialog
655				if (!link.hasAttribute("aria-haspopup")) {
656					link.setAttribute("aria-haspopup", "dialog");
657				}
658			});
659		}
660
661		modal.style.display = "none";
662		modal.setAttribute("aria-hidden", "true");
663
664		setupExternalLinks();
665
666		window.addEventListener('pageshow', (event) => {
667			if (event.persisted && popupShownInSession) {
668				modal.style.display = "none";
669				modal.setAttribute("aria-hidden", "true");
670			}
671		});
672
673		window.addEventListener('beforeunload', () => {
674			sessionStorage.removeItem('externalPopupShown');
675		});
676	});
677</script>
677
678
679<!-- Automatically sets aria label for phone, email, directions icons -->
680<script>
681    const iconGlyphMap = {
682        '\uE0CD': 'Phone',
683        '\uE0BE': 'Email',
684        '\uE52E': 'Get directions'
685    };
686
687    document.querySelectorAll('.material-icons').forEach(icon => {
688        const glyph = icon.textContent.trim();
689        if (iconGlyphMap[glyph]) {
690            icon.setAttribute('aria-label', iconGlyphMap[glyph]);
691            icon.setAttribute('role', 'img');
692        }
693    });
694</script>
694
695</body>
696
697
698
699<!-- Siteimprove Analytics Code -->
700<script async src="https://siteimproveanalytics.com/js/siteanalyze_10984.js"></script>
700
701
702
703
704</body>
705</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.