Text-only version. View the full version of this page · All text pages

Website audit

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

  • Pass Pass: fully meets the item.
  • Partial Partial: some of it is done, or done a different way than the spec describes.
  • Fail Fail: applies to this site and isn't done.
  • Not applicable Not 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
StatusChecklist itemHow kevinyoung.net did
PassRequired The HTML doctype<!doctype html> is the first line of every prerendered page.
PassRequired The lang attribute on <html>html lang is set per language (en, es, pt) and kept in sync during client-side navigation.
PassRequired <meta charset>UTF-8 is declared first in <head>, before any other tag.
PassRequired <meta viewport>width=device-width, initial-scale=1, and user scaling is never disabled.
PassRequired The <title> elementEvery page gets one unique <title> from Seo.svelte, separate from its <h1>.
PassRecommended <meta name="description">Every page has its own hand-written description, authored as a direct answer to what the page is.
PassRecommended Canonical URL (rel="canonical")Every page self-canonicalizes, and reposts point their canonical at the original source instead.
PassRecommended Favicons and app iconsShips 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.
PassRecommended <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.
PassRecommended <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.
PassRecommended Open Graph protocolog:title, og:description, og:image, og:url, og:type and og:locale are set on every page, with alternates for the other two languages.
PassRecommended Feed discovery with rel="alternate"Every page links to the per-language RSS feed with <link rel="alternate" type="application/rss+xml">.
PassRecommended Feed content hygieneThe 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.
FailRecommended Popover APIThe 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.
FailOptional WebSub: push notification for feedsNo WebSub hub is advertised for the RSS feed, so subscribers still have to poll for updates rather than being pushed them.
FailRecommended CSS anchor positioningPanels and menus are positioned with fixed and absolute CSS and manual coordinates, not anchor-name and position-anchor.
PassRecommended Balanced text wrappingtext-wrap: balance applies to every h1, h2 and h3 sitewide, not just the two About page headings that had it before.
PassRecommended CSS container queriesThe 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.
FailOptional Invoker commandsButtons that open panels (search, Display settings, the cookie banner) use onclick handlers, not the command/commandfor attributes.
Not applicableOptional _for-sale DNS recordskevinyoung.net is Kevin's own personal site and is not for sale.

SEO

27 / 27 (100%)

specification.website checklist results for SEO
StatusChecklist itemHow kevinyoung.net did
PassRecommended robots.txtA plain-text robots.txt at the root allows all crawlers and points to the sitemap.
PassRecommended XML sitemapssitemap.xml lists every canonical URL with hreflang alternates, generated fresh on every build.
Not applicableRecommended Sitemap index filesThe sitemap holds 45 URLs, far under the 50,000-URL point where an index file would matter.
Not applicableOptional Image and video sitemap extensionsEvery image is in plain, server-rendered HTML a crawler can already reach directly; nothing is hidden behind client-side JavaScript or an uncrawlable CDN.
PassRecommended URL structureURLs are lowercase, hyphenated and shallow (e.g. /writing/never-old-learn), with identical slugs across all three languages.
PassRequired Redirects (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.
PassRecommended Server-side renderingThe whole site is statically prerendered at build time; every page arrives fully formed in the first response, nothing waits on client-side JavaScript.
PassAvoid Soft 404sAn unknown URL returns a real 404 status, confirmed live, not a 200 with a "not found" message.
PassRequired Meta robots and X-Robots-TagPublic pages index by default; noindex is set explicitly on Search, the 404 pages, and the generated text and Markdown copies.
PassRequired Heading hierarchyOne h1 per page, checked in the accessibility audit, with semantic (not styled-only) headings throughout.
PassRecommended Internal linkingNav, footer, breadcrumbs and in-content links (brand cards, project links, related posts) all tie pages together.
PassRecommended Structured data (JSON-LD)Person, WebSite, page-type (WebPage/AboutPage/CollectionPage/BlogPosting) and BreadcrumbList JSON-LD are emitted on every indexable page.
PassRecommended BreadcrumbsBoth halves are covered: a visible breadcrumb trail plus matching BreadcrumbList JSON-LD, the visible half added in this audit.
PassOptional IndexNowEnabled 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
StatusChecklist itemHow kevinyoung.net did
PassRequired Colour contrastAudited with axe-core across every page, both themes, at desktop width and 375px, as recorded on the Accessibility policy page.
FailOptional Automatic contrasting colourText-on-brand-color pairings are hand-picked (a fixed dark ink color) rather than computed with the CSS contrast-color() function.
PartialRecommended Forced colours modeThe 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.
PassRequired Image alt textEvery 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.
PassRequired Form labelsEvery 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.
PassRequired Keyboard navigationA 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.
PassRequired Visible focus indicatorsA two-ring :focus-visible outline is defined sitewide, with an optional thicker "enhanced focus" mode.
PassRecommended Focus not obscuredChecked 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.
PassRequired Skip linksA "Skip to main content" link is the first focusable element on every page.
PartialRecommended The inert attributeThe 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.
PassRequired Semantic HTML and landmarksheader, nav, main and footer are used throughout, confirmed during the axe-core audit.
PassRecommended ARIA: first rule of ARIANative elements are preferred everywhere; ARIA is added only where nothing native fits, such as the custom panels.
PassRequired Descriptive link textLinks describe their destination ("Read the original," "See all posts in English"); generic "click here" text is not used.
PassAvoid Empty links and buttonsEvery icon-only control (search, theme toggle, close buttons) carries an aria-label or visually hidden text.
Not applicableRequired Accessible form errorsThis 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.
PassRecommended Status messagesConfirmed 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 applicableRecommended Accessible authenticationThere are no accounts or logins anywhere on this site.
Not applicableRecommended Redundant entryThere is no multi-step process anywhere on the site that would ask for the same information twice.
PassRecommended Consistent helpSearch, Display settings, the theme toggle, and now Cookie settings, all sit in the same header or footer position on every page.
PassRequired Document and parts languagehtml lang is always set correctly per language; the site's content does not currently mix languages mid-paragraph.
PassRequired Reduced motionprefers-reduced-motion is respected sitewide, and the site has little decorative animation to begin with.
PassAvoid Accessibility overlaysNo third-party accessibility widget is used; the Display settings panel is this site's own first-party code, not a bolted-on overlay.
Not applicableRequired Captions and transcriptsThe site has no video or audio content.
PassRequired Accessible data tablesMarkdown 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.
PassRequired Touch target sizeInteractive elements meet the 24 by 24 CSS px minimum sitewide, checked during the layout audit.
Not applicableRecommended Dragging movementsThe 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.
PassRecommended Hidden until foundThe 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).
PassRecommended Mobile-friendly form inputsThis 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.
PartialRecommended Native interactive elementsbutton, 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.
FailRecommended CSS 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
StatusChecklist itemHow kevinyoung.net did
PassRequired HTTPS and TLSServed over HTTPS everywhere via Cloudflare and Netlify; plain HTTP redirects to HTTPS.
PassRequired HSTS (Strict-Transport-Security)Sent with a one-year max-age and includeSubDomains, confirmed live, set through the Cloudflare dashboard.
PassRecommended Mixed content and upgrade-insecure-requestsEvery subresource loads over HTTPS, and the CSP's upgrade-insecure-requests directive is a safety net.
PassRecommended Content 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.
FailRecommended Reporting API (Reporting-Endpoints)No Reporting-Endpoints header is set; there is no third-party collector configured yet to receive CSP or COOP violation reports.
PassRecommended /.well-known/security.txtPublished with a contact address and an expiry date.
PassRequired X-Content-Type-Options: nosniffnosniff is sent on every response.
PassRequired Clickjacking protectionBoth X-Frame-Options: SAMEORIGIN and the modern CSP frame-ancestors 'self' are set.
FailRecommended Fetch Metadata request headersSec-Fetch-* headers are not read anywhere; this is a static site with no server-side request handler to inspect them.
PartialRecommended Cross-origin isolation (COOP / COEP / CORP)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.
PassRecommended Referrer-Policystrict-origin-when-cross-origin is sent on every response.
PassRecommended Permissions-PolicyCamera, microphone and geolocation are all turned off sitewide.
FailRecommended Subresource 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.
FailOptional Digest FieldsNot implemented.
FailRecommended Trusted TypesNot 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.
PassAvoid X-XSS-ProtectionCorrectly not sent; this dead header is left out, and CSP is relied on instead.
PassRequired Cookie attributes: Secure, HttpOnly, SameSiteThis 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 applicableOptional Clear-Site-DataThere is no login, logout, or other event on this site that would need to wipe a visitor's storage.
PassRecommended DNS CAA recordsissue 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.
PassOptional DNSSECEnabled 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
StatusChecklist itemHow kevinyoung.net did
PassRecommended Well-known URIs/.well-known/ is used correctly, for security.txt and gpc.json.
Not applicableOptional /.well-known/change-passwordThe site has no user accounts, so there is no change-password page to point to.
Not applicableOptional /.well-known/webauthnThe site does not use passkeys.
Not applicableOptional /.well-known/openid-configurationThis site is not an OpenID Connect identity provider.
Not applicableOptional /.well-known/oauth-authorization-serverThis site does not run an OAuth authorization server.
Not applicableOptional /.well-known/oauth-protected-resourceThis site exposes no OAuth-protected API.
PassOptional /.well-known/gpc.jsonDeclares that Global Privacy Control is recognized and honored.
PassRecommended /.well-known/api-catalogPublished 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 applicableOptional /.well-known/webfingerNot a Fediverse-connected site.
Not applicableOptional /.well-known/apple-app-site-associationThere is no companion iOS app.
Not applicableOptional /.well-known/assetlinks.jsonThere is no companion Android app.
Not applicableOptional /.well-known/nodeinfoNot a federated platform.
FailOptional /.well-known/traffic-adviceNot 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
StatusChecklist itemHow kevinyoung.net did
PassRecommended Agent 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.
PassRecommended /llms.txtPublished per language, listing every top-level page, post and brand with a description.
PassOptional /llms-full.txtPublished per language, concatenating every page's Markdown into one file.
PassRecommended Per-page Markdown source endpointsEvery page is available as raw Markdown at a matching .md URL, plus a <link rel="alternate" type="text/markdown">.
PassRecommended robots.txt for AI crawlersKevin'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.
PassOptional Content Signals in robots.txtA Content-Signal: search=yes, ai-input=yes, ai-train=yes line on the User-agent: * block matches the same welcoming stance.
FailOptional TDM reservation (TDMRep)No tdm-reservation header, meta tag, or tdmrep.json is published.
FailOptional Web Bot Auth: verifiable bot identityNot implemented; no bot is currently allowed or blocked by signed identity.
PassRequired Stable URLsSlugs are permanent and identical across all three languages; nothing has been renamed or broken since launch.
PassRecommended Structured data for agentsThe same JSON-LD used for search engines is available to agents: Person, WebSite, page types, and breadcrumbs.
PassRecommended Machine-readable formatsRSS, llms.txt, llms-full.txt and per-page Markdown are all offered alongside the HTML.
PassRecommended HTTP Link headers for discoverysitemap.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 applicableOptional MCP and tool discoveryThis 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 applicableOptional A2A agent cardsThe site has no agentic behaviour of its own for another agent to delegate to.
Not applicableRecommended Agent Skills discoveryChecked 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.
PassOptional DNS 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 applicableOptional Agentic Resource Discovery (ARD)There are no MCP servers or A2A agents on this domain to catalog.
FailOptional NLWeb: conversational interface discoveryNot implemented; this static site has no natural-language query endpoint to advertise.
FailOptional WebMCP: browser-native tools for agentsNot implemented; there is no in-page tool yet worth exposing to a browser-resident agent.
Not applicableOptional Open Knowledge Format (OKF) bundlellms-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 applicableOptional SchemamapThis 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
StatusChecklist itemHow kevinyoung.net did
PartialRequired Core 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.
PassRequired Image optimisationEvery 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.
PassRecommended Lazy loading images, iframes, and videoloading="lazy" is set on every below-the-fold image; the LCP hero images are correctly left eager.
PassRecommended Preload, prefetch, preconnectThe 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.
FailOptional 103 Early HintsRoot 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.
PassRequired Cache-Control headersHashed build assets get a one-year immutable cache; HTML gets a short, must-revalidate policy, confirmed live.
PassRecommended Vary: the cache key contractVary: Accept-Encoding is sent, confirmed live, without over-listing headers that would fragment the cache.
FailRecommended Conditional requests (ETag, Last-Modified, 304)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.
PassRecommended No-Vary-Search response headerNo-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=/&section= client-side, after load), so caches and BFCache can safely treat any two URLs differing only by query params as the same page.
PassRequired Compression (gzip, brotli, zstd)Brotli is confirmed live (content-encoding: br).
PartialRecommended Web font loadingFonts 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.
PartialRecommended Critical CSS and render-blocking resourcesVite and SvelteKit code-split CSS per route automatically, but no manual critical-CSS extraction or inlining has been added on top of that.
PassRecommended Script loading: defer, async, moduleVite emits type="module" for the app bundle; the Google Analytics and cal.com scripts are injected as async.
PassRecommended HTTP/2 and HTTP/3Confirmed live: HTTP/2 at minimum, with alt-svc advertising HTTP/3.
PassAvoid HTTP/1.1 workarounds: sharding, sprites, and bundlingNo domain sharding or image sprites are used anywhere.
PassRecommended Speculation RulesA sitewide prefetch ruleset (moderate eagerness, same-origin only) was added in this round of work.
PartialRecommended Resource hints overviewmodulepreload (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.
FailOptional View TransitionsNot implemented; navigation has no cross-document transition animation.
PassRecommended Back/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.
FailOptional Visibility-aware renderingcontent-visibility and Intersection Observer are not used; the site is small enough that this has not been a rendering bottleneck.
FailOptional CSS containmentNot used anywhere.
FailOptional Scroll-driven animationsNot used; the site has very little scroll-tied animation to begin with.
PassRecommended Scrollbar gutterscrollbar-gutter: stable is set on html sitewide, so gaining or losing a scrollbar no longer shifts content.
PassRecommended Dynamic 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.
FailOptional Compression Dictionary TransportNot implemented; a newer technique with limited hosting support at this stage.
Not applicableOptional Server-Timing headerThis 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
StatusChecklist itemHow kevinyoung.net did
PassRequired Privacy policyA 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.
PassRequired Cookie consentA default-deny banner blocks Google Analytics until a visitor explicitly accepts, built in this round of work.
PassRecommended Global 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.
PassRecommended Third-party scripts and privacyThe 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 applicableOptional Storage Access APIThis site has no embedded cross-site content of its own that would need to request its own cookies.
PartialRecommended Privacy-respecting analyticsGoogle 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.
PassRecommended Data minimisationOnly 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
StatusChecklist itemHow kevinyoung.net did
PassRequired Custom 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 applicableRecommended Maintenance pages and 503The site has no planned-maintenance workflow; Netlify keeps serving the last successful build, so there is no maintenance state to design a page for.
PartialRecommended Graceful degradation when JavaScript failsEvery 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.
FailOptional Offline support and service workersNot implemented; a network failure shows the browser's own offline page, not a cached fallback.
PassRecommended Web app manifestsite.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 applicableRecommended Monitoring and uptimeThis is a hosting and operations decision for Kevin to make, not something the codebase itself can implement.
Not applicableOptional Deprecation and SunsetThis site has no API endpoints being retired that clients would need advance warning about.
Not applicableRecommended Redirect-By headerThere 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
StatusChecklist itemHow kevinyoung.net did
PassRecommended International URL structureOne consistent pattern (subdirectory: /es/, /pt/) is used everywhere, with no mixing of country-domain or subdomain approaches.
PassRecommended hreflang for language and regional URLsReciprocal hreflang alternates, plus x-default, are set on every page that has translations, both in <head> and in the sitemap.
PassRecommended Localised page metadataTitle, description, Open Graph, JSON-LD and breadcrumbs are all translated per language, not just the visible body text.
PassOptional hreflang in XML sitemapsThe sitemap declares language alternates with xhtml:link, not only in the HTML head.
PassAvoid Avoid automatic IP-based language redirectsThere is no IP- or Accept-Language-based redirect anywhere; visitors choose their language explicitly.
PassRequired lang attribute on inline contentThe 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.
PartialOptional translate attribute for untranslatable contentAdded 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.
PassRecommended Language switcherLists each language by its own name (English, Español, Português) with the correct lang attribute, with no flags.
Not applicableRecommended RTL and bidirectional textThe site only serves English, Spanish and Portuguese, none of which are right-to-left languages.
Not applicableOptional Writing modes and CJK line breakingThe site serves no Chinese, Japanese, Korean or vertical-script content.
PassRecommended Locale-aware contentDates are formatted per locale through a shared date helper built on the Intl API.
PartialRecommended Plural 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 applicableOptional Internationalised 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)