a11y: skip-to-content link (0.72.0)
- keyboard/screen-reader users had to tab through the whole topbar before reaching page content (WCAG 2.4.1 Bypass Blocks gap) - add a skip link as the first focusable element: hidden until focused, slides in as a cyan pill, and on activation focuses the visible content container (works with the persistent-home structure, and avoids the hash-route conflict by focusing programmatically instead of via href) - verified live: Tab focuses it, it becomes visible, activation focuses content
This commit is contained in:
parent
696d727e44
commit
0f9d553deb
@ -4,7 +4,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="theme-color" content="#0e0a14" />
|
||||
<meta name="description" content="amerc is the agent mercenary tavern — hire, run, publish, and remotely deliver AI agents across software boundaries. No infrastructure, just skills." />
|
||||
<meta name="version" content="0.71.0-titles" />
|
||||
<meta name="version" content="0.72.0-skiplink" />
|
||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="icon" href="/app-192.png" type="image/png" sizes="192x192" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "amerc-site",
|
||||
"version": "0.71.0-titles",
|
||||
"version": "0.72.0-skiplink",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@ -7,7 +7,7 @@ import Account from './Account.jsx';
|
||||
import TavernGame from './TavernGame.jsx';
|
||||
import { api } from './api.js';
|
||||
|
||||
const RELEASE = '0.71.0-titles';
|
||||
const RELEASE = '0.72.0-skiplink';
|
||||
|
||||
const NAV = [
|
||||
{ id: 'home', label: 'Tavern' },
|
||||
@ -457,8 +457,14 @@ export default function Scene2DApp() {
|
||||
const auth = useAuth();
|
||||
const isHome = route === 'home';
|
||||
useEffect(() => { document.title = ROUTE_TITLES[route] || 'amerc'; }, [route]);
|
||||
const skipToContent = (e) => {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector('.route-enter') || document.querySelector('.route-host');
|
||||
if (target) { target.setAttribute('tabindex', '-1'); target.focus(); }
|
||||
};
|
||||
return (
|
||||
<main className="px-app td-app">
|
||||
<a className="skip-link" href="#content" onClick={skipToContent}>Skip to content</a>
|
||||
<h1 className="sr-only">amerc agent mercenary tavern</h1>
|
||||
<PixelTopbar route={route} setRoute={setRoute} auth={auth} />
|
||||
{/* Home stays mounted (hidden off-route) so returning to the tavern is instant —
|
||||
|
||||
@ -1468,3 +1468,9 @@ button {
|
||||
.ap-gate-rich h2 { font-family: Georgia, "Times New Roman", serif; font-size: 24px; color: #fff; margin: 0 0 10px; }
|
||||
.ap-gate-rich p { color: #b6a7d4; font-size: 14px; line-height: 1.65; margin: 0 0 22px; }
|
||||
.ap-gate-cta { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
|
||||
|
||||
/* skip-to-content link — visible only on keyboard focus (a11y, 0.72) */
|
||||
.skip-link { position: fixed; top: 10px; left: 10px; z-index: 100; background: var(--cyan); color: #06222f;
|
||||
font-family: Georgia, "Times New Roman", serif; font-weight: 600; font-size: 14px; padding: 9px 16px; border-radius: 9px;
|
||||
box-shadow: 0 6px 18px rgba(0,0,0,0.4); text-decoration: none; transform: translateY(-160%); transition: transform .16s ease-out; }
|
||||
.skip-link:focus, .skip-link:focus-visible { transform: none; outline: 2px solid #fff; outline-offset: 2px; }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user