Agent Skills

frontend-perfection

Audit and polish a frontend — static HTML/CSS/JS or a built SPA — towards verifiable perfection. The skill exists because production web perf tooling commonly breaks when it pokes at private APIs (Playwright internals, old Lighthouse signatures, unisolated global deps). This skill runs on STABLE apis only, computes exactly (luminance, not eyeballs), and demands a before/after report bound to audit ids.

When to use

Workflow

  1. Locate the project — static files (index.html + css/) or built SPA.
  2. Serve it locally if needed: python3 -m http.server 8377 (or the project’s dev server). Static files are fine over http://localhost.
  3. Run audit.js (Lighthouse, real Chrome):
    node scripts/audit.js --url http://localhost:8377/ --mobile --out lh-mobile.json
    node scripts/audit.js --url http://localhost:8377/ --desktop --out lh-desktop.json
    

    Default threshold is 100; exit 0 only when every measured category is at or above it. Add --only <category> to iterate on one category.

  4. Run meta_audit.py (SEO/contrast/headings/tokens, offline):
    python3 scripts/meta_audit.py --html index.html --css main.css css/demo.css --out meta.json
    

    Exit 0 = no violations; exit 1 = violations found.

  5. Fix by audit id — every fix must reference the audit it closes (e.g. audit.js color-contrast, meta_audit.py meta:description).
  6. Re-audit until green on both form factors. Only then call it done.
  7. Write the before/after report in the showcase format: input paths, exact commands, real output, interpretation. Explicitly list what was deliberately NOT done.

audit.js — Lighthouse runner (stable API)

meta_audit.py — static audit (Python stdlib, offline)

Checks and their ids:

id what it verifies
meta:title / meta:title-length title present, ≤ 60 chars
meta:description / meta:description-length description present, ≤ 160 chars
meta:canonical canonical link
meta:og:*, meta:og:size OG tags; image must declare 1200×630 (crop-safe)
meta:twitter:card twitter card tag
meta:json-ld any application/ld+json script
meta:robots not blocked with noindex/nofollow
meta:sitemap-link sitemap referenced
headings:single-h1 exactly one h1
headings:order h1→h6 sequence, no level skips (h1→h3 is a violation)
tokens:raw-hex zero raw hex outside the token block (:root/tokens)
contrast:wcag-aa computed WCAG relative luminance, fg/bg pairs ≥ 4.5:1
adaptive:scroll-padding fixed header ⇒ scroll-padding-top present
adaptive:media-queries responsive breakpoints exist for tablet widths

Design tokens — “colors as constants”

For static projects WITHOUT a build system (plain HTML/CSS/JS), a minimal design system still applies:

OG image generation — crop-safe social share

Social networks crop images differently (WhatsApp square-ish, Facebook center-crop). The skill’s rules, learned the hard way:

  1. Change the file name, never overwrite — social caches keyed by URL will keep showing the old preview forever. New content ⇒ new URL (e.g. og-2026-08-09.png).
  2. Content must fit the central safe zone — standard 1200×630 canvas is not enough: keep the hero/graphic content within ~600–640px centered width so a square/center crop (≈630×630) never clips text or logos.
  3. Force a reflow before the screenshot — after setting width via inline style, the first screenshot() may capture the stale layout. Read void element.offsetHeight (or getBoundingClientRect()) to force layout sync, then shoot.
  4. Declare exact dimensionsog:image:width/og:image:height = 1200/630 so scrapers don’t guess and mis-trim.
  5. Re-test in 2+ networks after changing the URL (WhatsApp + Telegram at minimum; they cache most aggressively).

Fixed-header anchoring

If position: fixed header exists, anchor jumps hide content underneath. Fix: html { scroll-padding-top: <header-height> } (+ scroll-margin-top on the anchors if needed). meta_audit.py reports adaptive:scroll-padding when this is missing.

Constraints / non-goals

Examples

Full loop on a static site:

cd ~/projects/lovii_demo
python3 -m http.server 8377 &
node .../audit.js --url http://localhost:8377/ --mobile --out lh-mobile.json
node .../audit.js --url http://localhost:8377/ --desktop --out lh-desktop.json
python3 .../meta_audit.py --html index.html --css main.css css/demo.css --out meta.json

Iterate on one category until green:

node .../audit.js --url http://localhost:8377/ --mobile --only accessibility

See references/canonical-patterns.md for the canonical sources this skill is aligned with, and the showcase in docs/showcase/showcase-frontend-perfection-lovii.md.