Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion _includes/connect.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="alert alert-info small mt-5" role="alert">
<h2 class="h4 mb-3">Connect with ScanGov</h2>
<nav aria-label="Social media links" class="social fs-4">
<ul class="list-unstyled d-flex gap-1 mb-0">
<ul class="list-unstyled d-flex flex-wrap gap-1 mb-0">
<li><a href="https://scangov.com/plans" aria-label="View ScanGov plans"><i class="fa-solid fa-crown"></i></a></li>
{% if site.substack %}<li><a href="{{ site.substack }}" aria-label="Subscribe to ScanGov on Substack" target="_blank" rel="noopener"><i class="fa-solid fa-envelope-open-text"></i></a></li>{% endif %}
{% if site.linkedin %}<li><a href="{{ site.linkedin }}" aria-label="Follow ScanGov on LinkedIn" target="_blank" rel="noopener"><i class="fa-brands fa-linkedin"></i></a></li>{% endif %}
Expand Down
131 changes: 131 additions & 0 deletions _includes/cta.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<style>
.cta-band {
position: fixed;
right: 0;
bottom: 0;
left: 0;
z-index: 1030;
padding: 0.75rem 0;
background-color: var(--bs-body-bg);
color: var(--bs-body-color);
transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s ease;
}

/* Hidden while the hero or the footer is on screen */
.cta-band.is-hidden {
opacity: 0;
visibility: hidden;
transform: translateY(100%);
pointer-events: none;
}

.cta-band .btn {
margin-top: 0;
margin-bottom: 0;
}

/* The crown has its own icon color rules (gold in dark mode, body color in
light mode); inside the primary button it should match the button text,
like the rocket in the hero */
.cta-band .btn.btn-primary svg.fa-crown,
.cta-band .btn.btn-primary i.fa-crown {
color: inherit !important;
fill: currentColor !important;
}

/* Some icons (the link icon, for one) keep a fixed color on hover in light
mode; inside the outline buttons they should follow the button text */
.cta-band .btn.btn-outline-primary:hover svg,
.cta-band .btn.btn-outline-primary:focus svg,
.cta-band .btn.btn-outline-primary:hover i,
.cta-band .btn.btn-outline-primary:focus i {
color: inherit !important;
fill: currentColor !important;
}
</style>
<div id="cta-band" class="cta-band border-top" role="region" aria-label="Get ScanGov, see the demo, and share this page">
<div class="container d-flex align-items-center justify-content-center gap-2">
<a href="https://scangov.com/plans/" class="btn btn-primary" aria-label="Plans">
<i class="fa-solid fa-crown" aria-hidden="true"></i><span class="d-none d-md-inline ms-2">Plans</span></a>
<a href="https://scangov.com/demo/" class="btn btn-outline-primary" aria-label="Demo">
<i class="fa-solid fa-wand-magic-sparkles" aria-hidden="true"></i><span class="d-none d-md-inline ms-2">Demo</span></a>
<button type="button" class="btn btn-outline-primary" id="cta-copy-link" aria-label="Copy link">
<i class="fa-solid fa-link" aria-hidden="true"></i><i class="fa-solid fa-check d-none" aria-hidden="true"></i><span class="d-none d-md-inline ms-2">Link</span></button>
<button type="button" class="btn btn-outline-primary" id="cta-copy-text" aria-label="Copy text">
<i class="fa-solid fa-copy" aria-hidden="true"></i><i class="fa-solid fa-check d-none" aria-hidden="true"></i><span class="d-none d-md-inline ms-2">Text</span></button>
<span class="visually-hidden" role="status" aria-live="polite" id="cta-copy-status"></span>
</div>
</div>
<script>
(function() {
var status = document.getElementById('cta-copy-status');

// The page link: the canonical link if there is one, else this URL without
// the query string or hash
function pageLink() {
var canonical = document.querySelector('link[rel="canonical"]');
return canonical && canonical.href ? canonical.href : location.origin + location.pathname;
}

// Title, description, and link, ready to paste into email, Teams, Slack, or a post
function pageText() {
var h1 = document.querySelector('h1');
var description = document.querySelector('meta[name="description"]');
return [
h1 ? h1.textContent.trim().replace(/\s+/g, ' ') : document.title,
description ? description.content.trim() : '',
pageLink()
].filter(Boolean).join('\n');
}

function wire(buttonId, getText, doneMessage) {
var button = document.getElementById(buttonId);
if (!button) return;
button.addEventListener('click', async function() {
// Icons are swapped for inline SVGs at build time, so show the hidden
// check mark instead of changing the icon's class
var icons = button.querySelectorAll('svg, i');
var label = button.querySelector('span');
var labelText = label.textContent;
try {
await navigator.clipboard.writeText(getText());
icons[0].classList.add('d-none');
icons[1].classList.remove('d-none');
label.textContent = 'Copied';
status.textContent = doneMessage;
setTimeout(function() {
icons[0].classList.remove('d-none');
icons[1].classList.add('d-none');
label.textContent = labelText;
status.textContent = '';
}, 2000);
} catch (err) {
// Clipboard unavailable: leave the button as it is
}
});
}

// Show the band only between the hero and the footer. This script sits above
// the footer in the page, so wait until the whole page is parsed.
function watchHeroAndFooter() {
var band = document.getElementById('cta-band');
var h1 = document.querySelector('h1');
var targets = [h1 ? (h1.closest('.pt-5') || h1) : null, document.querySelector('footer')].filter(Boolean);
if (!band || !targets.length || !('IntersectionObserver' in window)) return;
var inView = new Map();
var observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) { inView.set(entry.target, entry.isIntersecting); });
band.classList.toggle('is-hidden', Array.from(inView.values()).some(Boolean));
});
targets.forEach(function(target) { observer.observe(target); });
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', watchHeroAndFooter);
} else {
watchHeroAndFooter();
}

wire('cta-copy-link', pageLink, 'Link copied');
wire('cta-copy-text', pageText, 'Text copied');
})();
</script>
2 changes: 1 addition & 1 deletion _includes/details.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
{% if site.url == 'https://scangov.org' %}
<li>
Last scan:
<span id="updated">{{ updates }}</span>
<span id="updated">{% if domain.time %}{{ domain.time | standardFormatDate }}{% else %}{{ updates }}{% endif %}</span>
{% set infoHref = "https://docs.scangov.org/scans/" %}
{% set infoLabel = "Last scan" %}
{% set infoDescription = "How often ScanGov scans this site." %}
Expand Down
17 changes: 14 additions & 3 deletions _includes/feedback.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,28 @@
const feedbackButton = document.getElementById("feedback-button");
const footer = document.querySelector("footer");

// The fixed CTA band already carries the Get started button
const ctaBand = document.getElementById('cta-band');
function updateButton() {
const scrolled = document.documentElement.scrollTop > window.innerHeight * 0.3;
const footerVisible = footer && footer.getBoundingClientRect().top < window.innerHeight;
const visible = scrolled && !footerVisible;
const visible = scrolled && !footerVisible && !ctaBand;
feedbackButton.classList.toggle('is-visible', visible);
feedbackButton.setAttribute('aria-hidden', visible ? 'false' : 'true');
feedbackButton.setAttribute('tabindex', visible ? '0' : '-1');
}

if (window.location.hostname !== 'my.scangov.com') {
window.addEventListener('scroll', updateButton);
const hiddenPaths = ['/plans/', '/demo/', '/demo-confirm/', '/contact/'];
if (window.location.hostname !== 'my.scangov.com' && !hiddenPaths.includes(window.location.pathname)) {
let ticking = false;
window.addEventListener('scroll', function() {
if (ticking) return;
ticking = true;
requestAnimationFrame(function() {
updateButton();
ticking = false;
});
}, { passive: true });
updateButton();
}
</script>
1 change: 1 addition & 0 deletions _includes/footer.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{% if page.url != "/plans/" and page.url != "/demo/" and page.url != "/demo-confirm/" and page.url != "/contact/" %}{% include "cta.html" %}{% endif %}
<footer role="contentinfo">
{% if footer %}
<div class="container mt-5 pt-5 border-top">
Expand Down
6 changes: 3 additions & 3 deletions _includes/nav.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
] %}
{% set topnavUrls = ["https://scangov.com", "https://standards.scangov.org", "https://scangov.org", "https://docs.scangov.org", "https://data.scangov.org"] %}
{% if site.url in topnavUrls %}
<div class="d-none d-md-block">
<nav class="d-none d-md-block" aria-label="ScanGov sites">
<div class="d-flex justify-content-end border-bottom pt-1 pb-0">
<ul class="nav nav-tabs topnav small mb-0">
{% for item in topnav %}
Expand All @@ -20,9 +20,9 @@
{% endfor %}
</ul>
</div>
</div>
</nav>
{% endif %}
<nav class="navbar navbar-expand-md border-bottom">
<nav class="navbar navbar-expand-md border-bottom" aria-label="Main">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<svg
Expand Down
30 changes: 30 additions & 0 deletions public/css/scangov.css
Original file line number Diff line number Diff line change
Expand Up @@ -2678,6 +2678,10 @@ td a:hover .fa-circle-info {
color: #7efbe1;
}

.fa-rotate-left {
color: #7efbe1;
}

.fa-face-frown {
color: #fbbaa7;
}
Expand Down Expand Up @@ -2820,7 +2824,10 @@ a .fa-up-right-from-square {
[data-bs-theme=light] .fa-circle-nodes:not([class*="text-"]),
[data-bs-theme=light] .fa-scale-balanced:not([class*="text-"]),
[data-bs-theme=light] .fa-link:not([class*="text-"]),
[data-bs-theme=light] .fa-wand-magic-sparkles:not([class*="text-"]),
[data-bs-theme=light] .fa-window-maximize:not([class*="text-"]),
[data-bs-theme=light] .fa-copy:not([class*="text-"]),
[data-bs-theme=light] .fa-rotate-left:not([class*="text-"]),
[data-bs-theme=light] .fa-link-slash:not([class*="text-"]),
[data-bs-theme=light] .fa-concierge-bell:not([class*="text-"]),
[data-bs-theme=light] .fa-table:not([class*="text-"]),
Expand Down Expand Up @@ -2878,6 +2885,16 @@ a .fa-up-right-from-square {
fill: var(--bs-body-color) !important;
}

/* Icons inside a button follow the button's own text color when its background
changes (hover, focus, press). Without this the blanket light-mode icon rule above
keeps them body-colored, so they turn dark on a dark hover background. */
[data-bs-theme=light] .btn:hover .fa-solid:not([class*="text-"]),
[data-bs-theme=light] .btn:focus-visible .fa-solid:not([class*="text-"]),
[data-bs-theme=light] .btn:active .fa-solid:not([class*="text-"]) {
color: var(--bs-btn-hover-color) !important;
fill: var(--bs-btn-hover-color) !important;
}

/* Status cards keep their own text color for icons in light mode too: the blanket
light-mode icon rule above would otherwise turn an info icon black on a red card.
The anchor selectors out-rank the "a:not(.btn):not(.active) .fa-solid" light-mode rule. */
Expand Down Expand Up @@ -3455,6 +3472,7 @@ body[data-bs-theme='dark'] ul.navbar-nav img {
.card-footer {
color: inherit !important;
font-family: var(--bs-font-monospace);
text-align: start;
}

a.cardlink {
Expand Down Expand Up @@ -4102,6 +4120,18 @@ blockquote .lead {
.sg-map-county--pass {
fill: color-mix(in oklab, var(--sg-chart-muted) 30%, var(--bs-body-bg));
}
/* A page's most severe stage (scripts/issues.js `stages`, tone 'severe'). */
.sg-map-issue--severe path {
fill: var(--bs-danger);
}
/* A passing county the page still flags (item.mark): the issue accent at a
tint, so it reads as related to the highlighted set but lesser. */
.sg-map-county--marked {
fill: color-mix(in oklab, var(--sg-chart-series-1) 40%, var(--bs-body-bg));
}
.sg-swatch--marked {
background: color-mix(in oklab, var(--sg-chart-series-1) 40%, var(--bs-body-bg));
}
.sg-map-county--unscanned {
fill: var(--bs-inaccessible);
}
Expand Down
30 changes: 30 additions & 0 deletions scripts/bundle.css
Original file line number Diff line number Diff line change
Expand Up @@ -2893,6 +2893,10 @@ td a:hover .fa-circle-info {
color: #7efbe1;
}

.fa-rotate-left {
color: #7efbe1;
}

.fa-face-frown {
color: #fbbaa7;
}
Expand Down Expand Up @@ -3035,7 +3039,10 @@ a .fa-up-right-from-square {
[data-bs-theme=light] .fa-circle-nodes:not([class*="text-"]),
[data-bs-theme=light] .fa-scale-balanced:not([class*="text-"]),
[data-bs-theme=light] .fa-link:not([class*="text-"]),
[data-bs-theme=light] .fa-wand-magic-sparkles:not([class*="text-"]),
[data-bs-theme=light] .fa-window-maximize:not([class*="text-"]),
[data-bs-theme=light] .fa-copy:not([class*="text-"]),
[data-bs-theme=light] .fa-rotate-left:not([class*="text-"]),
[data-bs-theme=light] .fa-link-slash:not([class*="text-"]),
[data-bs-theme=light] .fa-concierge-bell:not([class*="text-"]),
[data-bs-theme=light] .fa-table:not([class*="text-"]),
Expand Down Expand Up @@ -3093,6 +3100,16 @@ a .fa-up-right-from-square {
fill: var(--bs-body-color) !important;
}

/* Icons inside a button follow the button's own text color when its background
changes (hover, focus, press). Without this the blanket light-mode icon rule above
keeps them body-colored, so they turn dark on a dark hover background. */
[data-bs-theme=light] .btn:hover .fa-solid:not([class*="text-"]),
[data-bs-theme=light] .btn:focus-visible .fa-solid:not([class*="text-"]),
[data-bs-theme=light] .btn:active .fa-solid:not([class*="text-"]) {
color: var(--bs-btn-hover-color) !important;
fill: var(--bs-btn-hover-color) !important;
}

/* Status cards keep their own text color for icons in light mode too: the blanket
light-mode icon rule above would otherwise turn an info icon black on a red card.
The anchor selectors out-rank the "a:not(.btn):not(.active) .fa-solid" light-mode rule. */
Expand Down Expand Up @@ -3670,6 +3687,7 @@ body[data-bs-theme='dark'] ul.navbar-nav img {
.card-footer {
color: inherit !important;
font-family: var(--bs-font-monospace);
text-align: start;
}

a.cardlink {
Expand Down Expand Up @@ -4317,6 +4335,18 @@ blockquote .lead {
.sg-map-county--pass {
fill: color-mix(in oklab, var(--sg-chart-muted) 30%, var(--bs-body-bg));
}
/* A page's most severe stage (scripts/issues.js `stages`, tone 'severe'). */
.sg-map-issue--severe path {
fill: var(--bs-danger);
}
/* A passing county the page still flags (item.mark): the issue accent at a
tint, so it reads as related to the highlighted set but lesser. */
.sg-map-county--marked {
fill: color-mix(in oklab, var(--sg-chart-series-1) 40%, var(--bs-body-bg));
}
.sg-swatch--marked {
background: color-mix(in oklab, var(--sg-chart-series-1) 40%, var(--bs-body-bg));
}
.sg-map-county--unscanned {
fill: var(--bs-inaccessible);
}
Expand Down
Loading