html · chain · relay · step 017 of 64
offline render, Chrome 154, light scheme, 2 s of virtual time
runs in a sandboxed frame with no origin; live pages may fetch CDN fonts the offline render did not
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<meta http-equiv="content-security-policy" content="default-src 'none'; style-src 'sha256-hIEOEpfCkDEw8qKQu1eJQs8N5ajxwvYGPkPU6qpyQnA='; img-src data:; base-uri 'none'; form-action 'none'">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="description" content="A well-structured, accessible HTML5 document with modern best practices.">
<meta name="color-scheme" content="light dark">
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#121212" media="(prefers-color-scheme: dark)">
<meta name="author" content="ksmith@centricle.com">
<title>Welcome</title>
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='.9em' font-size='90'%3E👋%3C/text%3E%3C/svg%3E">
<link rel="canonical" href="https://example.com/">
<meta property="og:type" content="website">
<meta property="og:title" content="Welcome">
<meta property="og:description" content="A well-structured, accessible HTML5 document with modern best practices.">
<meta property="og:url" content="https://example.com/">
<meta property="og:image" content="https://example.com/og-image.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:locale" content="en_US">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Welcome">
<meta name="twitter:description" content="A well-structured, accessible HTML5 document with modern best practices.">
<meta name="twitter:image" content="https://example.com/og-image.png">
<style>
:root {
color-scheme: light dark;
--text: #1a1a1a;
--text-secondary: #555;
--background: #fff;
--accent: #0052a3;
--border: #e0e0e0;
}
@media (prefers-color-scheme: dark) {
:root {
--text: #e0e0e0;
--text-secondary: #a0a0a0;
--background: #121212;
--accent: #5fa3ff;
--border: #333;
}
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
}
@media (prefers-reduced-motion: no-preference) {
html {
scroll-behavior: smooth;
}
a {
transition: text-decoration-thickness 0.15s ease;
}
.skip-link {
transition: transform 0.15s ease;
}
}
body {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
min-height: 100dvh;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
font-size: 1rem;
line-height: 1.6;
max-width: 70ch;
margin: 0 auto;
padding: clamp(1rem, 5vw, 1.5rem);
padding-top: max(clamp(1rem, 5vw, 1.5rem), env(safe-area-inset-top));
padding-right: max(clamp(1rem, 5vw, 1.5rem), env(safe-area-inset-right));
padding-bottom: max(clamp(1rem, 5vw, 1.5rem), env(safe-area-inset-bottom));
padding-left: max(clamp(1rem, 5vw, 1.5rem), env(safe-area-inset-left));
color: var(--text);
background: var(--background);
}
h1 {
color: var(--accent);
font-size: clamp(1.75rem, 1.25rem + 3vw, 2.5rem);
font-weight: 700;
line-height: 1.1;
text-wrap: balance;
margin: 0 0 1.5rem 0;
letter-spacing: -0.02em;
}
p {
text-wrap: pretty;
margin: 1rem 0;
}
a {
color: var(--accent);
text-underline-offset: 0.2em;
text-decoration-thickness: 2px;
text-decoration-skip-ink: auto;
font-weight: 500;
}
a:hover, a:active {
text-decoration-thickness: 3px;
}
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
border-radius: 2px;
}
button:focus-visible, a:focus-visible {
box-shadow: 0 0 0 3px var(--background), 0 0 0 5px var(--accent);
outline: none;
}
.skip-link {
position: absolute;
left: 0;
top: 0;
transform: translateY(-100%);
background: var(--accent);
color: var(--background);
padding: 0.75rem 1.5rem;
z-index: 1000;
border-radius: 0 0 0.25rem 0;
font-weight: 600;
text-decoration: none;
display: inline-block;
}
.skip-link:focus {
transform: none;
outline: 3px solid var(--text);
outline-offset: -3px;
}
header {
padding-block: 1.5rem 0;
}
main {
padding: 1rem 0;
}
main:focus {
outline: none;
}
footer {
padding-block: 1.5rem;
margin-top: 3rem;
border-top: 1px solid var(--border);
font-size: 0.875rem;
color: var(--text-secondary);
text-align: center;
}
footer p {
margin: 0.5rem 0;
}
@media print {
.skip-link {
display: none;
}
body {
display: block;
min-height: 0;
max-width: none;
padding: 0;
}
a {
color: inherit;
text-decoration: underline;
}
a[href^="http"]::after {
content: " (" attr(href) ")";
font-size: 0.85em;
font-weight: normal;
}
}
</style>
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<header>
<h1>Welcome</h1>
</header>
<main id="main" tabindex="-1">
<p>This is a well-structured, accessible HTML5 document.</p>
<p>
It uses semantic landmarks, a skip link for keyboard navigation,
and CSS that adapts to your light or dark mode preference.
</p>
<p>
Text and link colors meet WCAG AA contrast in both themes, type scales
with your browser's font size, and motion respects your system settings.
</p>
</main>
<footer>
<p><small>© <time datetime="2026">2026</time>. All rights reserved.</small></p>
</footer>
</body>
</html>
what changed from step 016
+1 / -4 lines
<meta name="theme-color" content="#121212" media="(prefers-color-scheme: dark)"> <meta name="author" content="ksmith@centricle.com">- <meta name="robots" content="index, follow">- <meta name="language" content="English">- <meta name="revisit-after" content="7 days"> <title>Welcome</title> <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='.9em' font-size='90'%3E👋%3C/text%3E%3C/svg%3E">⋯ line 175 </head> <body>- <a class="skip-link" href="#main" aria-label="Skip to main content">Skip to content</a>+ <a class="skip-link" href="#main">Skip to content</a> <header> <h1>Welcome</h1>
What the model said
I made two small markup fixes to `0.html` and left the CSS untouched, because the file was already in good shape and I couldn't safely change the stylesheet.
## What I changed
- **Skip link label** (`0.html:177`): removed `aria-label="Skip to main content"`. It overrode the visible text "Skip to content" with a different name, which breaks voice control (WCAG 2.5.3 Label in Name).
- **Obsolete meta tags**: removed `robots` (`index, follow` is already the default), `language` and `revisit-after` (non-standard, and search engines ignore them).
## Why the CSS is untouched
The Content Security Policy only allows the inline `<style>` block if it matches a SHA-256 hash, so any edit to the CSS, even whitespace, makes the browser block the whole stylesheet unless the hash is regenerated. The command I tried for computing the hash was denied in this session, so I could not update it. I also couldn't confirm that the existing hash matches the current stylesheet, so check that the page renders styled.
## CSS changes worth making when you can regenerate the hash
| Location | Issue | Fix |
|---|---|---|
| `0.html:111-114` | `a:focus-visible` sets `outline: none` and uses `box-shadow` for the focus ring. Box shadows are dropped in Windows High Contrast mode, so keyboard focus becomes invisible there. | Delete the rule; the generic `:focus-visible` outline above it already covers this. |
| `0.html:75-79` | The `padding` shorthand is immediately overridden by the four longhand declarations. | Remove the shorthand, or put the `clamp()` in a custom property. |
| `0.html:193` | `<small>` inside a footer already set to `0.875rem` renders at about 11.6px. | Add `footer small { font-size: inherit; }` or drop the `<small>`. |
To regenerate the hash after editing the CSS:
```sh
python3 -c "import re,hashlib,base64;s=open('0.html',encoding='utf-8').read();print('sha256-'+base64.b64encode(hashlib.sha256(re.search(r'<style>(.*?)</style>',s,re.S).group(1).encode()).digest()).decode())"
```
## Things for you to check
- **Placeholder URLs**: `canonical`, `og:url`, `og:image` and `twitter:image` all point to `example.com`. These need real values before publishing.
- **Email in the author tag**: `<meta name="author">` contains your email address, which scrapers can harvest. A name is the usual choice there.