# Building an app for Sanduq

Sanduq runs a single HTML file as an app on the user's phone. The file runs full screen in a private sandbox, offline, with its own saved data. Follow these rules and the app will work the first time.

## Deliver
- One self-contained .html file. All HTML, CSS and JavaScript inline. No build step, no imports of local files, no service worker.
- Under 5 MB. Prefer inline SVG to images. Embed small images as data: URLs.
- A short app name in <title>. Sanduq uses it as the app's name.

## Layout
- Phone first, portrait, roughly 360 to 430 px wide.
- <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">.
- Pad for the notch and home bar with env(safe-area-inset-top/right/bottom/left). Sanduq passes the real values in.
- Fixed headers and bottom tab bars are fine. Sanduq's own control sits in the status bar strip and never covers your content.
- Support light and dark with prefers-color-scheme.

## Saving data
- Use localStorage or sessionStorage. Sanduq keeps each app's data separate and persistent, and survives the user replacing the file with a new version.
- Wrap storage calls in try/catch and keep the app usable if storage is unavailable.
- Store data under one or a few keys with a version field, so a newer version of the app can migrate old data.
- Do not depend on a server, login, cookies or a cloud database.

## Network
- The app must work offline.
- Stylesheets, fonts and scripts from fonts.googleapis.com, fonts.gstatic.com, cdn.jsdelivr.net, unpkg.com and cdnjs.cloudflare.com are allowed. Sanduq downloads them once on import.
- Any other request is blocked until the user approves that website. If the app needs live data, say so in the UI and handle a blocked or failed request gracefully.

## Not available
- No popups, new windows or navigation away from the app. Keep everything on one page and use in-page views.
- No camera, microphone, location or notifications.
- No iframes inside the app.
- No platform-specific objects such as window.claude. Check for them and fall back to localStorage.

## Good to have
- A clear empty state on first run.
- An export button that copies or downloads the user's data as JSON, and an import that reads it back.
- Large tap targets, at least 44 px.
