Nonce
Nonce is a site for a crypto exchange office: a counter where people buy and sell with a person, Bitcoin ATMs, an OTC desk for larger trades and paid wallet setup sessions. It fits Bitcoin ATM operators and crypto shops too. It is laid out like a blockchain explorer turned into print: paper white with a fine dot field, a hairline chain down the left edge, every number in a monospaced face, signal green for buying and rising prices, coral for selling and falling ones. The home page opens on the headline over today’s rate board, with Find an ATM and Book the OTC desk from the first frame. The demo is a fictional exchange office in Lisbon, Nonce.
Nonce comes in two variants, chosen when you create the site: files/Sanity (static pages, any host)
and EmDash (--cms emdash, rendered on request on Cloudflare). The pages are the
same in both.
Pages and their content
Section titled “Pages and their content”| Page | Edit it in |
|---|---|
| Home | Pages → Home page (a list of sections) |
| Today’s rates (the hero’s board, the header’s ticker, the Rates page, the chat) | Content → Rates |
| Rates (the rate table with the spread, the converter, fees and limits, how a rate is set, the OTC quote form, questions) | Pages → Rates page |
| Services (every service as a card, what comes with every trade, questions) | Pages → Services page |
| A service (a page each: fee, limit, time, what to bring, key figures, what’s included, how it goes, questions, photo) | Content → Services |
| ATMs (every machine in a table) | Pages → ATMs page |
| An ATM (a page each: status, hours, buy and sell, coins, limit, fee, directions, how to find it, photo) | Content → ATMs |
| How it works (the steps of a first trade, book the OTC desk, the paid wallet setup, questions) | Pages → How it works page |
| Security (the promises, ID checks by amount, scam warnings, questions) | Pages → Security page |
| Reviews | Pages → Reviews page |
| Learn | Content → Learn (one guide can be members-only) |
| Visit (the map, the ATMs, how to get there, opening hours, message form, questions) | Pages → Visit page |
| Name, phone, address, registrations, rating, hours, navigation, profiles, the risk warning | Pages → Site settings |
| Buttons, labels, chat, emails, game texts | Content → Interface texts |
| Privacy, terms, fees and limits | Pages → Legal |
In headlines, words wrapped in *stars* get a highlighter sweep under them, as in
“Buy and sell crypto *with a person*”.
Your rates live in one place, Content → Rates: when they were set (“Rates at 09:40 · Thu 6 Nov”), the currency, and for each coin what a customer pays, what they get, the 24-hour change and a few prices for the sparkline. The hero’s board shows the first six coins (each price’s last two digits roll into place once, the sparklines draw themselves), the header’s ticker shows them across the top of every page, and the Rates page lists every coin with its spread. These are the rates you publish, not a live feed: update them when you set new ones, and keep the time on them.
The converter on the Rates page works out a trade in the browser: buy or sell, a coin, an amount and where (each place you trade with its fee, Pages → Rates page → Converter). It takes the market price between your buying and selling rate and adds or takes off that fee, then shows the rate, the fee and what the customer receives.
Block by block
Section titled “Block by block”Every home section after the hero is a block of a chain. A stamp strip above each shows its height, a
short hash with the leading zeros of a mined block and its confirmations; as it scrolls into view the
hash scrambles through hex characters and settles. The chain down the left edge fills with the accent
as you scroll, the steps on How it works hang on it as blocks, and the footer ends in a strip of the
latest blocks whose newest one fills as you arrive. The stamps are decoration, the same on every build
(src/lib/block.ts). With reduced motion everything shows settled.
Services, ATMs and fees
Section titled “Services, ATMs and fees”Each service has a page laid out like a transaction: the fee and what it covers, the limit, how long it
takes and what to bring as fields, then what’s included, the steps and questions. A service whose
button goes to /atms also shows the ATM table. Each ATM has its status (online or under maintenance),
hours, whether customers can buy and sell, its coins, limit and fee, and its latitude and longitude for
the Google Maps, Apple Maps and OpenStreetMap directions links. Search engines get the machines as
schema.org AutomatedTellers with coordinates.
Every page’s footer carries the risk warning from Site settings, and the chat never gives investment advice. Keep both, and never promise returns in your own content.
The map
Section titled “The map”The visit page and the home section “Visit” show a map of the streets round your office, drawn from
OpenStreetMap in your colors, with a pin, your address and
directions links. It is part of the page (no embed, no cookies) and follows the theme and your accent.
To draw your own, put your coordinates in map.config.json and run pnpm map -- fetch.
Integrations
Section titled “Integrations”Everything works without keys; each feature switches on with its variables in .env.example.
| Feature | Where | Service |
|---|---|---|
| Book the OTC desk | How it works page, loads on click; a preview of the calendar until connected | Cal.com |
| Paid wallet setup session | How it works page (one-time payment) | Stripe or Lemon Squeezy |
| Rate alerts by email | Home and Learn pages, with a welcome email | Supabase or Mailchimp |
| OTC quote requests and messages | Rates and visit pages; to the email in Site settings | Resend |
| AI chat | Every page; answers about rates, fees, ATMs, ID checks and how a trade works; no investment advice, warns about scams | Claude or OpenAI |
| Members-only guide | Learn | Clerk |
| Search | ⌘K or the search field: services, ATMs, pages, guides | built in, or Algolia |
| Analytics | Every page; Google Analytics only after consent | Plausible, Umami, Google Analytics, PostHog |
| Photos | Production builds | Cloudinary (optional) |
Sections
Section titled “Sections”The home page is built from these sections, in any order: Hero (the rate board), Services, ATMs (a table of machines), Numbers (over a chart of blocks that fills as it scrolls in), How it works (the steps along the chain), Security (a photo, facts and a button), Reviews, Learn, Rate alerts, Visit (the map) and Closing call (a photo beside the headline).
Colors and brand
Section titled “Colors and brand”src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the accent
(signal green: buying, rising prices, the buttons and filled blocks), the second (coral: selling and
falling prices, the scam warnings) and the third (blue: hashes and step numbers). Buttons are
adjusted until their dark text is readable and the text colors for each theme; a color that can’t get
there stops the build with a message. Brand also sets the fonts and the corners. The site opens in its
light theme; the toggle switches to a graphite dark theme and the browser remembers it.
Languages
Section titled “Languages”Nonce is ready for more languages: see Languages.
The 404 page
Section titled “The 404 page”A small game, Fill the block: you are the miner. Transactions wait in the mempool, each with a size in vB and a fee in sats. Pick which ones go into a block of 1,000 vB (tap them, or move with ← → and press Space), then mine it (the button, Enter or M) before the timer runs out, when the network mines it with whatever you had in. The highest fee rate first is not always the best block. You score 100 × your fees ÷ the most fees that fit. Three blocks: 8 transactions in 30 seconds, 10 in 25 and 12 in 20; the best score is kept in the visitor’s browser.
AI assistants and search engines
Section titled “AI assistants and search engines”AGENTS.mddescribes the project for coding assistants (Claude Code reads it throughCLAUDE.md, Cursor through.cursor/rules/)./llms.txtlists your pages, services, ATMs and guides for AI assistants, in every language.- Pages carry JSON-LD: the company as a
FinancialService(hours and rating), services asServices, ATMs asAutomatedTellers with coordinates, the paid session as an offer, the reviews, questions as aFAQPage, and each guide as aBlogPosting.
Commands
Section titled “Commands”pnpm dev # local site, editor at /keystaticpnpm build # production buildpnpm map -- fetch # draw the map round map.config.json from OpenStreetMappnpm cms sanity schema|seed # move content to Sanity (see Content → Sanity)In the EmDash variant: npm run dev, npm run deploy (Cloudflare) and npm run emdash:schema
(after changing the content model).
