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: 2 additions & 0 deletions .github/workflows/deploy-site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ jobs:
needs: deploy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Lighthouse audit
uses: treosh/lighthouse-ci-action@2f8dda6cf4de7d73b29853c3f29e73a01e297bd8 # v12.1.0
with:
Expand Down
5 changes: 4 additions & 1 deletion apps/web/src/components/DiffViewer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,10 @@
<!-- Change history -->
<h3 class="mb-2 text-base font-semibold text-gray-800 dark:text-gray-200">Change History</h3>
{#if commits.length === 0}
<p class="text-gray-500">No history yet for this section.</p>
<div class="rounded-lg bg-warm-gray p-4 text-center text-[13px] leading-relaxed text-gray-500 dark:bg-gray-800/50 dark:text-gray-400">
<p>No amendments tracked yet for this section.</p>
<p class="mt-1 text-[11px]">Change history will appear here automatically when the pipeline detects modifications between US Code release points.</p>
</div>
{:else}
{#if tags.length === 0}
<p class="mb-3 rounded bg-teal/10 p-2 text-xs text-teal-700 dark:text-teal-300">Version timeline available when release point tags are published.</p>
Expand Down
21 changes: 21 additions & 0 deletions apps/web/src/pages/404.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
import BaseLayout from '../layouts/BaseLayout.astro';
const base = import.meta.env.BASE_URL;
---

<BaseLayout title="Page not found">
<div class="not-prose mx-auto max-w-md py-16 text-center font-sans">
<h1 class="mb-3 text-2xl font-medium text-navy dark:text-amber">Section not found</h1>
<p class="mb-6 text-gray-500 leading-relaxed">
The section you're looking for may have been renumbered, repealed,
or the URL may be incorrect.
</p>
<a
href={`${base}browse/`}
class="inline-block rounded-lg bg-navy px-5 py-2.5 text-sm font-medium text-white transition-colors hover:bg-navy-dark dark:bg-teal dark:hover:bg-teal/80"
>
Browse all titles &rarr;
</a>
<p class="mt-8 text-sm text-gray-400">Or use the search bar above to find what you need.</p>
</div>
</BaseLayout>
50 changes: 49 additions & 1 deletion apps/web/src/pages/statute/[...slug].astro
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,23 @@ const readingTimeMin = Math.max(1, Math.round(wordCount / 200));

<BaseLayout
title={entry.data.title}
description={`${classification} - current through ${current_through}`}
description={`Full text of ${classification} with change history. Current through ${current_through}.`}
>
<!-- Schema.org Legislation structured data -->
<script type="application/ld+json" set:html={JSON.stringify({
"@context": "https://schema.org",
"@type": "Legislation",
"name": classification,
"headline": entry.data.title.replace(/^Section \S+ - /, ''),
"legislationIdentifier": classification,
"legislationJurisdiction": "US",
"legislationLegalForce": status === 'repealed' ? 'NotInForce' : 'InForce',
"isPartOf": { "@type": "Legislation", "name": "United States Code", "legislationIdentifier": "USC" },
"url": `https://civic-source.github.io${base}statute/${entry.id}/`,
"dateModified": generated_at?.split('T')[0] ?? "2026-03-30",
"publisher": { "@type": "Organization", "name": "Office of the Law Revision Counsel", "url": "https://uscode.house.gov/" }
})} />

<!-- Breadcrumbs -->
<Breadcrumbs items={[
{ label: 'Home', href: base },
Expand Down Expand Up @@ -155,6 +170,14 @@ const readingTimeMin = Math.max(1, Math.round(wordCount / 200));
>
Print
</button>
<button
class="rounded bg-gray-100 px-2 py-1 text-gray-600 hover:bg-gray-200 transition-colors dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700"
aria-label="Copy citation to clipboard"
data-citation={classification}
onclick="navigator.clipboard.writeText(this.dataset.citation).then(()=>{this.textContent='Copied!';setTimeout(()=>this.textContent='Copy cite',2000)}).catch(()=>{})"
>
Copy cite
</button>
</div>
</div>

Expand Down Expand Up @@ -382,4 +405,29 @@ const readingTimeMin = Math.max(1, Math.round(wordCount / 200));
});
})();
</script>

<!-- Keyboard shortcuts: j/k navigate sections -->
<script is:inline>
document.addEventListener('keydown', function (e) {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
var nav = document.querySelector('nav[aria-label="Section navigation"]');
if (!nav) return;
var links = nav.querySelectorAll('a');
if (e.key === 'k' || (e.key === 'ArrowLeft' && !e.metaKey)) {
if (links[0]) window.location.href = links[0].href;
} else if (e.key === 'j' || (e.key === 'ArrowRight' && !e.metaKey)) {
if (links[1]) window.location.href = links[1].href;
else if (links[0] && links.length === 1) window.location.href = links[0].href;
}
});
</script>

<!-- Keyboard hints (desktop only) -->
<div class="not-prose mt-4 text-center text-[11px] text-gray-300 dark:text-gray-700 hidden lg:block" aria-hidden="true">
<kbd class="rounded border border-gray-200 bg-gray-50 px-1.5 py-0.5 font-mono text-[10px] dark:border-gray-700 dark:bg-gray-800">j</kbd>
<kbd class="rounded border border-gray-200 bg-gray-50 px-1.5 py-0.5 font-mono text-[10px] dark:border-gray-700 dark:bg-gray-800">k</kbd>
navigate sections
<kbd class="ml-2 rounded border border-gray-200 bg-gray-50 px-1.5 py-0.5 font-mono text-[10px] dark:border-gray-700 dark:bg-gray-800">/</kbd>
search
</div>
</BaseLayout>
Loading