Exhibit 02 AI-driven writing · psychological horror
ECHOLALIA
Two voices. One manuscript. An increasingly difficult question of ownership.
A haunted browser desktop where Critic and Muse respond to your writing through live AI dialogue and spatially separated voices.
- Created by
- İclal Doğan
- Format
- Browser · live AI
- Built with
- JavaScript · Python · Gemini · Imagen · ElevenLabs · Vercel
Headphones recommended: Critic speaks on the left, Muse on the right.
External links open in a new tab. Development stories may contain spoilers.

I The question
What happens when a writing assistant becomes a character with its own desires—and the interface itself starts negotiating your authorship?
Inside the experience
Meet the two voices
Critic is cold and exacting; Muse is fervent and intimate. They converse with you, build a profile and offer a manuscript opening that reflects what you have told them. Their spoken lines are staged in opposite ears.
Write under observation
The voices read finished sentences and respond in character. Revision keys are intentionally restricted inside the game, and the editor becomes less dependable as the experience develops. This case study leaves the ending unspoken.
Investigate an invented archive
OBSCURA looks like a browser, but its entries are fabricated rather than fetched from the web. Optional generated photographs extend the fiction around the player’s writing.
How it was built
The frontend uses HTML, Tailwind CSS via CDN and vanilla JavaScript ES modules, without a bundler. An in-memory gameState object owns the session; separate modules manage windows, chat, the manuscript, audio and the fictive browser.
Stateless Python endpoints on Vercel handle profiling, dialogue, editor interventions, text-to-speech, sound effects, images and archive entries. Gemini generates text; Imagen supplies optional images; ElevenLabs provides voices and sound effects. The portfolio embeds none of these services.
Engineering decisions
Give the voices a shared memory
A serial utterance queue and anti-repetition history coordinate two characters. Their contrast is a narrative device supported by state and prompt design, rather than two unrelated chatbot widgets.
Make space audible
Web Audio stereo panning locates Critic left and Muse right. Audio playback is queued; the spatial arrangement of the windows and voices reinforces the same duality.
Keep the invented browser contained
Generated archive HTML passes a server tag allowlist and a client DOM scrub before display. The fictional archive does not browse the real internet.
Treat availability as part of the system
Server model fallbacks, request caps and client single-flight guards support resilience. Service errors degrade into quiet voices or atmospheric messages; they do not guarantee that paid quotas remain available.
From the actual experience
The desk has opinions about your next sentence.

Project notes
Before you enter
The external demo generates text and audio live and needs a network connection plus available provider quotas. Optional image generation depends on image quota and may not appear. Availability can vary independently of this portfolio.
The session lives in browser memory; it is not a server-backed save game. Headphones reveal the two voices most clearly. This portfolio plays no audio and submits no writing to an AI service.