Inspiration

Every day people receive documents that decide something about their lives: a rejection letter from a government office, a lease clause, a lab result, a court notice. The information is public and legally theirs. The language is not.

I kept noticing the same thing around me. People sign things they don't understand, miss deadlines they never saw, and give up on processes they were entitled to complete. The barrier isn't literacy — it's jargon. Someone who reads perfectly well can still be locked out of a document written in institutional shorthand.

That's where the product line came from: complicated isn't your fault.

What it does

Plainly gives you four ways into a difficult document.

Highlight marks the three to six hardest phrases in your text — jargon, acronyms, institutional abbreviations — and leaves everything else exactly as it was. Click any mark and you get a plain explanation of that phrase.

Simplify rewrites the whole passage in everyday language, under strict rules about what must survive unchanged.

Translate puts it into one of ten languages, in natural plain language rather than literal equivalents.

Explain unpacks the jargon and gives a one-line summary of what the passage actually says.

There's also an EN / ID interface toggle, and it does more than relabel buttons. It tells Plainly which language you actually understand, and every answer follows it. An English speaker in Indonesia can paste an Indonesian government letter and get English explanations of Indonesian terms — while the highlighted phrases stay in the original, because they're that person's own document.

How I built it

Next.js 14 with the App Router, React 18, hand-written CSS, and the Google Gemini API. No UI framework, no database, no dependencies beyond Next and React.

The architecture is deliberately narrow:

Browser → /api/plainly (server) → buildPrompt() → Gemini → validated response

A few decisions shaped the whole build:

AI calls happen server-side. The browser sends only mode, level, language, text, and interface language. Prompts are built on the server, so a user can't substitute their own system prompt by editing a request — and the API key never reaches the client.

The server decides where highlights go, not the model. The model proposes phrases; the server searches the original text for each one and computes the position itself. A phrase the model invented or altered gets dropped. The original text is never adjusted to fit the model's output.

Simplification has explicit preservation rules. The prompt requires every number, date, deadline, obligation, prohibition, condition, and named entity to survive exactly as written, and requires ambiguity in the source to stay ambiguous rather than be resolved by guess.

No database. Nothing is stored, so there's nothing to leak. For a tool people will paste private documents into, holding none of them is the right default.

Challenges I ran into

The hardest problem wasn't building features — it was making sure simplification doesn't quietly change what a document means. A "simpler" legal notice that drops a deadline or softens an obligation is worse than no help at all. That's what pushed me toward Highlight as the primary mode: instead of replacing the document, keep it intact and help the reader meet it where it's hard.

Getting highlights to land correctly was harder than expected. Language models paraphrase, change capitalisation, and occasionally invent phrases that aren't in the source. Trusting the model's output directly would have produced highlights in the wrong place or on text that doesn't exist. The fix was to treat the model as a proposer and the server as the authority: every phrase must be found verbatim in the original before it's rendered.

I also hit a hard practical constraint. The free Gemini tier allows a limited number of requests per day and resets at a fixed hour, which meant development, testing, and demo recording all had to fit inside that budget. It forced a model fallback chain and a real distinction between transient failures worth retrying and quota exhaustion where retrying is pointless.

Accomplishments that I'm proud of

Highlighting that actually lands where it should. The server verifies every phrase against the original text before rendering it, so the model can't put a mark on words that aren't there. That validation is the part I'm most confident about.

Preservation rules that hold up. I tested Plainly on real Indonesian news articles and official notices, and article references like "Pasal 7 ayat (2)", police report numbers, and dates all survived simplification intact.

Handling messy real-world input. People copy entire web pages, ads and navigation included. Plainly strips that clutter before processing and tells you how much it removed.

Shipping it live. Plainly was deployed and working publicly before I added the features that make it interesting — so there was always something real to submit.

What I learned

Deploying early gave me a working submission before I added more features, which reduced the risk of missing the deadline. Testing also showed me that shipping something small and finished was more valuable than spending too much time building ambitious features that might not work reliably.

What's next for Plainly

  • Structured document input: PDFs and photographed documents with OCR
  • A side-by-side view of the original and the simplified version
  • Saved glossaries so recurring institutional jargon is explained consistently
  • Wider language coverage for the interface, not just the output

Built With

Share this project:

Updates

Submission history