spa
Skill1 starsChanged 2 months agoMITView on GitHub
Single-Page-Application rules for projects following the air-gapped, browser-native architecture. Defines the one entry document, radio-driven navigation read by CSS `:has()`, the fetch-once shell, the `oninput` data lifecycle per view change, and same-document content transitions. Use whenever wiring navigation, routing, view switching, deep-linking, or page-to-page behavior. Pairs with the `pwa` skill.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- aigengame/aseprite-automationtheir own version, first seen Oct 8, 2026
- ffsshhttiikk/opencode-agents-skillstheir own version, first seen Feb 28, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- aigengame/aseprite-automation★ 25same name
- ffsshhttiikk/opencode-agents-skills★ 2same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository14 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- architectureSkill
- cssSkill
- data-flowSkill
- htmlSkill
- javascriptSkill
- jsonSkill
- namingSkill
- principlesSkill
- pwaSkill
- securitySkill
- sessionSkill
- testingSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 2 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 57
Never a client-side router library (no hash router, no History-API view routing)
- Distinctive: line 58
Never a second HTML page or a JS template/rendering engine for views
- Very specific: line 59
Never <a href> for in-app view changes (anchors are for real cross-document links only)
- Very specific: line 60
Never a user-event handler for data fetching — the oninput lifecycle owns all CRUD
- Very specific: line 61
Never @view-transition (cross-document only.
- Very specific: line 62
Never store view state in JS variables — :checked in the DOM is the state
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
SPA
One document. The browser is the router. Navigation is DOM state (:checked), read by CSS. JavaScript moves data, never drives the view. This is the twin of the pwa skill: SPA defines the in-page model, PWA defines the deployment posture.
One entry document
A single index.html at project root holds the entire DOM up front (see the html skill's shell). There is no second HTML page, no client-side template engine, no innerHTML view rendering. Views are regions of the one document that show or hide based on data presence and :checked state.
Navigation is a radio state machine
Global navigation is mutually-exclusive radio inputs inside labels, inside <nav> — never <a href> page loads, never a JS router, never the History API for view switching:
<nav>
<label><input type="radio" name="nav" aria-hidden="true" /></label>
<label><input type="radio" name="nav" aria-hidden="true" /></label>
</nav>CSS reads the checked radio with :has() and reveals the matching view. The name="nav" group gives single-selection for free (the browser enforces exclusivity). The full input-hiding + accessibility details live in the css skill's state-machines reference; the visual reaction lives in css layout/state.
No checked attribute is set in the HTML. The startup script restores the persisted selection (or the first radio) and dispatches an input event — see below.
The shell is fetched once
Chrome-of-the-app content — header, nav, footer, meta — is fetched and injected a single time per runtime session, not on every view change. Only the per-view data is re-fetched when the nav selection changes. The javascript skill owns the transport; this skill owns the rule: shell once, view data per selection.
Every view change enters the same oninput lifecycle
A view change is an input event on the selected nav radio. That is the only trigger for a data fetch. The lifecycle:
- A nav radio becomes
:checked(user click, or programmatic restore on load). - Its own
oninputfires the shared lifecycle inoninput.js. - The lifecycle maps the radio's index to an endpoint suffix and fetches that view's JSON.
- JSON is injected into the reused DOM targets; CSS reveals them via
:not(:empty)/:has().
:checked is the single source of truth for both the CSS view state and the data call. Full lifecycle rules are in the javascript skill — this skill only fixes that navigation and data are one event, never two.
Initial load and return visits
No nav radio is checked in the HTML. On load, the startup script reads the persisted selection from storage (or falls back to the first nav radio), sets input.checked = true, then dispatches input.dispatchEvent(new Event('input', { bubbles: true })) so the input's own oninput runs the lifecycle. This dispatchEvent is the single sanctioned programmatic selection — .click() / onclick are forbidden. Return visits restore the persisted radio the same way, which is how the SPA "deep-links" to a view without a URL router.
Same-document view transitions
Switching views is a same-document change, so it fades via the universal * transition plus transition-behavior: allow-discrete (see the css skill's transitions reference). @view-transition is not used — it fires only on cross-document navigations and is inert in this single-document app. If the project ever becomes multi-document, revisit that decision then.
What the SPA never does
- Never a client-side router library (no hash router, no History-API view routing)
- Never a second HTML page or a JS template/rendering engine for views
- Never
<a href>for in-app view changes (anchors are for real cross-document links only) - Never a user-event handler for data fetching — the
oninputlifecycle owns all CRUD - Never
@view-transition(cross-document only; does nothing here) - Never store view state in JS variables —
:checkedin the DOM is the state
Boundaries with other skills
| Piece | Owned by |
The one index.html shell + regions | html |
| Nav state machine markup + input hiding | html + css (state-machines) |
| View reveal, layout, view transitions | css (layout, transitions) |
oninput lifecycle, fetch, storage, startup dispatch | javascript |
| View JSON shape | json |
| Offline shell caching + install | pwa |
Baseline & support
Checked against MDN as of 2026-07-16.
:has()— Baseline Widely available — https://developer.mozilla.org/en-US/docs/Web/CSS/:hastransition-behavior(incl.allow-discrete) — Baseline 2024 Newly available — https://developer.mozilla.org/en-US/docs/Web/CSS/transition-behavior@view-transition— Limited availability — https://developer.mozilla.org/en-US/docs/Web/CSS/@view-transition
Canonical rules: https://github.com/Autocss-com/ai/blob/main/AGENTS.md
Reference
- MDN
:has(): https://developer.mozilla.org/en-US/docs/Web/CSS/:has - MDN
:checked: https://developer.mozilla.org/en-US/docs/Web/CSS/:checked - MDN
transition-behavior: https://developer.mozilla.org/en-US/docs/Web/CSS/transition-behavior - MDN
Event()/dispatchEvent: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent - MDN Single-page applications: https://developer.mozilla.org/en-US/docs/Glossary/SPA
- AutoCSS Architecture (canonical rules): https://github.com/Autocss-com/ai/blob/main/AGENTS.md
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

