Edge to edge, nothing under the notch
The page fills the whole screen and pads around the status bar, the home indicator and the rounded corners.
viewport-fit=cover · env(safe-area-inset-*)
Any web page made for a phone plays in Proto, full screen. The Proto skill is one folder you give to Claude Code, or any agent that reads Agent Skills: it builds the page, checks it and sends it to your phone.
Node 18 or newer · no npm install · no account · see the helpers
habit-tracker/index.html for a phone screencheck.mjs: Ready for Protoproto://open?u=http%3A%2F%2F192.168.1.24…Six rules it follows, so the page feels like an app and not like a website.
The page fills the whole screen and pads around the status bar, the home indicator and the rounded corners.
viewport-fit=cover · env(safe-area-inset-*)
Full height, scrolling only where the content is, and never sideways. Checked at 375 to 430 points wide.
100dvh · overflow-y: auto
Sample data, a sign-in that takes anything, pretend photos. Proto gives pages no camera, location or files.
no backend needed
Tap targets of 44 points, pressed states, no accidental text selection, transitions under 350 ms.
:active { scale: .97 }
The page title becomes its name in your library. Meta tags set the status bar, the loading colour and the preview.
<meta name="proto:status-bar">
Inside Proto the page gets a tiny bridge for haptics, the status bar and closing. In a browser it’s simply not there.
window.proto?.haptic('light')
Run a small script on your computer. Proto finds it, and the phone reloads every time you save.
Put it on Vercel, Netlify, GitHub Pages or any other host, then paste the link.
Pack it into a .proto file and AirDrop or Quick Share it. It plays offline.
Ask your agent for as many takes on a screen as you like, two or ten. They arrive as one prototype: flip between them on your phone, try the switches, pick the one you like. Your picks and notes go straight back to the agent.
Each take gets a letter and a live preview. Tap or swipe through them and the prototype changes right behind the tray.
Theme, sample data, a banner on or off. The page reads them from attributes on <html>, so plain CSS can follow.
After your feedback the next round comes first. Earlier rounds stay one swipe away, just as they were.
Pick a variant or leave a note. A live prototype sends it to the computer serving it, where your agent reads it.
<script type="application/proto+json">
{ "controls": [
{ "id": "variant", "role": "variant", "options": [
{ "value": "a", "label": "One page" },
{ "value": "b", "label": "Stepper" },
{ "value": "c", "label": "Sheet" } ] },
{ "id": "theme", "type": "theme" },
{ "id": "promo", "type": "toggle", "label": "Promo banner" }
] }
</script>
The skill writes this for your agent. Proto turns it into tabs and switches.
/* the state sits on <html> */
html[data-variant="b"] .checkout { … }
html[data-promo="off"] .promo { display: none }
window.proto?.state // { variant: 'b', theme: 'dark', … }
addEventListener('proto:state', (e) => render(e.detail.state))
In a browser the defaults show, so the page works anywhere. Links and QR codes carry the switches along.
They come inside the skill folder. Node 18 or newer, no npm install, no account. Your agent runs them for you, but they’re just as handy by hand.
None of this is required. Proto reads it when the page loads, and in a normal browser it does nothing.
<title>Habit Tracker</title> <!-- its name in your library -->
<meta name="proto:status-bar" content="dark">
<meta name="theme-color" content="#0b1020">
<meta name="proto:thumbnail" content="thumb.png">
<meta name="proto:orientation" content="portrait">
Or put the same in a proto.json next to index.html.
// light | medium | heavy | selection | success | warning | error
window.proto?.haptic('light')
window.proto?.setStatusBar('light') // for this screen
window.proto?.exit() // close the prototype
window.proto?.state // the switches (see Variants)
That’s the whole bridge. No camera, no location, no files: Proto keeps permissions out of it.
Figma, ProtoPie, Sketch & more