Imported from AhamadMufeez/tohfa (
AGENTS.md). Install upstream withnpx skills add AhamadMufeez/tohfa. Copyright stays with the author.
TOHFA — project architecture and invariants
What this project is
TOHFA is a static, client-only digital gift builder. The user fills a letterhead with TO and FROM names, packs items from six categories, previews the result and shares it as a URL.
There is no backend, database, upload service, build step, framework or dependency. The site is plain HTML, CSS and vanilla JavaScript intended to run by opening index.html directly from disk.
Mobile-only contract
This project is intentionally mobile-only.
- Target width: 320px–430px portrait on smartphones.
- No responsive desktop/tablet rules.
- No media queries for layout.
- Everything is single-column, full-bleed and sized using fluid values.
- Touch targets stay at 48px minimum, and buttons are designed for thumb use.
Files
index.html— all UI: header, letterhead, item picker, sheets, preview, share URL, toast.style.css— the single stylesheet and all visual tokens.script.js— the single script that stores values, opens/closes sheets, updates inventory, builds share URLs and restores shared links.README.md— original product prose; not the technical source of truth.camera.png,video.png,audio.png,letter.png,headset.png,crayon.png— six category icons.barcode.jpeg— present on disk but intentionally unreferenced.
Core behaviors
- The user enters names in
TO:andFROM:. - The user chooses from six categories: Photos, Videos, Audio, Text, Songs and Scribbles.
- Each category is opened from a bottom sheet and the chosen value is reflected in the inventory.
PREVIEW YOUR TOHFAshows the current summary in a sheet.SEND VIA URLopens a share sheet with a generated URL.- The URL carries text and file names only; it cannot transport file bytes because there is no backend.
- When the page is reopened with query parameters, it restores the saved values.
Sheet and attribute rules
The UI depends on a lightweight attribute model:
data-sheet="sheet-id"opens a sheet.data-closecloses a sheet.data-remove="gift-key"clears a specific item.data-file-name="gift-key"exposes the file name row.data-preview="to|from"fills preview labels.
The JS and CSS rely on these ids and hooks remaining stable.
Share-link format
The generated URL contains these query parameters:
tofromsongsongnamenotescribblephotovideoaudio
Only text and file names are transmitted. The page is static, so file bytes can never be shared.
Important scope decisions
- Audio recording is intentionally disabled. It is a decorative, non-functional control.
- Scribbles are implemented as textarea input, not a drawing canvas.
- No file bytes are uploaded or stored.
- The preview sheet is a concise summary, not a literal replica of the letter card.
Verification
Run these from the project root:
node --check script.jsnode verify.mjs
Any new change must preserve the mobile-only contract and these checks must still pass.
Do not break
- Keep the original palette and visual identity.
- Preserve all existing ids and data attributes.
- Keep the CRLF line endings for text files.
- Do not add media queries or desktop layouts.
- Do not add a framework or package.json.
- Do not commit or push unless asked.