Build or maintain a static website using $ARGUMENTS. Apply all rules below strictly.
Composition
Compose with /web-conventions — it provides the baseline rules for semantic HTML, accessibility,
modern CSS, design tokens, and the Baseline browser-support policy. Rules in this skill override it.
When a page needs a small, bounded amount of JavaScript — a theme toggle, a copy button, a
client-side filter — use /web-sprinkles, which keeps every rule below except the no-JavaScript
constraint. For applications that need client-side state, routing, or templating, use
/web-components instead.
Hard Constraints
- No JavaScript — no
<script>tags, no inline event handlers, no.jsfiles; a page that genuinely needs a script belongs to/web-sprinkles, not to an exception here - No external dependencies — no frameworks, libraries, CDNs, or package managers
- No build systems — no transpilation, bundling, preprocessing, Sass, Less, or Tailwind
- No inline styles — all CSS in separate
.cssfiles - Baseline compliance — CSS features per the
/web-conventionsBaseline policy, enforced by the verification loop below
HTML Rules
HTML semantics, heading hierarchy, labels, and skip links follow /web-conventions.
CSS Rules
Design tokens, logical properties, modern CSS features, accessibility, and the Baseline policy
follow /web-conventions. This stack adds:
- Mobile-first responsive design with
min-widthbreakpoints - Use
content-visibility: autofor off-screen sections
CSS Reset Baseline
Every project starts with:
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: system-ui, -apple-system, sans-serif; line-height: 1.5; }
Interactive Patterns (CSS-Only)
When interactivity is needed, use these approaches — never JavaScript:
- Accordion:
<details>/<summary> - Modal:
:targetpseudo-class with anchor links - Tabs: hidden radio buttons with
:checked+ sibling selectors - Dropdown menu:
:hover+:focus-within - Mobile hamburger: hidden checkbox with
:checked+ sibling selectors - Form styling:
appearance: noneto customize native controls - Form validation: standard input types plus constraint attributes (
required,pattern,min/max) — the browser validates and blocks submission without any JavaScript; style feedback with:user-invalid/:user-valid(seeweb-conventionsForm Rules)
Page Transitions (Cross-Document View Transitions)
For multipage sites, animate navigation between pages with cross-document view transitions — pure CSS, no JavaScript:
@media (prefers-reduced-motion: no-preference) {
@view-transition { navigation: auto; }
}
- Opt in on every page (both the outgoing and incoming page must carry the rule)
- Always inside
prefers-reduced-motion: no-preference— reduced motion means instant navigation - Give recurring elements (site header, logo) a
view-transition-namefor continuity across pages; each name must be unique per page - Keep transitions subtle and fast; never let them delay content
Baseline exception: cross-document view transitions are Limited availability, which the
/web-conventions Baseline policy normally forbids. They are exempt because the failure mode is
total graceful degradation — a browser that doesn't understand @view-transition ignores the
at-rule and navigates instantly, losing nothing. No @supports wrapper is needed. The exception
covers exactly the @view-transition at-rule, view-transition-name, and the
::view-transition-* pseudo-elements — nothing else, and never anything JavaScript-driven
(document.startViewTransition stays forbidden by the no-JavaScript constraint).
Performance
loading="lazy"on below-fold images<picture>with WebP sources for responsive images- Preload critical CSS and fonts
contain: layout style painton repeated components
Project Structure
project/
├── index.html
├── css/
│ └── style.css
├── images/
├── fonts/
└── icons/
For small sites, a flat structure (HTML + single style.css + images/) is acceptable.
Verification Loop (Chrome DevTools MCP)
The site ships with zero tooling, so verification happens from the outside: drive a real browser
through the Chrome DevTools MCP tools (chrome-devtools) and assert against what it renders.
This loop defines green for this stack — when a composed skill (/sbce, /continuous-testing)
asks "are you green?", it means exactly this. Never declare a page done from reading its source;
the rendered page is the oracle. If the chrome-devtools MCP tools are unavailable, report the
loop as not runnable — do not silently skip it or self-certify.
Serve
Serve the site root with zws, the zero-dependency single-file
Java development server: java zws <site-root> (serves http://localhost:3000, caching disabled).
If zws is not on the PATH, use the copy bundled with the composed web-conventions skill:
java <web-conventions skill dir>/scripts/zws <site-root>.
Two optional flags:
--live— watches the site root and reloads connected browsers on every file change, via a one-line SSE script injected into served HTML. Use it while authoring, never during the verification loop: the injected script and its/reloadstream would show up in the console, network, and snapshot checks and contaminate the no-JavaScript evidence. Verify against a plainjava zws <site-root>instance.--single— SPA fallback (extension-less unknown paths serveindex.html). Not for this stack: static multi-page sites have a real file behind every URL, and the fallback would mask broken links as false 200s. It belongs toweb-components. Open pages vianew_page/navigate_page. Verification tooling never ships with the site, so this violates no constraint — the no-JS/no-dependency rules govern the artifact, not the harness.file://URLs work for a single page but break root-relative links; prefer the server.evaluate_scriptis permitted for read-only inspection (e.g.getComputedStyle) — it runs in the test browser, not in the site.
Standard checks — every page, every run
- Console —
list_console_messages: no errors, no failed requests (also proves the no-JavaScript constraint holds). - Structure —
take_snapshot(accessibility tree): exactly onemain, no skipped heading levels, a label on every form input,aria-labelon each nav when several exist, skip link first in tab order, alt text on every image. - Responsive —
resize_pageto 375×667 and 1280×800: the layout adapts, and mobile patterns (hamburger, stacked columns) appear only at the narrow width. - Preferences —
emulatewithcolorScheme: dark: the page restyles. The MCP cannot emulate reduced motion, so check it statically: read-onlyevaluate_scriptoverdocument.styleSheets(or a source grep) confirms theprefers-reduced-motion: reducequery exists and neutralizes animations/transitions. - Lighthouse —
lighthouse_audit(covers accessibility, best-practices, SEO — not performance): accessibility = 100 (includes WCAG AA contrast), best-practices and SEO ≥ 90. When performance is in question, invoke/web-performance-reviewer(throttled traces, Core Web Vitals, waterfall) — on explicit request, never part of standard green.
Project checks — checks.md
Site-specific behavior lives in checks.md at the site root (one per BC directory when composed
with /bce): one labeled line per check, mechanically executable — exact URL, viewport, and
expected observation, resolved with the same MCP tools.
# Checks
- [nav-mobile] / at 375px: snapshot contains button "Menu"; nav links hidden until checked
- [R1.2] /catalog/ at 1280px: every workshop is an <article> containing a <time>
Labels are stable identifiers — never renumber, retire instead of reuse. When composed with
/sbce, the label is the requirement id (R1.2), which makes the spec↔check trace
grep-visible — all /sbce needs. Write each check as an observation the browser can contradict
("snapshot contains button 'Menu'"), never as a judgment ("menu looks right") — the next run must
be able to disagree.
Baseline check
Classify each CSS feature the stylesheets use by its Baseline status from knowledge — no external
validation services. A Widely Available feature passes; a Newly Available feature passes
only when wrapped in @supports with a graceful fallback (per the /web-conventions Baseline policy); Limited
availability fails the loop — with one exception: the cross-document view-transition features
named in the Page Transitions section pass despite Limited status, provided they sit inside a
prefers-reduced-motion: no-preference media query. One caveat keeps this honest: the DevTools browser is Chrome, so a
page rendering correctly proves Chrome support, never Baseline — when a feature's status is
uncertain, report the uncertainty instead of guessing.
When composed with /web-latest (experiments and PoCs), this check is replaced by that
skill's support-floor report — an inventory of below-Widely features instead of a gate.
Green
Green = standard checks pass on every page, every checks.md line passes, and the Baseline check
passes. Report per check — label → pass/fail with the observed evidence — then fix and re-run.
Anything less than all-green is red; there is no "mostly green".
What NOT to Do
In addition to the /web-conventions prohibitions (layout tables, <br> spacing, non-semantic
<div>, inline styles):
- Do not use
onclickor any inline event handlers - Do not add JavaScript for interactions achievable with CSS
- Do not use CSS frameworks or preprocessors