Arcana
Create a custom tarot deck and get a reading
The Tower. The Emperor. The Hierophant. Whether or not you believe in its power to actually tell the future, there is something inexplicably powerful about a tarot deck. Each card is an archetype, a single card standing in for a whole shape of human experience - sudden ruin, immovable authority, inherited doctrine. Strip away the mysticism and what's left is a remarkably complete map of meaning, just twenty-two points wide. The insight behind Arcana is that this map isn't unique to tarot. Every domain has its own Tower, its own Emperor, its own Hierophant - you just have to go looking. Name a theme, and Arcana finds them.
Arcana is a Gradio space that takes as input a word describing some category — be it physics, Greek gods or breakfast foods — and then generates a whole tarot deck's worth of cards from objects belonging to said category. Why do this at all? Sometimes, the juxtaposition of everyday objects and mysticism results in very entertaining combinations. For instance, I present the following:
On the other hand, the cards sometimes do inspire a genuine sense of meaning. Following the card generation phase, Arcana proceeds to read the cards and tell your fortune. Drawing a "phase transition" card while you're agonising over whether to leave something stable, or a "whale fall" card while you're tethered to a grief that, even now, is quietly feeding the life growing up around it, could be just the thing that gives you the missing words to make sense of whatever situation you feel trapped by.
This space utilizes two modalities of generative AI, text and images, both load-bearing for the experience.The text model is Qwen3-14B (unsloth/Qwen3-14B-GGUF, Apache-2.0); the image model is FLUX.2-klein (black-forest-labs/FLUX.2-klein-9B, a ~9B distilled model). Both run locally on the Space's own GPU via Hugging Face ZeroGPU, so there are no external inference APIs, and nothing the models produce ever leaves the Space.Qwen runs on a llama.cpp backend, served as a 4-bit quantized GGUF. Beyond letting a 14B model fit comfortably in a single ZeroGPU allocation, this lets me constrain generation with a JSON-schema grammar: I hand it the exact shape I want and the sampler is forced to obey it, so the model emits valid, correctly-typed JSON from the first token. For a pipeline that passes structured objects between stages, that reliability is the whole game.
Qwen has three distinct tasks:
The Designer (mapping): Given the theme, the Designer maps each of the 22 Major Arcana onto a concept from that theme, with a one-line justification and a single shared visual style for the deck. Its system prompt carries the 22 archetypes, their canonical meanings, and two worked example decks; the user prompt is little more than the theme. The result is validated before anything downstream sees it (22 distinct concepts, full 0 to 21 coverage, no echoes of the arcana names), and it carries no meanings or art: the Designer produces only the skeleton.
The Scribe (meaning + art): The Scribe takes that skeleton and, per card, invents the rest from scratch: an essence, an upright meaning, a reversed meaning, and an art brief. It is given the concept, its justification, and the seeding archetype's canonical meaning, but the archetype only sets the emotional shape of the meaning; everything else is built from what the concept actually is, which is what keeps the art from collapsing into generic tarot cliché.
The Reader (oracle): Once a deck exists, the Reader runs the fortune. It draws a spread and interprets the cards progressively, each reading conditioned on the question and the cards already turned, before a final pass weaves them into one synthesis. This stage is free prose rather than JSON.
FLUX paints each card from the art brief the Scribe wrote, concatenated with the deck's shared style and a fixed global style clause so all 22 cards share one look; a per-card seed keeps that cohesion tight. It renders only the central illustration: the gold frame, title, and numeral are composited on afterwards with Pillow (the frame is built once and reused).
A guided, linear flow: The interface is one linear path with a few branch points, so the user is walked through a tale rather than dropped onto a dashboard: name a theme and watch the deck conjure, or open a saved deck, then step into a reading where the cards turn one at a time.
Four GPUs in parallel: Four concurrent ZeroGPU allocations are requested, giving the Space enough compute to run in decent time while still absolving the need for any external API. This is also why the Designer and Scribe are kept as separate calls: the 22 cards are split round-robin into four chunks, one per GPU worker, so four Scribe calls write meanings and art briefs at once, and the painting is then fanned out the same way, four cards rendering concurrently instead of 22 in series.
Lazy card rendering: During the paint phase, a small GUI trick hides the wait. The deck view opens the moment the Scribe finishes, already showing every card's name and meaning; each illustration then streams into its card as it finishes rendering. The user reads the freshly written deck while it quietly paints itself in.
I learned a lot building this. I'd never touched llama.cpp before, and I'd done very little GUI work of any kind, so a fair amount of this was new ground. What surprised me most was Gradio: I went in expecting something serviceable-but-plain, and came away genuinely impressed by how polished a Gradio app can be made to look. I'm keen to see how far I can push that.
If there's one takeaway that transfers cleanly to text, though, it is that the newest models are not automatically the best models. Before settling on Qwen, I tried a handful of others, and some of the newer, agentic-tuned ones turned out to be a poor fit: handed a task that just needed a clean JSON mapping, they would instinctively reach for tool calls and burn through their context trying to orchestrate tools that weren't there, rather than simply producing the output. Those models are formidable at what they were built for; they were just built for something else. It is worth spending the time up front to test which model actually suits your specific task before committing to one.
HF Space: https://huggingface.co/spaces/build-small-hackathon/arcana
Demo Video: https://youtu.be/j-yLxVL9WPY?si=sAywPlIjSWg3TieR
Create a custom tarot deck and get a reading
More from this author