A full, self-assessed run through specification.website's technical checklist for what a good website does: every one of its 172 items, checked against this site.
What is specification.website?
specification.website is an open, community-maintained checklist of the technical details that make a good website:
things like a correct <title> tag, working search-engine discovery, color
contrast, security headers, and how legible a site is to the AI agents more people now use to
find things. Each of its 172 items links back to the actual standard behind it, a WHATWG or
W3C specification, an IETF RFC, or WCAG, rather than someone's opinion of best practice.
Most of these items are invisible to a visitor scrolling the page, but they're exactly what
decides whether this site loads fast, works for people with disabilities, keeps visitor data
private, and gets read correctly by both search engines and AI tools. The kevinyoung.net
website is checked against this exact checklist. This page is the result: every item, one
row each, with an honest status.
How this page is scored
specification.website tags every item Required, Recommended, Optional, or Avoid (shown as
the small badge next to each item's name), and this page weights the score to match: a
pass is worth 3 points on a Required or Avoid item, 2 on a Recommended one, and 1 on an
Optional one, since a missing <title> tag matters a lot more than missing
IndexNow support. A partial is worth half of whatever that item's pass is worth, and a fail
is always 0, regardless of tier. Items that don't apply to a site like this one (an OAuth
item on a site with no logins, say) are left out of the score entirely rather than counted
against it. Add up the points earned, divide by the points possible for the items that
actually applied, and that's the percentage at the bottom of the table.
Worth being skeptical of: this audit was done by Claude, the AI assistant that
built most of this site, using its own knowledge of the codebase plus live checks against the
published site. It is not an independent, third-party audit, and a person has not re-verified
every row by hand. Read it as a detailed, honest self-assessment, not a certification.
Status key
PassPass: fully meets the item.
PartialPartial: some of it is done, or done a different way than the spec describes.
FailFail: applies to this site and isn't done.
Not applicableNot applicable: the item doesn't apply to a site like this one.
85.0%
250 of 294 applicable points across all 172 checklist items
Foundations
35 / 41 (85%)
specification.website checklist results for Foundations
Status
Checklist item
How kevinyoung.net did
Pass
RequiredThe HTML doctype
<!doctype html> is the first line of every prerendered page.
Pass
RequiredThe lang attribute on <html>
html lang is set per language (en, es, pt) and kept in sync during client-side navigation.
Pass
Required<meta charset>
UTF-8 is declared first in <head>, before any other tag.
Pass
Required<meta viewport>
width=device-width, initial-scale=1, and user scaling is never disabled.
Pass
RequiredThe <title> element
Every page gets one unique <title> from Seo.svelte, separate from its <h1>.
Pass
Recommended<meta name="description">
Every page has its own hand-written description, authored as a direct answer to what the page is.
Pass
RecommendedCanonical URL (rel="canonical")
Every page self-canonicalizes, and reposts point their canonical at the original source instead.
Pass
RecommendedFavicons and app icons
Ships an .ico, 16/32px PNGs, an apple-touch-icon, a manifest with both any and maskable icons (see Web app manifest below), and now a 27 KB static/favicon.svg (a low-poly vector trace of the same photo Kevin generated and hand-optimized, further reduced from 105 KB via SVGO), linked before the .ico so SVG-supporting browsers prefer it. A first vectorization attempt was too heavy to ship (827 KB, 1,481 paths tracing full photographic detail); a lower-fidelity re-trace plus lossless SVGO optimization (whitespace, redundant attributes, integer coordinate rounding) got it to a size actually worth serving, confirmed readable down to 32px.
Pass
Recommended<meta name="theme-color">
Set to match --c-page exactly for the active theme: resolved before first paint by the same inline bootstrap script that sets data-theme, and updated live when the reader toggles the theme.
Pass
Recommended<meta name="color-scheme">
Set as a CSS property tied to the dark-mode toggle, so it changes with the theme rather than sitting as a static tag.
Pass
RecommendedOpen Graph protocol
og:title, og:description, og:image, og:url, og:type and og:locale are set on every page, with alternates for the other two languages.
Pass
RecommendedFeed discovery with rel="alternate"
Every page links to the per-language RSS feed with <link rel="alternate" type="application/rss+xml">.
Pass
RecommendedFeed content hygiene
The feed has a self-referencing atom:link, a stable non-permalink guid per item, and a ttl declaring how often it changes. Confirmed valid by the W3C Feed Validator for all three languages.
Fail
RecommendedPopover API
The cookie banner and Display settings panel are hand-built floating panels with manual positioning and ARIA, not the native Popover API the spec recommends for exactly this.
Fail
OptionalWebSub: push notification for feeds
No WebSub hub is advertised for the RSS feed, so subscribers still have to poll for updates rather than being pushed them.
Fail
RecommendedCSS anchor positioning
Panels and menus are positioned with fixed and absolute CSS and manual coordinates, not anchor-name and position-anchor.
Pass
RecommendedBalanced text wrapping
text-wrap: balance applies to every h1, h2 and h3 sitewide, not just the two About page headings that had it before.
Pass
RecommendedCSS container queries
The Work page's brand-card grids size their columns off the grid's own rendered width (container-type: inline-size plus @container) rather than the viewport. Today that behaves the same as the viewport breakpoints it replaced, since the surrounding .frame tracks viewport width almost 1:1; the win is that the grid would keep sizing correctly if it were ever reused somewhere narrower than the viewport, which a media query can't do. The rest of the site's layout still runs on ordinary viewport breakpoints, which remain the right tool for page-level layout.
Fail
OptionalInvoker commands
Buttons that open panels (search, Display settings, the cookie banner) use onclick handlers, not the command/commandfor attributes.
Not applicable
Optional_for-sale DNS records
kevinyoung.net is Kevin's own personal site and is not for sale.
SEO
27 / 27 (100%)
specification.website checklist results for SEO
Status
Checklist item
How kevinyoung.net did
Pass
Recommendedrobots.txt
A plain-text robots.txt at the root allows all crawlers and points to the sitemap.
Pass
RecommendedXML sitemaps
sitemap.xml lists every canonical URL with hreflang alternates, generated fresh on every build.
Not applicable
RecommendedSitemap index files
The sitemap holds 45 URLs, far under the 50,000-URL point where an index file would matter.
Not applicable
OptionalImage and video sitemap extensions
Every image is in plain, server-rendered HTML a crawler can already reach directly; nothing is hidden behind client-side JavaScript or an uncrawlable CDN.
Pass
RecommendedURL structure
URLs are lowercase, hyphenated and shallow (e.g. /writing/never-old-learn), with identical slugs across all three languages.
Pass
RequiredRedirects (301/302/308)
The only redirect-like rule on the site (the /es/ and /pt/ 404 rewrites) returns the correct status, and no redirect chains exist anywhere.
Pass
RecommendedServer-side rendering
The whole site is statically prerendered at build time; every page arrives fully formed in the first response, nothing waits on client-side JavaScript.
Pass
AvoidSoft 404s
An unknown URL returns a real 404 status, confirmed live, not a 200 with a "not found" message.
Pass
RequiredMeta robots and X-Robots-Tag
Public pages index by default; noindex is set explicitly on Search, the 404 pages, and the generated text and Markdown copies.
Pass
RequiredHeading hierarchy
One h1 per page, checked in the accessibility audit, with semantic (not styled-only) headings throughout.
Pass
RecommendedInternal linking
Nav, footer, breadcrumbs and in-content links (brand cards, project links, related posts) all tie pages together.
Pass
RecommendedStructured data (JSON-LD)
Person, WebSite, page-type (WebPage/AboutPage/CollectionPage/BlogPosting) and BreadcrumbList JSON-LD are emitted on every indexable page.
Pass
RecommendedBreadcrumbs
Both halves are covered: a visible breadcrumb trail plus matching BreadcrumbList JSON-LD, the visible half added in this audit.
Pass
OptionalIndexNow
Enabled via Cloudflare's Crawler Hints (Kevin's own dashboard setting, not code in this repo): with traffic proxied through Cloudflare, it automatically pings IndexNow-participating search engines (Bing, Yandex, Naver, Seznam) whenever cached content changes, the same mechanism this item is checking for.
Accessibility
57 / 63 (90%)
specification.website checklist results for Accessibility
Status
Checklist item
How kevinyoung.net did
Pass
RequiredColour contrast
Audited with axe-core across every page, both themes, at desktop width and 375px, as recorded on the Accessibility policy page.
Fail
OptionalAutomatic contrasting colour
Text-on-brand-color pairings are hand-picked (a fixed dark ink color) rather than computed with the CSS contrast-color() function.
Partial
RecommendedForced colours mode
The forced-colors media feature hides decorative shapes and solidifies hairline borders, but this has been reasoned through rather than tested in an actual forced-colors environment.
Pass
RequiredImage alt text
Every img has an alt attribute; a dedicated quality pass found and fixed two weak ones (a post featured image labelled with the post title instead of what the photo shows) and confirmed the rest are genuinely descriptive.
Pass
RequiredForm labels
Every input this codebase controls (the search box) is properly labelled. The Contact and Speaking pages embed Meteor Forms' and Cal.com's own forms in an iframe; their internal labelling is a different origin's markup, not this site's, the same way a linked-to page's accessibility isn't scored as part of this one.
Pass
RequiredKeyboard navigation
A keyboard-only walkthrough (skip link, header controls, mobile menu, search dialog, FAQ disclosure, cookie banner, Display settings panel) found and fixed one real bug: opening Display settings left focus behind on the trigger, so Tab skipped straight past the now-open panel to the next header button instead of into it (it is mounted after Footer, far from its trigger in DOM order). It now moves focus to the panel heading on open, matching the cookie banner's existing pattern.
Pass
RequiredVisible focus indicators
A two-ring :focus-visible outline is defined sitewide, with an optional thicker "enhanced focus" mode.
Pass
RecommendedFocus not obscured
Checked directly at phone width: with the cookie banner or Display settings panel open, several footer links (Cookie settings, the policy links, the text-only-version link) were completely hidden behind the fixed panel with no way to scroll them into view, since the document was already at max scroll. Both panels now measure their own rendered height and reserve that much extra scroll room (and matching scroll-padding-bottom) while open, confirmed against the same links: none end up fully hidden any more, in either panel, and the reserved space disappears again on close.
Pass
RequiredSkip links
A "Skip to main content" link is the first focusable element on every page.
Partial
RecommendedThe inert attribute
The native search dialog gets this for free from showModal(); the custom Display settings and cookie banner panels do not inert the rest of the page, relying on visual layering instead.
Pass
RequiredSemantic HTML and landmarks
header, nav, main and footer are used throughout, confirmed during the axe-core audit.
Pass
RecommendedARIA: first rule of ARIA
Native elements are preferred everywhere; ARIA is added only where nothing native fits, such as the custom panels.
Pass
RequiredDescriptive link text
Links describe their destination ("Read the original," "See all posts in English"); generic "click here" text is not used.
Pass
AvoidEmpty links and buttons
Every icon-only control (search, theme toggle, close buttons) carries an aria-label or visually hidden text.
Not applicable
RequiredAccessible form errors
This site has no form of its own that produces a validation error; the Contact and Speaking page forms are entirely Meteor Forms' and Cal.com's own embedded UI.
Pass
RecommendedStatus messages
Confirmed in SearchPanel.svelte: the result-count text sits in its own role="status" aria-live="polite" element, separate from the results list, so a screen reader announces count changes without the results themselves needing to be re-read.
Not applicable
RecommendedAccessible authentication
There are no accounts or logins anywhere on this site.
Not applicable
RecommendedRedundant entry
There is no multi-step process anywhere on the site that would ask for the same information twice.
Pass
RecommendedConsistent help
Search, Display settings, the theme toggle, and now Cookie settings, all sit in the same header or footer position on every page.
Pass
RequiredDocument and parts language
html lang is always set correctly per language; the site's content does not currently mix languages mid-paragraph.
Pass
RequiredReduced motion
prefers-reduced-motion is respected sitewide, and the site has little decorative animation to begin with.
Pass
AvoidAccessibility overlays
No third-party accessibility widget is used; the Display settings panel is this site's own first-party code, not a bolted-on overlay.
Not applicable
RequiredCaptions and transcripts
The site has no video or audio content.
Pass
RequiredAccessible data tables
Markdown tables get a focusable, scrollable wrapper, scope="col" on every header cell, and an sr-only caption drawn from the heading that introduces the table, all applied automatically by rehype-table-scroll.ts so future tables get them for free.
Pass
RequiredTouch target size
Interactive elements meet the 24 by 24 CSS px minimum sitewide, checked during the layout audit.
Not applicable
RecommendedDragging movements
The one candidate, the Writing carousel, uses native browser scrolling with arrow-button alternatives, not a custom drag gesture, so there is no drag-only interaction to provide an alternative for.
Pass
RecommendedHidden until found
The About page's "Training and courses" disclosure and the Contact page's FAQ accordions are plain native <details>, which auto-expands for find-in-page and fragment navigation on its own (Chrome 97+, Firefox 139+, Safari 26.2) without needing hidden="until-found" (a separate mechanism for hand-hidden, non-<details> content, which this site does not use).
Pass
RecommendedMobile-friendly form inputs
This site's own search input is a plain, correctly-typed text field, the only input this codebase controls. The embedded Meteor Forms and Cal.com forms' input types are a different origin's markup, the same reasoning as Form labels above.
Partial
RecommendedNative interactive elements
button, a, details and a native dialog (search) are used throughout, but the Display settings panel and cookie banner are deliberately custom, non-modal panels rather than native dialog elements.
Fail
RecommendedCSS state and relational selectors
:has(), :user-invalid and :focus-within are not used; this site has very little custom form UI for them to apply to.
Security
32 / 42 (76%)
specification.website checklist results for Security
Status
Checklist item
How kevinyoung.net did
Pass
RequiredHTTPS and TLS
Served over HTTPS everywhere via Cloudflare and Netlify; plain HTTP redirects to HTTPS.
Pass
RequiredHSTS (Strict-Transport-Security)
Sent with a one-year max-age and includeSubDomains, confirmed live, set through the Cloudflare dashboard.
Pass
RecommendedMixed content and upgrade-insecure-requests
Every subresource loads over HTTPS, and the CSP's upgrade-insecure-requests directive is a safety net.
Pass
RecommendedContent Security Policy (CSP)
Confirmed live and working against production: the cal.com booking widget and Meteor Forms iframe both render and function correctly. It needs 'unsafe-inline' for script-src and style-src on this fully static site, and Cloudflare's own auto-injected analytics beacon is (harmlessly) blocked, since it isn't in the allowlist.
Fail
RecommendedReporting API (Reporting-Endpoints)
No Reporting-Endpoints header is set; there is no third-party collector configured yet to receive CSP or COOP violation reports.
Pass
Recommended/.well-known/security.txt
Published with a contact address and an expiry date.
Pass
RequiredX-Content-Type-Options: nosniff
nosniff is sent on every response.
Pass
RequiredClickjacking protection
Both X-Frame-Options: SAMEORIGIN and the modern CSP frame-ancestors 'self' are set.
Fail
RecommendedFetch Metadata request headers
Sec-Fetch-* headers are not read anywhere; this is a static site with no server-side request handler to inspect them.
Cross-Origin-Opener-Policy: same-origin is set; COEP and CORP were deliberately left out, since COEP could break the cal.com and Google Analytics scripts the site depends on.
Pass
RecommendedReferrer-Policy
strict-origin-when-cross-origin is sent on every response.
Pass
RecommendedPermissions-Policy
Camera, microphone and geolocation are all turned off sitewide.
Fail
RecommendedSubresource Integrity (SRI)
Not used for the cal.com embed script or Google Analytics' gtag.js: both are unversioned third-party scripts that change without notice, so a pinned hash would break on their next deploy, not this site's.
Fail
OptionalDigest Fields
Not implemented.
Fail
RecommendedTrusted Types
Not implemented yet, deliberately: it would stack a second, unverified enforcement layer on top of a CSP that itself has not been confirmed working in production.
Pass
AvoidX-XSS-Protection
Correctly not sent; this dead header is left out, and CSP is relied on instead.
This site sets no cookies of its own at all (theme, Display settings and consent state all live in localStorage), so there is nothing here for this codebase to misconfigure. Google Analytics' cookies, loaded only after consent, are Google's to configure.
Not applicable
OptionalClear-Site-Data
There is no login, logout, or other event on this site that would need to wipe a visitor's storage.
Pass
RecommendedDNS CAA records
issue and issuewild records are published for every CA Cloudflare's Universal SSL can use (Let's Encrypt, Google Trust Services, SSL.com, Sectigo), confirmed live; Cloudflare automatically supplemented a couple more (Comodo, DigiCert) on its own.
Pass
OptionalDNSSEC
Enabled in Cloudflare, with the DS record published at the registrar; confirmed live with a valid RRSIG on the signed answer.
Well-Known URIs
5 / 6 (83%)
specification.website checklist results for Well-Known URIs
Status
Checklist item
How kevinyoung.net did
Pass
RecommendedWell-known URIs
/.well-known/ is used correctly, for security.txt and gpc.json.
Not applicable
Optional/.well-known/change-password
The site has no user accounts, so there is no change-password page to point to.
Not applicable
Optional/.well-known/webauthn
The site does not use passkeys.
Not applicable
Optional/.well-known/openid-configuration
This site is not an OpenID Connect identity provider.
Not applicable
Optional/.well-known/oauth-authorization-server
This site does not run an OAuth authorization server.
Not applicable
Optional/.well-known/oauth-protected-resource
This site exposes no OAuth-protected API.
Pass
Optional/.well-known/gpc.json
Declares that Global Privacy Control is recognized and honored.
Pass
Recommended/.well-known/api-catalog
Published per RFC 9727, as a Linkset (RFC 9264) JSON document listing the sitemap, llms.txt, llms-full.txt and RSS feed for every language, plus robots.txt, with a matching Link: rel="api-catalog" response header sitewide.
Not applicable
Optional/.well-known/webfinger
Not a Fediverse-connected site.
Not applicable
Optional/.well-known/apple-app-site-association
There is no companion iOS app.
Not applicable
Optional/.well-known/assetlinks.json
There is no companion Android app.
Not applicable
Optional/.well-known/nodeinfo
Not a federated platform.
Fail
Optional/.well-known/traffic-advice
Not published; a low-stakes, still-provisional signal this site has not opted into either way.
Agent Readiness
20 / 24 (83%)
specification.website checklist results for Agent Readiness
Status
Checklist item
How kevinyoung.net did
Pass
RecommendedAgent readiness (overview)
Stable URLs, JSON-LD, robots controls and several machine-readable endpoints are all in place, making this one of the stronger categories on this site.
Pass
Recommended/llms.txt
Published per language, listing every top-level page, post and brand with a description.
Pass
Optional/llms-full.txt
Published per language, concatenating every page's Markdown into one file.
Pass
RecommendedPer-page Markdown source endpoints
Every page is available as raw Markdown at a matching .md URL, plus a <link rel="alternate" type="text/markdown">.
Pass
Recommendedrobots.txt for AI crawlers
Kevin's stated position: this is a personal-brand site, so being read, cited and trained on by AI is the point, the same way being indexed by a search engine is. robots.txt now names GPTBot, ClaudeBot, Google-Extended, CCBot, PerplexityBot and others explicitly with Allow: /, instead of relying on the silent User-agent: * default.
Pass
OptionalContent Signals in robots.txt
A Content-Signal: search=yes, ai-input=yes, ai-train=yes line on the User-agent: * block matches the same welcoming stance.
Fail
OptionalTDM reservation (TDMRep)
No tdm-reservation header, meta tag, or tdmrep.json is published.
Fail
OptionalWeb Bot Auth: verifiable bot identity
Not implemented; no bot is currently allowed or blocked by signed identity.
Pass
RequiredStable URLs
Slugs are permanent and identical across all three languages; nothing has been renamed or broken since launch.
Pass
RecommendedStructured data for agents
The same JSON-LD used for search engines is available to agents: Person, WebSite, page types, and breadcrumbs.
Pass
RecommendedMachine-readable formats
RSS, llms.txt, llms-full.txt and per-page Markdown are all offered alongside the HTML.
Pass
RecommendedHTTP Link headers for discovery
sitemap.xml, llms.txt and rss.xml are now also advertised via a real HTTP Link response header (netlify.toml), language-matched for the /es/ and /pt/ trees, for agents that check headers without parsing the page body.
Not applicable
OptionalMCP and tool discovery
This is a static content site with nothing queryable or actionable to expose as a tool, and no server to run an MCP endpoint on.
Not applicable
OptionalA2A agent cards
The site has no agentic behaviour of its own for another agent to delegate to.
Not applicable
RecommendedAgent Skills discovery
Checked against Cloudflare's own draft RFC (github.com/cloudflare/agent-skills-discovery-rfc): it defines a /.well-known/agent-skills/index.json listing actual scoped instructions/tools an agent can load. This is a static personal-brand site with no such skill or tool to register, the same reasoning as the na status on MCP and tool discovery and A2A agent cards above; publishing an empty or fabricated index would misrepresent what this site offers.
Pass
OptionalDNS for AI Discovery (DNS-AID)
An _index._agents HTTPS record points at kevinyoung.net with the recommended alpn, port and mandatory parameters, confirmed live and DNSSEC-signed.
Not applicable
OptionalAgentic Resource Discovery (ARD)
There are no MCP servers or A2A agents on this domain to catalog.
Fail
OptionalNLWeb: conversational interface discovery
Not implemented; this static site has no natural-language query endpoint to advertise.
Fail
OptionalWebMCP: browser-native tools for agents
Not implemented; there is no in-page tool yet worth exposing to a browser-resident agent.
Not applicable
OptionalOpen Knowledge Format (OKF) bundle
llms-full.txt already serves the "ingest everything in one fetch" purpose OKF targets, at a fraction of the complexity, for a site this size.
Not applicable
OptionalSchemamap
This is specification.website's own proposed, not-yet-adopted convention with no external standard behind it yet.
Performance
36.5 / 49 (74%)
specification.website checklist results for Performance
Status
Checklist item
How kevinyoung.net did
Partial
RequiredCore Web Vitals (LCP, INP, CLS)
Measured with PageSpeed Insights (Lighthouse 13.5) against production, Sep 28, 2026, before and after fixing the image-delivery gap below. No field data exists either way (Chrome UX Report: "No Data", not enough real-user traffic for a site this size). Before: desktop LCP 1.8s, mobile LCP 4.9s, image-delivery opportunity 2,047 KiB, total page weight flagged at 2.7 MB. After re-optimizing the ten post featured images (AVIF/WebP via <picture>, see the Performance section below): desktop LCP nearly halved to 0.9s, mobile Speed Index dropped from 4.2s to 2.5s, the image-delivery opportunity shrank 79% to 430 KiB (now just the hero portrait and a few already-optimized photos wanting slightly tighter sizing, not a format problem), and the "enormous network payload" warning is gone entirely. Mobile LCP barely moved (4.9s to 4.6s, still over Google's 2.5s "good" threshold) despite those other gains, and mobile Performance only ticked up one point (79 to 80); read as lab-run noise from a single throttled run against a live edge network rather than the fix not working, given how much moved everywhere else. CLS (0.000 to 0.001) and TBT (0ms) stayed excellent throughout, on both form factors. Left as partial, not pass: mobile LCP still misses the "good" bar under worst-case simulated conditions and there's still no field data to say real users fare better.
Pass
RequiredImage optimisation
Every photo ships as AVIF and WebP with a jpg or png fallback. Most carry explicit width and height; the ten post featured images (added later, see the Core Web Vitals note above) don't, since two of their three render contexts force a fixed aspect-ratio box in CSS regardless, and CLS was already 0.000-0.001 before they existed. A responsive srcset (multiple widths for different screens) was deliberately skipped: it would add build complexity for savings a single well-chosen size mostly already captures.
Pass
RecommendedLazy loading images, iframes, and video
loading="lazy" is set on every below-the-fold image; the LCP hero images are correctly left eager.
Pass
RecommendedPreload, prefetch, preconnect
The LCP hero image is preloaded, format-matched to the picture element's first source, and third-party origins that load unconditionally (cal.com, Meteor Forms) are preconnected.
Fail
Optional103 Early Hints
Root cause found: Cloudflare's Early Hints replays a Link header from a cached copy of the page, but this site's HTML is intentionally Cache-Control: max-age=0 (cf-cache-status: DYNAMIC), so Cloudflare has nothing cached to replay it from. The Link header itself is confirmed sent correctly; getting an actual 103 would mean making the HTML edge-cacheable, a bigger caching-strategy tradeoff, not done here.
Pass
RequiredCache-Control headers
Hashed build assets get a one-year immutable cache; HTML gets a short, must-revalidate policy, confirmed live.
Pass
RecommendedVary: the cache key contract
Vary: Accept-Encoding is sent, confirmed live, without over-listing headers that would fragment the cache.
No ETag or Last-Modified header is sent on the live HTML response, so every request re-downloads the full body instead of getting a 304.
Pass
RecommendedNo-Vary-Search response header
No-Vary-Search: params is sent sitewide: every page is static prerendered HTML whose content never changes based on a query string (the search page reads ?q=/§ion= client-side, after load), so caches and BFCache can safely treat any two URLs differing only by query params as the same page.
Pass
RequiredCompression (gzip, brotli, zstd)
Brotli is confirmed live (content-encoding: br).
Partial
RecommendedWeb font loading
Fonts are self-hosted WOFF2 with font-display: swap, but are not preloaded, since the build's content-hashed filenames would need a small script to find them, similar to the existing text-page generator.
Partial
RecommendedCritical CSS and render-blocking resources
Vite and SvelteKit code-split CSS per route automatically, but no manual critical-CSS extraction or inlining has been added on top of that.
Pass
RecommendedScript loading: defer, async, module
Vite emits type="module" for the app bundle; the Google Analytics and cal.com scripts are injected as async.
Pass
RecommendedHTTP/2 and HTTP/3
Confirmed live: HTTP/2 at minimum, with alt-svc advertising HTTP/3.
Pass
AvoidHTTP/1.1 workarounds: sharding, sprites, and bundling
No domain sharding or image sprites are used anywhere.
Pass
RecommendedSpeculation Rules
A sitewide prefetch ruleset (moderate eagerness, same-origin only) was added in this round of work.
Partial
RecommendedResource hints overview
modulepreload (automatic), preconnect and preload are all used; dns-prefetch is deliberately not, since the only remaining un-preconnected third-party origin is consent-gated Google Analytics, and a DNS lookup before consent defeats the point of gating it. Standalone prefetch hints aren't used anywhere.
Fail
OptionalView Transitions
Not implemented; navigation has no cross-document transition animation.
Pass
RecommendedBack/forward cache (BFCache)
No unload or beforeunload handlers exist anywhere in the codebase, and the live site's Cache-Control (public, max-age=0, must-revalidate) does not include no-store, the two most common blockers. The Speaking and Contact pages' third-party iframes (cal.com, Meteor Forms) are outside this codebase's control and were not checked.
Fail
OptionalVisibility-aware rendering
content-visibility and Intersection Observer are not used; the site is small enough that this has not been a rendering bottleneck.
Fail
OptionalCSS containment
Not used anywhere.
Fail
OptionalScroll-driven animations
Not used; the site has very little scroll-tied animation to begin with.
Pass
RecommendedScrollbar gutter
scrollbar-gutter: stable is set on html sitewide, so gaining or losing a scrollbar no longer shifts content.
Pass
RecommendedDynamic viewport units (dvh, svh, lvh)
The remaining full-height and viewport-relative rules (the layout's min-height, the search dialog's margin, the reading ruler's default position) now use dvh instead of plain vh.
Fail
OptionalCompression Dictionary Transport
Not implemented; a newer technique with limited hosting support at this stage.
Not applicable
OptionalServer-Timing header
This is a fully static site with no backend request processing to measure and report on.
Privacy
13 / 14 (93%)
specification.website checklist results for Privacy
Status
Checklist item
How kevinyoung.net did
Pass
RequiredPrivacy policy
A plain-language policy covers what is collected, Google Analytics, the cookie banner, GPC, and every third party (Cal.com, Meteor Forms, Netlify), in all three languages.
Pass
RequiredCookie consent
A default-deny banner blocks Google Analytics until a visitor explicitly accepts, built in this round of work.
Pass
RecommendedGlobal Privacy Control (GPC)
Honored automatically: a GPC signal turns analytics off with no banner shown and nothing written to storage, and /.well-known/gpc.json declares this.
Pass
RecommendedThird-party scripts and privacy
The only third-party scripts (Google Analytics, cal.com) are consent-gated or page-specific, and both are listed explicitly in the CSP allowlist and the Privacy policy.
Not applicable
OptionalStorage Access API
This site has no embedded cross-site content of its own that would need to request its own cookies.
Partial
RecommendedPrivacy-respecting analytics
Google Analytics is used rather than a cookieless, EU-hosted alternative, but it is now fully consent-gated and GPC-aware, which addresses the consent half of this item even though the tool itself is not the more private option the spec favors.
Pass
RecommendedData minimisation
Only what is needed is collected: no accounts, no combining analytics with other data, and the Contact form only sends what a visitor types into it.
Resilience
6 / 8 (75%)
specification.website checklist results for Resilience
Status
Checklist item
How kevinyoung.net did
Pass
RequiredCustom error pages (404, 500)
A real 404 page returns the correct status, explains what happened in plain language, and links back into the site, confirmed live.
Not applicable
RecommendedMaintenance pages and 503
The site has no planned-maintenance workflow; Netlify keeps serving the last successful build, so there is no maintenance state to design a page for.
Partial
RecommendedGraceful degradation when JavaScript fails
Every page is fully prerendered, so core content and navigation work without JavaScript; interactive extras (search, Display settings, the cookie banner, cal.com booking) do need it, and that has not been explicitly tested with JavaScript disabled.
Fail
OptionalOffline support and service workers
Not implemented; a network failure shows the browser's own offline page, not a cached fallback.
Pass
RecommendedWeb app manifest
site.webmanifest has a name, theme and background color, and now lists both purpose: "any" and purpose: "maskable" icons: the maskable pair are freshly generated, shrinking the existing circular photo crop onto a full-bleed same-color background so the face sits inside the maskable safe zone instead of touching the canvas edge.
Not applicable
RecommendedMonitoring and uptime
This is a hosting and operations decision for Kevin to make, not something the codebase itself can implement.
Not applicable
OptionalDeprecation and Sunset
This site has no API endpoints being retired that clients would need advance warning about.
Not applicable
RecommendedRedirect-By header
There are no genuine HTTP redirects (3xx) configured anywhere on this site right now for the header to attach to.
Internationalisation
18.5 / 20 (93%)
specification.website checklist results for Internationalisation
Status
Checklist item
How kevinyoung.net did
Pass
RecommendedInternational URL structure
One consistent pattern (subdirectory: /es/, /pt/) is used everywhere, with no mixing of country-domain or subdomain approaches.
Pass
Recommendedhreflang for language and regional URLs
Reciprocal hreflang alternates, plus x-default, are set on every page that has translations, both in <head> and in the sitemap.
Pass
RecommendedLocalised page metadata
Title, description, Open Graph, JSON-LD and breadcrumbs are all translated per language, not just the visible body text.
Pass
Optionalhreflang in XML sitemaps
The sitemap declares language alternates with xhtml:link, not only in the HTML head.
Pass
AvoidAvoid automatic IP-based language redirects
There is no IP- or Accept-Language-based redirect anywhere; visitors choose their language explicitly.
Pass
Requiredlang attribute on inline content
The document-level lang is always correct, and the site's content does not mix languages mid-paragraph anywhere, so there is no inline foreign-language text that would need its own lang attribute. Revisit if a future post ever quotes another language inline.
Partial
Optionaltranslate attribute for untranslatable content
Added to brand and project names across the main pages and footer in this round, but not yet swept across every remaining mention sitewide, such as inside long-form post body text.
Pass
RecommendedLanguage switcher
Lists each language by its own name (English, Español, Português) with the correct lang attribute, with no flags.
Not applicable
RecommendedRTL and bidirectional text
The site only serves English, Spanish and Portuguese, none of which are right-to-left languages.
Not applicable
OptionalWriting modes and CJK line breaking
The site serves no Chinese, Japanese, Korean or vertical-script content.
Pass
RecommendedLocale-aware content
Dates are formatted per locale through a shared date helper built on the Intl API.
Partial
RecommendedPlural rules and grammatical number
"1 result" versus "{n} results" style strings are hand-authored per language rather than driven by Intl.PluralRules or CLDR categories, though Spanish and Portuguese's simple plural rules have not caused a wrong-sounding string yet.
Not applicable
OptionalInternationalised Domain Names (IDN)
kevinyoung.net is a plain ASCII domain name.
85.0%
Overall score: 250 of 294 applicable points (-122 of 172 items were not applicable and don't count toward or against the score)