The three-card spread
Each reading uses a traditional tarot spread with three positions:Past — What brought you here
The first card reveals influences from your past that are still affecting your current situation. It provides context for understanding where you are today.
Present — What's happening now
The second card reflects your current circumstances and the energies surrounding you at this moment. It asks you to pay attention to how you’re handling the situation.
Card drawing mechanism
The deck consists of 78 cards total:- 22 Major Arcana — Significant life themes and spiritual lessons (The Fool, The Magician, Death, etc.)
- 56 Minor Arcana — Everyday situations across four suits:
- Wands (Bastos) — Creativity, passion, action, inspiration
- Pentacles (Oros) — Material wealth, career, practical matters
- Cups (Copas) — Emotions, relationships, intuition
- Swords (Espadas) — Thoughts, conflicts, truth, mental clarity
How cards are selected
ThedrawCards() function in src/data/cards.ts:647 randomly selects three cards:
src/data/cards.ts
AI interpretation flow
Once you submit your consultation, here’s what happens:Form submission and validation
Your name and question are validated client-side:
src/components/TarotForm.astro
- Name: 1-60 characters
- Question: 1-500 characters
Usage limit check
Before drawing cards, the system checks if you’ve exceeded the daily limit:The limit is stored in
src/components/TarotForm.astro
localStorage under the key tarot_usage and resets after 24 hours.Three cards are drawn
The
drawCards(3) function randomly selects three cards from the 78-card deck and determines if each is reversed:src/components/TarotForm.astro
Cards flip with 3D animation
Cards flip one by one with a 700ms delay between each:The 3D flip effect uses
src/components/TarotForm.astro
transform-style: preserve-3d in pure CSS.Server action processes the reading
The form data and drawn cards are sent to the server action at
src/actions/index.ts:30:src/actions/index.ts
AI generates the interpretation
The server constructs a detailed prompt for Google Gemini:The prompt includes:
src/actions/index.ts
- Your name and question
- Each card’s position, name, orientation, description, and keywords
- Instructions for Seraphina’s tone (warm, direct, practical)
- Maximum length of 250 words
- Structure: greeting, past, present, future, advice
Fallback system handles errors
If the AI fails, the system tries multiple models:If all models fail, a static template reading is generated from
src/actions/index.ts
src/actions/index.ts:15.Reading appears paragraph by paragraph
The text is split into paragraphs and displayed with staggered fade-in animations:Each paragraph fades in 0.25 seconds after the previous one.
src/components/TarotForm.astro
Card data structure
Each card in the deck contains:src/data/cards.ts
src/data/cards.ts
Seraphina’s personality
The AI tarot reader is named Seraphina and follows specific guidelines fromsrc/actions/index.ts:53:
- Tone: Warm but direct and practical
- Style: Clear language, not overly mystical
- Goal: Provide actionable advice the person can apply immediately
- Constraints: Won’t answer health, medical diagnosis, or pregnancy questions
- Length: Maximum 250 words per reading
- Structure: Greeting → Past → Present → Future → Practical advice
If you ask about health, diseases, medical diagnoses, or pregnancy, Seraphina will politely decline and recommend consulting a medical professional instead.
Usage limit system
The 5-consultations-per-day limit works as follows:- Storage: Client-side in
localStorageunder keytarot_usage - Window: 24 hours (86400000 milliseconds)
- Reset: Automatic after 24 hours from first use
- Data stored:
The limit is per browser/device. Clearing your browser’s
localStorage will reset the counter, but this is intentional to keep the implementation simple and privacy-focused.Next steps
Get started
Install and run the application locally
Live demo
Try the production version