SOP: Frontend Experiment Setup
Purpose
Standard process for adding a new frontend experiment to the playground, and promoting approved prototypes to production SvelteKit apps.
Core Principle: Playground IS Production
SvelteKit
.svelte files ARE HTML. A playground prototype is not "inspiration" — it IS the implementation. The promotion path is copy-paste, not rewrite:- Copy the
<style>block → paste into the.sveltecomponent's scoped<style>(or intoapp.cssfor shared styles) - Copy the HTML structure → paste into the
.sveltetemplate - Replace hardcoded text with
{data.foo}Svelte bindings - Add
+page.server.tsto fetch the real data
That's it. No screenshots. No "porting." No interpretation. The prototype IS the code.
Rule
Vanilla HTML, CSS, and JavaScript only. No npm. No SvelteKit. No build step. If it can't be opened directly in a browser, it doesn't belong in the playground.
Playground Structure
| Component | What It Is | Example |
|---|---|---|
| <strong>Hub repo</strong> | CSS philosophy guide + landing page. No project prototypes. | <code>pal-e-playground</code> |
| <strong>Project playground repo</strong> | Each product project owns its own <code>[project]-playground</code> repo for HTML/CSS prototyping. | <code>westside-playground</code>, <code>mcd-tracker-playground</code> |
Procedure: Create Project Playground Repo
- Create Forgejo repo —
forgejo_admin/[project]-playground - Clone locally —
git clone ... ~/[project]-playground - Add index.html — follow
convention-frontend-css(Atkinson Hyperlegible,#fafafabg,max-width: 48rem, mobile breakpoint 600px). Readpal-e-playground/guide/first. - Add nginx subpath — add a
location /[project]/ { alias /srv/[project]-playground/; }block to the playground nginx config + hostPath mount for~/[project]-playground. This serves the new repo atplayground.tail5b443a.ts.net/[project]/. - Update hub landing page — add a link to the new subpath in
pal-e-playground/index.html. Push to the hub repo. - Verify on phone — open
playground.tail5b443a.ts.net/[project]/and confirm it renders. - Register — add repo to
project-frontend-playgroundRepos table under Project Playground Repos. - Push to Forgejo
cd ~/[project]-playground git add . git commit -m "initial prototype" git push
Procedure: Hub Repo Maintenance
- The hub repo (
pal-e-playground) contains only:guide/index.html(CSS philosophy reference) andindex.html(landing page linking to all project subpaths). - Landing page is the live directory — it links to every project playground via subpath (e.g.
/westside/,/mcd-tracker/). Update it whenever a new project onboards. - Guide updates — when CSS conventions change, update
convention-frontend-cssfirst, then update the guide to match. - No project prototypes in the hub — project prototypes live in their own
[project]-playgroundrepos, served as subpaths under the same Tailscale funnel.
Promotion to Production
- Approve on phone — Lucas verifies the prototype looks right on mobile
- Create Forgejo issue on target repo (pal-e-app, westside-app, etc.) referencing the prototype path
- Direct copy-paste — the dev agent's job is mechanical:
- QA review — verify zero hardcoded hex, all data bindings correct, mobile responsive
- Lucas verifies production on phone before merge
Why This Works
SvelteKit components are HTML with superpowers. A
.svelte file has three sections: <script>, HTML template, and <style>. The HTML template IS HTML. The <style> IS CSS. The only translation from playground to production is adding the <script> for data binding and replacing static content with template expressions.Proven by: F11c home page (PR #37). Prototype at
html-playground/6-pal-e-home/ → direct port to +page.svelte in one dev agent dispatch.What NOT to Do
- Don't add
package.jsonto a playground experiment - Don't try to connect to live APIs from the playground — use hardcoded/fake data
- Don't skip the phone check — if it's not mobile-friendly, it's not ready
- Don't let agents design the look — agents port proven CSS, they don't create it
- Don't use screenshots as an intermediary — the HTML/CSS IS the spec
- Don't "reinterpret" the prototype — copy it literally, then swap data bindings
Related
project-frontend-playground— parent projectdoc-html-playground— philosophy + infra referenceconvention-frontend-css— CSS custom property rulesfeedback_playground_first— the original feedback that established this conventionfeedback_frontend_iteration— frontend must iterate with Lucas in the loop