+ Your Rising Sign (Ascendant) is the zodiac sign that was rising on the
+ eastern horizon at the moment of your birth. It represents how you
+ present yourself to the world and your first impressions.
+
+
+
+)}
+```
+
+**2. "What This Means for Me" Expandable Sections**
+
+Every major section should have an expandable "What this means for me" card:
+
+```tsx
+
+
+
setExpanded(!expanded)}
+ >
+
Your Planetary Positions
+
+
+
+ {expanded && (
+
+
+ 💡 What This Means for You
+
+
+ Each planet represents a different part of your personality and life.
+ The zodiac sign tells you HOW that planet expresses itself, and the
+ house shows WHERE in your life it plays out. For example, Venus in
+ Leo in the 5th house means you express love (Venus) dramatically and
+ confidently (Leo) in romance and creativity (5th house).
+
+
+ )}
+
+
+```
+
+**3. Onboarding Tour (First-Time User Experience)**
+
+Create a guided tour that appears for first-time users:
+
+New file: `/home/user/Astro/components/OnboardingTour.tsx`
+
+Steps:
+1. Welcome to your dashboard!
+2. Here's your daily guidance (point to hero section)
+3. This is your Big Three (point to sun/moon/rising)
+4. Explore different sections using these tabs
+5. Need help? Click the AI Assistant anytime
+6. You can export and share your chart
+
+**4. Glossary/Help Center**
+
+Add a help center accessible from the header:
+
+New component: `/home/user/Astro/components/HelpCenter.tsx`
+
+Sections:
+- **Astrology Basics** - Signs, planets, houses, aspects
+- **Understanding Your Chart** - How to read natal chart
+- **Astrocartography Guide** - What are planetary lines?
+- **Numerology Explained** - Life path, destiny, cycles
+- **Chinese Astrology** - Four Pillars system explained
+- **FAQ** - Common questions
+
+**5. Contextual "Learn More" Buttons**
+
+Throughout the dashboard, add "Learn More" buttons that open relevant help articles:
+
+```tsx
+
+```
+
+### Critical UX Issue #5: Mobile Responsiveness
+
+**PROBLEM:** Some components are cramped on mobile, globe performance issues on mobile devices.
+
+**SOLUTION:** Optimize for mobile with responsive layouts and simplified mobile views.
+
+#### Mobile-Specific Improvements
+
+**1. Responsive Tab Navigation**
+
+Current horizontal tab list doesn't work well on mobile.
+
+**Solution:** Convert to dropdown menu on mobile:
+
+```tsx
+{/* Desktop: Horizontal tabs */}
+
+ {tabs.map(tab => (
+
+ ))}
+
+
+{/* Mobile: Dropdown */}
+
+
+
+```
+
+**2. Simplified Globe on Mobile**
+
+On mobile devices, show a simplified 2D map instead of the heavy 3D globe:
+
+```tsx
+const isMobile = window.innerWidth < 768;
+
+{isMobile ? (
+
+) : (
+ }>
+
+
+)}
+```
+
+**3. Mobile-Optimized Card Layouts**
+
+Stack cards vertically on mobile instead of grid layouts:
+
+```tsx
+
+ {/* Cards automatically stack on mobile */}
+
+```
+
+**4. Touch-Friendly Interactive Elements**
+
+Ensure all buttons and interactive elements are at least 44x44px for touch targets:
+
+```tsx
+
+```
+
+---
+
+## 🚀 NAVIGATION & USER FLOW ENHANCEMENTS
+
+### Complete User Journey Map
+
+#### Journey 1: New User First Visit
+
+**Current Flow:**
+```
+Input Form → Loading → Dashboard (lost) → Close tab
+```
+
+**Improved Flow:**
+```
+1. Landing Page (Input Form)
+ ↓
+2. Loading Screen (with educational tips)
+ ↓
+3. Welcome Screen (first-time only)
+ "Welcome! Here's what you'll discover..."
+ [Start Tour] [Skip to Dashboard]
+ ↓
+4. Dashboard - Overview Tab
+ → Onboarding tour highlights key sections
+ ↓
+5. User explores with confidence
+ → Help tooltips available everywhere
+ → Can always return to overview
+ → Clear navigation at all times
+```
+
+#### Journey 2: Returning User - Daily Check
+
+**Desired Flow:**
+```
+1. User opens app (remembers last session)
+ ↓
+2. Dashboard - Overview Tab (Auto-focused on "Today's Guidance")
+ → See daily horoscope immediately
+ → Check current transits
+ → View personal day number
+ ↓
+3. Quick actions available:
+ → Chat with AI about today's energy
+ → Explore best locations for activities
+ → View weekly/monthly forecasts
+```
+
+#### Journey 3: Deep Exploration - Understanding Chart
+
+**Desired Flow:**
+```
+1. User on Overview Tab
+ ↓
+2. Clicks "View Full Chart" button
+ ↓
+3. Chart Tab opens
+ → Sees natal chart wheel
+ → Aspect grid below
+ → Numerology panel on side
+ → Four Pillars display
+ ↓
+4. Clicks planet position (e.g., "Mars in Capricorn, 10th House")
+ ↓
+5. Options appear:
+ → [Ask AI to Explain] → Opens chat with pre-filled question
+ → [Learn More] → Opens help article about Mars
+ → [See Aspects] → Highlights aspects in grid
+```
+
+#### Journey 4: Location Exploration
+
+**Desired Flow:**
+```
+1. User on Overview Tab
+ ↓
+2. Sees "Best Places for You" card
+ ↓
+3. Clicks "Explore Locations" button
+ ↓
+4. Lines Tab opens with globe view
+ ↓
+5. User can:
+ → Click planetary lines to see effects
+ → Use Scout tab to search specific cities
+ → View relocation analysis for current city
+ → Compare multiple locations
+ ↓
+6. Clear navigation:
+ → Back to Overview button always visible
+ → Breadcrumb shows: Dashboard > Locations > Lines
+```
+
+### Navigation Hierarchy
+
+**Proposed App Structure:**
+
+```
+CELESTIA
+│
+├── 🏠 HOME (Overview Dashboard)
+│ ├── Today's Guidance (Hero Section)
+│ ├── Your Cosmic Identity (Big Three)
+│ ├── Quick Insights (Cards)
+│ └── Explore More (Links to all sections)
+│
+├── 📊 YOUR CHART
+│ ├── Natal Chart Wheel
+│ ├── Planetary Positions Table
+│ ├── Aspect Grid
+│ ├── House System Selector
+│ └── Chart Settings
+│
+├── 📅 FORECASTS
+│ ├── Daily Horoscope
+│ ├── Weekly Forecast (NEW)
+│ ├── Monthly Forecast (NEW)
+│ ├── Yearly Forecast (NEW)
+│ ├── Current Transits
+│ ├── Upcoming Transits Calendar
+│ └── Progressions Timeline
+│
+├── 🔢 NUMEROLOGY
+│ ├── Core Numbers (Life Path, Destiny, Soul Urge)
+│ ├── Cycles & Pinnacles
+│ ├── Personal Year/Month/Day
+│ ├── Daily Numerology Forecast
+│ └── Numerology Calendar (NEW)
+│
+├── 🐉 CHINESE ASTROLOGY
+│ ├── Four Pillars of Destiny
+│ ├── Luck Pillars Timeline
+│ ├── Element Balance
+│ ├── Annual Forecast
+│ └── Monthly Forecast
+│
+├── 💕 RELATIONSHIPS
+│ ├── Synastry (Compatibility)
+│ ├── Composite Chart (NEW - full implementation)
+│ ├── Compare Multiple Charts
+│ └── Relationship Forecast (NEW)
+│
+├── 🌍 LOCATIONS
+│ ├── Astrocartography Map (Lines View)
+│ ├── Relocation Analysis (Current City)
+│ ├── City Scout (Search & Analyze)
+│ ├── Compare Locations (NEW)
+│ ├── Parans (NEW)
+│ └── Local Space (NEW)
+│
+├── 🤖 AI ASSISTANT (Full-Page Chat)
+│ ├── Conversation Interface
+│ ├── Pre-built Prompts
+│ ├── Chat History
+│ └── Export Conversation
+│
+├── 💾 MY CHARTS
+│ ├── Saved Charts Library (INTEGRATE SavedChartsManager)
+│ ├── Import Chart
+│ ├── Export Chart
+│ └── Share Chart
+│
+└── ⚙️ SETTINGS & HELP
+ ├── House System Preference
+ ├── Theme (Dark/Light)
+ ├── Timezone Settings
+ ├── Help Center
+ ├── Glossary
+ └── About
+```
+
+### Implementing Better Menu Structure
+
+**Replace current horizontal tab list with grouped mega-menu:**
+
+**Code Pattern for New Navigation:**
+
+```tsx
+// Dashboard.tsx - Improved navigation
+
+const TAB_GROUPS = [
+ {
+ label: 'About Me',
+ icon: User,
+ tabs: [
+ { id: 'overview', label: 'Overview', icon: Home },
+ { id: 'chart', label: 'Your Chart', icon: Star },
+ { id: 'numerology', label: 'Numerology', icon: Hash },
+ { id: 'four-pillars', label: 'Four Pillars', icon: Flame }
+ ]
+ },
+ {
+ label: 'Forecasts',
+ icon: Calendar,
+ tabs: [
+ { id: 'daily', label: 'Daily', icon: Sun },
+ { id: 'weekly', label: 'Weekly', icon: Calendar },
+ { id: 'monthly', label: 'Monthly', icon: Moon },
+ { id: 'yearly', label: 'Yearly', icon: Sparkles },
+ { id: 'transits', label: 'Transits', icon: Activity },
+ { id: 'progressions', label: 'Progressions', icon: TrendingUp }
+ ]
+ },
+ {
+ label: 'Relationships',
+ icon: Heart,
+ tabs: [
+ { id: 'synastry', label: 'Compatibility', icon: Heart },
+ { id: 'composite', label: 'Composite', icon: Users },
+ { id: 'compare', label: 'Compare Charts', icon: GitCompare }
+ ]
+ },
+ {
+ label: 'Locations',
+ icon: Globe,
+ tabs: [
+ { id: 'relocation', label: 'Current City', icon: MapPin },
+ { id: 'lines', label: 'Map View', icon: Map },
+ { id: 'scout', label: 'City Scout', icon: Search }
+ ]
+ },
+ {
+ label: 'More',
+ icon: MoreHorizontal,
+ tabs: [
+ { id: 'assistant', label: 'AI Assistant', icon: MessageSquare },
+ { id: 'saved-charts', label: 'My Charts', icon: BookMarked },
+ { id: 'help', label: 'Help', icon: HelpCircle }
+ ]
+ }
+];
+
+// Render grouped navigation
+
+```
+
+---
+
+## 🔧 FEATURE GAPS & ADDITIONS
+
+This section details all missing features that need to be implemented to match industry standards.
+
+### Category 1: Critical Astrology Features (HIGH PRIORITY)
+
+#### 1.1 House Systems - Complete Implementation
+
+**FILE:** `/home/user/Astro/services/astronomyService.ts`
+
+**CURRENT STATUS:** Only Equal House and Whole Sign work. Placidus, Koch, Campanus, Regiomontanus, and Porphyry are not implemented.
+
+**IMPORTANCE:** HIGH - Placidus is the most popular house system among professional astrologers.
+
+**IMPLEMENTATION:**
+
+Placidus house system requires calculating cusps based on trisection of semi-arcs. This is complex but astronomy-engine provides some helpers.
+
+**Code Template:**
+
+```typescript
+// Add to astronomyService.ts
+
+function calculatePlacidusHouses(
+ birthDate: Date,
+ latitude: number,
+ longitude: number,
+ ascendant: number
+): number[] {
+ // Placidus divides the time it takes for the ecliptic to travel
+ // from IC to Ascendant and from Ascendant to MC into thirds
+
+ const houseCusps: number[] = [ascendant]; // House 1
+
+ // Calculate RAMC (Right Ascension of MC)
+ const ramc = calculateRAMC(birthDate, longitude);
+
+ // Calculate MC (10th house cusp)
+ const mc = calculateMidheaven(birthDate, latitude, longitude);
+ houseCusps[9] = mc; // House 10
+
+ // Calculate other cusps using Placidus formula
+ // This involves spherical trigonometry
+
+ for (let house = 11; house <= 12; house++) {
+ const cusp = calculatePlacidusIntermediateCusp(
+ ramc,
+ latitude,
+ house,
+ mc
+ );
+ houseCusps[house - 1] = cusp;
+ }
+
+ // Houses 2-3 (trisect IC to Ascendant)
+ const ic = (mc + 180) % 360;
+ for (let house = 2; house <= 3; house++) {
+ const cusp = calculatePlacidusIntermediateCusp(
+ ramc,
+ latitude,
+ house,
+ ic
+ );
+ houseCusps[house - 1] = cusp;
+ }
+
+ // Opposite houses (4-6, 7-9)
+ houseCusps[3] = ic; // House 4
+ houseCusps[6] = (ascendant + 180) % 360; // House 7 (Descendant)
+
+ for (let i = 1; i <= 3; i++) {
+ houseCusps[i + 3] = (houseCusps[i] + 180) % 360; // Houses 5, 6, 8, 9
+ }
+
+ return houseCusps;
+}
+
+function calculatePlacidusIntermediateCusp(
+ ramc: number,
+ latitude: number,
+ house: number,
+ angle: number
+): number {
+ // Complex spherical trigonometry calculation
+ // See: https://www.astro.com/swisseph/swisseph.htm
+ // Formula from Swiss Ephemeris documentation
+
+ const latRad = latitude * Math.PI / 180;
+ const obliquity = 23.4397; // Earth's axial tilt
+ const oblRad = obliquity * Math.PI / 180;
+
+ // Trisection factor
+ let f: number;
+ if (house === 11) f = 1/3;
+ else if (house === 12) f = 2/3;
+ else if (house === 2) f = 1/3;
+ else if (house === 3) f = 2/3;
+ else f = 0;
+
+ // Semi-arc formula
+ const D = Math.atan(
+ Math.tan(latRad) * Math.tan(oblRad)
+ );
+
+ const semiArc = f * D;
+
+ // Calculate cusp longitude
+ const cusp = ramc + semiArc * 180 / Math.PI;
+
+ return (cusp % 360 + 360) % 360;
+}
+
+function calculateRAMC(birthDate: Date, longitude: number): number {
+ // RAMC = Sidereal Time at Greenwich + longitude
+ const st = calculateSiderealTime(birthDate);
+ const ramc = st + longitude;
+ return (ramc % 360 + 360) % 360;
+}
+
+function calculateSiderealTime(date: Date): number {
+ // Calculate Greenwich Sidereal Time
+ // Formula from astronomical algorithms
+ const J2000 = Date.UTC(2000, 0, 1, 12, 0, 0);
+ const jd = date.getTime() / 86400000 + 2440587.5;
+ const T = (jd - 2451545.0) / 36525;
+
+ let gst = 280.46061837 + 360.98564736629 * (jd - 2451545.0)
+ + 0.000387933 * T * T
+ - T * T * T / 38710000;
+
+ return (gst % 360 + 360) % 360;
+}
+```
+
+**ALTERNATIVE:** Use Swiss Ephemeris library more fully
+
+The swisseph package is already installed but not fully integrated. Consider using it:
+
+```typescript
+import swisseph from 'swisseph';
+
+// Initialize Swiss Ephemeris
+swisseph.swe_set_ephe_path('/path/to/ephemeris');
+
+function calculateHousesWithSwisseph(
+ birthDate: Date,
+ latitude: number,
+ longitude: number,
+ houseSystem: string
+): number[] {
+ const julianDay = swisseph.swe_julday(
+ birthDate.getFullYear(),
+ birthDate.getMonth() + 1,
+ birthDate.getDate(),
+ birthDate.getHours() + birthDate.getMinutes() / 60,
+ swisseph.SE_GREG_CAL
+ );
+
+ // House system codes: 'P' = Placidus, 'K' = Koch, 'C' = Campanus, etc.
+ const systemCode = houseSystem === 'Placidus' ? 'P' :
+ houseSystem === 'Koch' ? 'K' :
+ houseSystem === 'Campanus' ? 'C' : 'E';
+
+ const houses = swisseph.swe_houses(
+ julianDay,
+ latitude,
+ longitude,
+ systemCode
+ );
+
+ return houses.house; // Array of 12 house cusps
+}
+```
+
+**UPDATE HouseSystemSelector Component:**
+
+File: `/home/user/Astro/components/HouseSystemSelector.tsx`
+
+Add all house systems to the selector once implemented:
+
+```tsx
+const HOUSE_SYSTEMS = [
+ { value: 'Placidus', label: 'Placidus', description: 'Most popular system' },
+ { value: 'Koch', label: 'Koch', description: 'Birthplace system' },
+ { value: 'Equal', label: 'Equal', description: 'Simple and ancient' },
+ { value: 'Whole Sign', label: 'Whole Sign', description: 'Hellenistic astrology' },
+ { value: 'Campanus', label: 'Campanus', description: 'Space-based division' },
+ { value: 'Regiomontanus', label: 'Regiomontanus', description: 'Medieval system' },
+ { value: 'Porphyry', label: 'Porphyry', description: 'Equal divisions of quadrants' }
+];
+```
+
+
+#### 1.2 Missing Celestial Points (Chiron, Nodes, Lilith, Part of Fortune)
+
+**FILE:** `/home/user/Astro/services/astronomyService.ts`
+
+**CURRENT STATUS:** Types defined for Chiron and Nodes, but not calculated. Lilith and Part of Fortune not defined.
+
+**IMPORTANCE:** HIGH - These are standard in professional astrology software.
+
+**IMPLEMENTATION:**
+
+**1. Add Chiron to Planetary Calculations**
+
+Chiron is already supported by astronomy-engine:
+
+```typescript
+// In calculatePlanetaryPositions function, add to PLANETS array:
+const PLANETS = [
+ 'Sun', 'Moon', 'Mercury', 'Venus', 'Mars',
+ 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Pluto',
+ 'Chiron' // ADD THIS
+];
+
+// astronomy-engine already supports Chiron as a body
+// No special handling needed - it will work automatically!
+```
+
+**2. Calculate North/South Nodes**
+
+The Lunar Nodes require special calculation:
+
+```typescript
+// Add to astronomyService.ts
+
+export function calculateLunarNodes(birthDate: Date): {
+ northNode: PlanetaryPosition;
+ southNode: PlanetaryPosition;
+} {
+ // The North Node (Rahu) is the point where the Moon crosses the ecliptic northward
+ // astronomy-engine doesn't directly provide nodes, so we calculate them
+
+ // Get Moon's orbital elements
+ const moonLon = Astronomy.EclipticLongitude('Moon', birthDate);
+
+ // The lunar nodes regress through the zodiac, completing a cycle in ~18.6 years
+ // Formula for mean lunar node (simplified)
+ const T = (julianDate(birthDate) - 2451545.0) / 36525;
+ const meanNode = 125.04452 - 1934.136261 * T + 0.0020708 * T * T + T * T * T / 450000;
+
+ const northNodeLon = ((meanNode % 360) + 360) % 360;
+ const southNodeLon = (northNodeLon + 180) % 360;
+
+ const northZodiac = getZodiacSign(northNodeLon);
+ const southZodiac = getZodiacSign(southNodeLon);
+
+ // Nodes don't have house placement traditionally, but we can calculate it
+ const northHouse = calculateHouseForPosition(northNodeLon, birthDate, 0, 0);
+ const southHouse = calculateHouseForPosition(southNodeLon, birthDate, 0, 0);
+
+ return {
+ northNode: {
+ planet: 'North Node',
+ sign: northZodiac.sign,
+ degree: northZodiac.degree,
+ absoluteDegree: northNodeLon,
+ house: northHouse,
+ retrograde: true, // Nodes are always retrograde
+ summary: `North Node in ${northZodiac.sign}`
+ },
+ southNode: {
+ planet: 'South Node',
+ sign: southZodiac.sign,
+ degree: southZodiac.degree,
+ absoluteDegree: southNodeLon,
+ house: southHouse,
+ retrograde: true,
+ summary: `South Node in ${southZodiac.sign}`
+ }
+ };
+}
+
+function julianDate(date: Date): number {
+ return date.getTime() / 86400000 + 2440587.5;
+}
+```
+
+**3. Calculate Black Moon Lilith**
+
+```typescript
+// Add to astronomyService.ts
+
+export function calculateLilith(birthDate: Date): PlanetaryPosition {
+ // Black Moon Lilith is the lunar apogee (farthest point of Moon's orbit)
+ // This is the "Mean Lilith" calculation (most commonly used)
+
+ const T = (julianDate(birthDate) - 2451545.0) / 36525;
+
+ // Mean Lilith formula (from astrology references)
+ const lilithLon = 83.35324 + 40.66246 * T;
+ const normalizedLon = ((lilithLon % 360) + 360) % 360;
+
+ const zodiac = getZodiacSign(normalizedLon);
+ const house = calculateHouseForPosition(normalizedLon, birthDate, 0, 0);
+
+ return {
+ planet: 'Lilith',
+ sign: zodiac.sign,
+ degree: zodiac.degree,
+ absoluteDegree: normalizedLon,
+ house: house,
+ retrograde: false,
+ summary: `Lilith in ${zodiac.sign}`
+ };
+}
+```
+
+**4. Calculate Part of Fortune**
+
+```typescript
+// Add to astronomyService.ts
+
+export function calculatePartOfFortune(
+ ascendantLon: number,
+ sunLon: number,
+ moonLon: number,
+ isDayBirth: boolean
+): PlanetaryPosition {
+ // Part of Fortune formula:
+ // Day birth: Ascendant + Moon - Sun
+ // Night birth: Ascendant + Sun - Moon
+
+ let fortuneLon: number;
+ if (isDayBirth) {
+ fortuneLon = ascendantLon + moonLon - sunLon;
+ } else {
+ fortuneLon = ascendantLon + sunLon - moonLon;
+ }
+
+ const normalizedLon = ((fortuneLon % 360) + 360) % 360;
+ const zodiac = getZodiacSign(normalizedLon);
+ const house = calculateHouseForPosition(normalizedLon, Date.now(), 0, 0);
+
+ return {
+ planet: 'Part of Fortune',
+ sign: zodiac.sign,
+ degree: zodiac.degree,
+ absoluteDegree: normalizedLon,
+ house: house,
+ retrograde: false,
+ summary: `Part of Fortune in ${zodiac.sign}`
+ };
+}
+
+// Helper to determine if birth was during day or night
+function isDayBirth(sunLon: number, ascendantLon: number): boolean {
+ // Day if Sun is above horizon (in houses 7-12)
+ // Simplified: if Sun is within 180° ahead of Ascendant
+ const diff = ((sunLon - ascendantLon + 360) % 360);
+ return diff < 180;
+}
+```
+
+**5. Update Types**
+
+File: `/home/user/Astro/types.ts`
+
+Add to PlanetName type if not present:
+
+```typescript
+export type PlanetName =
+ | 'Sun' | 'Moon' | 'Mercury' | 'Venus' | 'Mars'
+ | 'Jupiter' | 'Saturn' | 'Uranus' | 'Neptune' | 'Pluto'
+ | 'Chiron' | 'North Node' | 'South Node' | 'Lilith' | 'Part of Fortune'
+ | 'Ascendant' | 'Midheaven' | 'Descendant' | 'IC';
+```
+
+**6. Update Dashboard to Display New Points**
+
+In Dashboard.tsx, add a special section for "Significant Points":
+
+```tsx
+
+ );
+};
+```
+
+---
+
+## 📄 PAGE-BY-PAGE IMPROVEMENT GUIDE
+
+This section provides detailed improvements for every page/tab in the application.
+
+### Page 1: Input Form (Landing Page)
+
+**FILE:** `/home/user/Astro/components/InputForm.tsx`
+
+**CURRENT STATUS:** Functional but could be more engaging and informative.
+
+**IMPROVEMENTS NEEDED:**
+
+1. **Add Welcome Message & Value Proposition**
+
+```tsx
+// Add before the form
+
+
+ Discover Your Cosmic Blueprint
+
+
+ Enter your birth information to receive a comprehensive astrological analysis
+ including your natal chart, astrocartography map, numerology profile,
+ and personalized AI guidance.
+
+
+```
+
+2. **Add Example/Demo Button**
+
+```tsx
+
+
+function fillDemoData() {
+ setFormData({
+ name: 'Jane Doe',
+ date: '1990-06-15',
+ time: '14:30',
+ place: 'New York, NY, USA',
+ currentLocation: 'Los Angeles, CA, USA'
+ });
+}
+```
+
+3. **Add "Why We Need This" Tooltips**
+
+Next to each field, add info icons explaining why:
+
+```tsx
+
+
+
+
+{showTimeInfo && (
+
+ Birth time is essential for calculating your Rising Sign and house placements.
+ Even approximate times work! If unknown, we'll use noon.
+
+ 🔒 Your data is private and stored locally. We never share your information.
+
+```
+
+5. **Improve Loading Experience**
+
+The current loading screen is good, but add educational tips:
+
+```tsx
+// LoadingScreen.tsx - Add rotating tips
+
+const LOADING_TIPS = [
+ "Did you know? Your Rising Sign changes approximately every 2 hours!",
+ "Astrocartography shows how planetary energies shift based on location.",
+ "Numerology can reveal your life purpose through your birth date.",
+ "The Four Pillars of Destiny provide insights into different life phases.",
+ "Transits show how current planetary positions affect your natal chart."
+];
+
+// Display random tip during loading
+
+ {data.dailyHoroscope?.overallVibe ||
+ "Today brings a blend of energies that invite you to balance action with reflection. The planets support both productivity and introspection."}
+
+ This week brings opportunities for growth and expansion. Pay attention to
+ midweek when Venus forms a harmonious aspect to your natal Sun, bringing
+ positive energy to relationships and creative projects.
+
+ {monthName} is a month of transformation and new beginnings. The planets
+ align to support your personal growth and expansion in key life areas.
+
+
+ {/* Key Dates */}
+
+
Important Dates
+
+
+ New Moon in Sagittarius
+ Dec 12
+
+
+ Mercury Retrograde Begins
+ Dec 13
+
+
+ Full Moon in Cancer
+ Dec 26
+
+
+
+
+
+ {/* Monthly Guidance by Area */}
+
+
+
+
+
+
+
+ {/* Numerology Month */}
+
+
Numerology Insights
+
+ You're in a Personal Month
+ {data.numerology?.daily?.personalMonth || 5}
+
+
+
+ This is a month of change, adventure, and freedom. Embrace new experiences.
+
+
+
+ );
+};
+
+const YearlyForecast: React.FC<{ data: AstroReport; user: UserBirthData }> = ({ data, user }) => {
+ const year = new Date().getFullYear();
+
+ return (
+
+
+
Your Year Ahead
+
{year} Forecast
+
+
+ {/* Year Theme */}
+
+
+
+ Your Theme for {year}
+
+
+ {year} is a year of manifestation and achievement. The planetary alignments
+ support bringing your visions into reality through focused action and strategic planning.
+
+
+ {/* Personal Year Number */}
+
+
Personal Year Number
+
+ {data.numerology?.daily?.personalYear || 3}
+
+
+ A year of creativity, self-expression, and social expansion.
+
+
+
+
+ {/* Quarterly Breakdown */}
+
+
+
+
+
+
+
+ {/* Chinese Astrology - Annual Forecast */}
+
+
+ 🐉
+ Chinese Astrology - Year of the {getChineseYear(year)}
+
+
+ {data.chineseHoroscope?.currentYearForecast ||
+ "This year brings opportunities for growth and transformation. Your Chinese zodiac sign interacts favorably with the year's energy."}
+
+
+
+ Day {safeData.numerology?.daily?.personalDay || 1}
+
+
+
+
+ {/* Cosmic Weather */}
+
+
+
+ Cosmic Weather
+
+
+ {safeData.dailyHoroscope?.overallVibe ||
+ "The cosmos invites you to embrace the day with intention and awareness. Pay attention to synchronicities and trust your intuition."}
+
+
+
+ {/* Quick Insights Grid */}
+
+
+
+
+ Love
+
+
+ {safeData.dailyHoroscope?.love?.substring(0, 60) || 'Open your heart to connection'}...
+
+
+
+
+
+ Career
+
+
+ {safeData.dailyHoroscope?.career?.substring(0, 60) || 'Focus on your goals'}...
+
+
+
+
+
+ Energy
+
+
+ Personal Year {safeData.numerology.daily.personalYear} • {safeData.numerology.daily.dailyForecast.substring(0, 40)}...
+
+
+
+ Personal Day {data.numerology?.daily?.personalDay || 1}
+
+
+
+
+ {/* Overall Vibe */}
+
+
+
+ Today's Cosmic Energy
+
+
+ {data.dailyHoroscope?.overallVibe ||
+ "The cosmos invites you to embrace the day with intention and awareness. Pay attention to synchronicities."}
+
+ This week brings opportunities for growth and expansion. Midweek energy peaks
+ as planetary alignments support both personal and professional endeavors.
+ Stay flexible and open to unexpected opportunities.
+
+ This month emphasizes transformation and new beginnings. The planets
+ align to support your personal growth and expansion in key life areas.
+ Focus on building foundations for long-term success.
+
+ {new Date().getFullYear()} is a year of manifestation and achievement.
+ Planetary alignments support bringing your visions into reality through
+ focused action and strategic planning.
+
+
+ {data.numerology?.daily?.personalYear && (
+
+
Personal Year Number
+
+ {data.numerology.daily.personalYear}
+
+
+ A year of {getPersonalYearMeaning(data.numerology.daily.personalYear)}
+
+ Celestia has access to your complete birth chart and can provide deep insights
+
+
+
+
+ );
+};
+
+export default FullPageChat;
diff --git a/components/HelpCenter.tsx b/components/HelpCenter.tsx
new file mode 100644
index 0000000..65a64d6
--- /dev/null
+++ b/components/HelpCenter.tsx
@@ -0,0 +1,335 @@
+
+import React, { useState } from 'react';
+import { X, BookOpen, Compass, Star, Globe, Calendar, Heart, TrendingUp, Sparkles, ChevronRight } from 'lucide-react';
+
+interface HelpCenterProps {
+ isOpen: boolean;
+ onClose: () => void;
+}
+
+interface HelpSection {
+ id: string;
+ icon: any;
+ title: string;
+ description: string;
+ content: {
+ subtitle: string;
+ text: string;
+ }[];
+}
+
+const HELP_SECTIONS: HelpSection[] = [
+ {
+ id: 'getting-started',
+ icon: Compass,
+ title: 'Getting Started',
+ description: 'Learn the basics of your Celestia dashboard',
+ content: [
+ {
+ subtitle: 'Understanding Your Dashboard',
+ text: 'Your dashboard provides a complete astrological profile based on your birth data. Navigate between tabs to explore different aspects: Overview for your core chart, Daily for forecasts, Transits for current planetary influences, and more.'
+ },
+ {
+ subtitle: 'The Big Three',
+ text: 'Your Sun sign represents your core identity, Moon sign governs your emotions and instincts, and Ascendant (Rising) shows how others perceive you. These three form the foundation of your chart.'
+ },
+ {
+ subtitle: 'Using the AI Assistant',
+ text: 'Click on the ✨ AI Assistant tab to ask questions about any aspect of your chart. You can also click the sparkle icons throughout the dashboard for instant explanations of specific placements.'
+ }
+ ]
+ },
+ {
+ id: 'birth-chart',
+ icon: Star,
+ title: 'Your Birth Chart',
+ description: 'Understanding planetary positions and houses',
+ content: [
+ {
+ subtitle: 'Planetary Placements',
+ text: 'Each planet represents a different aspect of your psyche: Sun (identity), Moon (emotions), Mercury (communication), Venus (love/values), Mars (action), Jupiter (expansion), Saturn (discipline), Uranus (innovation), Neptune (spirituality), Pluto (transformation).'
+ },
+ {
+ subtitle: 'The 12 Houses',
+ text: 'Houses represent life areas: 1st (Self/Identity), 2nd (Money/Values), 3rd (Communication), 4th (Home/Family), 5th (Creativity/Romance), 6th (Work/Health), 7th (Partnerships), 8th (Transformation/Shared Resources), 9th (Philosophy/Travel), 10th (Career/Public Image), 11th (Community/Goals), 12th (Spirituality/Subconscious).'
+ },
+ {
+ subtitle: 'Aspects & Relationships',
+ text: 'Aspects are angles between planets showing how their energies interact. Harmonious aspects (trines 120°, sextiles 60°) indicate flow, while challenging aspects (squares 90°, oppositions 180°) create dynamic tension for growth.'
+ },
+ {
+ subtitle: 'Special Points',
+ text: 'Beyond planets, your chart includes: North Node (soul\'s purpose), South Node (past patterns), Chiron (wounded healer), Lilith (shadow self), and Part of Fortune (worldly success).'
+ }
+ ]
+ },
+ {
+ id: 'forecasts',
+ icon: Calendar,
+ title: 'Forecasts & Timing',
+ description: 'Daily, weekly, monthly, and yearly guidance',
+ content: [
+ {
+ subtitle: 'Daily Forecasts',
+ text: 'Daily forecasts show the current day\'s astrological weather based on the Moon\'s position, aspects forming today, and your personal numerology day number. Use this for daily planning and understanding your emotional state.'
+ },
+ {
+ subtitle: 'Weekly & Monthly Views',
+ text: 'Weekly forecasts help you plan the week ahead, highlighting key days. Monthly forecasts show the overall theme and energy of the month based on lunations (New/Full Moons) and major transits.'
+ },
+ {
+ subtitle: 'Yearly Overview',
+ text: 'Yearly forecasts include your Personal Year number (numerology), major transits from slow-moving planets, and quarterly themes. Use this for long-term planning and understanding the year\'s arc.'
+ },
+ {
+ subtitle: 'Best Times for Action',
+ text: 'Look for harmonious transits to your Sun, Moon, or Ascendant for optimal timing. Avoid starting major projects during challenging Mars or Mercury retrograde periods.'
+ }
+ ]
+ },
+ {
+ id: 'transits',
+ icon: TrendingUp,
+ title: 'Transits',
+ description: 'Current planetary influences on your chart',
+ content: [
+ {
+ subtitle: 'What Are Transits?',
+ text: 'Transits are the current positions of planets in the sky and how they aspect your birth chart. They activate different parts of your chart, triggering events, insights, and growth opportunities.'
+ },
+ {
+ subtitle: 'Major vs Minor Transits',
+ text: 'Fast-moving planets (Moon, Mercury, Venus, Mars) create short-term influences (days to weeks). Slow-moving planets (Jupiter, Saturn, Uranus, Neptune, Pluto) create long-term themes (months to years).'
+ },
+ {
+ subtitle: 'Important Transit Events',
+ text: 'Saturn Return (ages 29-30, 58-59): Life restructuring. Jupiter Return (every 12 years): Expansion and opportunity. Uranus Opposition (age 40-42): Mid-life awakening. Pluto Square (varies): Deep transformation.'
+ },
+ {
+ subtitle: 'Working With Transits',
+ text: 'Harmonious transits (trines, sextiles) bring ease and opportunities. Challenging transits (squares, oppositions) bring lessons and growth. Both are valuable for evolution.'
+ }
+ ]
+ },
+ {
+ id: 'compatibility',
+ icon: Heart,
+ title: 'Compatibility (Synastry)',
+ description: 'Understanding relationship dynamics',
+ content: [
+ {
+ subtitle: 'How Synastry Works',
+ text: 'Synastry compares two birth charts to see how planets from one person aspect planets of another. This reveals attraction, challenges, and the purpose of the relationship.'
+ },
+ {
+ subtitle: 'Key Compatibility Factors',
+ text: 'Sun-Moon aspects show emotional compatibility. Venus-Mars aspects indicate romantic/sexual chemistry. Saturn aspects show commitment and longevity. Outer planet aspects reveal karmic connections and transformative potential.'
+ },
+ {
+ subtitle: 'Composite Charts',
+ text: 'A composite chart blends two charts into one, showing the relationship itself as an entity. It reveals the relationship\'s purpose, strengths, and challenges independent of the individuals.'
+ },
+ {
+ subtitle: 'Beyond Sun Signs',
+ text: 'Sun sign compatibility is just the beginning! Look at Moon signs for emotional needs, Venus for love styles, Mars for how you handle conflict, and the 7th house for partnership dynamics.'
+ }
+ ]
+ },
+ {
+ id: 'astrocartography',
+ icon: Globe,
+ title: 'Astrocartography',
+ description: 'How different locations affect you',
+ content: [
+ {
+ subtitle: 'What Is Astrocartography?',
+ text: 'Astrocartography maps your birth chart onto Earth, showing where different planetary energies are strongest. Each planetary line crossing a location creates specific experiences and opportunities there.'
+ },
+ {
+ subtitle: 'Planetary Lines',
+ text: 'Sun lines: Vitality, recognition, leadership. Moon lines: Emotional comfort, family, intuition. Venus lines: Love, beauty, pleasure. Mars lines: Action, passion, competition. Jupiter lines: Luck, growth, expansion. Saturn lines: Discipline, career, challenges.'
+ },
+ {
+ subtitle: 'Using Astrocartography',
+ text: 'Visit Venus lines for romance or artistic inspiration. Consider Jupiter lines for career opportunities. Use Saturn lines for serious work and building lasting foundations. Avoid challenging planetary lines for vacations.'
+ },
+ {
+ subtitle: 'City Scout',
+ text: 'Use the City Scout feature to search specific cities and see which planetary lines affect them. This helps with relocation decisions, travel planning, and understanding your experiences in different places.'
+ }
+ ]
+ },
+ {
+ id: 'numerology',
+ icon: Sparkles,
+ title: 'Numerology',
+ description: 'Numbers and their spiritual significance',
+ content: [
+ {
+ subtitle: 'Life Path Number',
+ text: 'Your Life Path number (calculated from birth date) reveals your core purpose, natural talents, and main life lessons. It\'s the most important number in your numerology chart.'
+ },
+ {
+ subtitle: 'Destiny & Soul Urge',
+ text: 'Destiny Number (from birth name) shows what you\'re meant to achieve. Soul Urge Number (from vowels in name) reveals your inner motivations and heart\'s desires.'
+ },
+ {
+ subtitle: 'Personal Year Cycles',
+ text: 'Each year you experience a Personal Year number (1-9) creating a 9-year cycle. Year 1: New beginnings. Year 5: Change and freedom. Year 9: Completion and release. Current cycles appear in your forecasts.'
+ },
+ {
+ subtitle: 'Master Numbers',
+ text: 'Master Numbers (11, 22, 33) carry intensified spiritual significance and higher vibrations. They indicate old souls with powerful missions but also greater challenges.'
+ }
+ ]
+ },
+ {
+ id: 'tips',
+ icon: BookOpen,
+ title: 'Tips & Best Practices',
+ description: 'Getting the most from Celestia',
+ content: [
+ {
+ subtitle: 'Daily Practice',
+ text: 'Check your Daily Forecast each morning to understand the day\'s energy. Review Transits weekly to prepare for upcoming influences. Use the AI Assistant to explore any placements or transits you don\'t understand.'
+ },
+ {
+ subtitle: 'Asking Better Questions',
+ text: 'Instead of "Will I find love?", ask "What can my Venus placement teach me about my relationship patterns?" Focus on growth, understanding, and empowerment rather than prediction.'
+ },
+ {
+ subtitle: 'Combining Systems',
+ text: 'Use astrology for timing and understanding cosmic weather. Use numerology for personal cycles and life path. Use astrocartography for location decisions. Each system offers unique insights.'
+ },
+ {
+ subtitle: 'Free Will & Astrology',
+ text: 'Your chart shows potentials, not inevitabilities. Challenging aspects create growth opportunities. You always have free will in how you express your chart. Astrology empowers self-awareness, not fatalism.'
+ }
+ ]
+ }
+];
+
+const HelpCenter: React.FC = ({ isOpen, onClose }) => {
+ const [selectedSection, setSelectedSection] = useState(null);
+
+ if (!isOpen) return null;
+
+ const currentSection = HELP_SECTIONS.find(s => s.id === selectedSection);
+
+ return (
+
+ Our AI Assistant is available 24/7 to answer specific questions about your chart, explain astrological concepts, and provide personalized guidance.
+
+ Celestia Help Center • For personalized guidance, use the AI Assistant tab
+
+
+
+
+ );
+};
+
+export default HelpCenter;
diff --git a/components/OnboardingTour.tsx b/components/OnboardingTour.tsx
new file mode 100644
index 0000000..a1b39da
--- /dev/null
+++ b/components/OnboardingTour.tsx
@@ -0,0 +1,205 @@
+
+import React, { useState, useEffect } from 'react';
+import { X, ChevronLeft, ChevronRight, Sparkles } from 'lucide-react';
+
+interface OnboardingTourProps {
+ isOpen: boolean;
+ onClose: () => void;
+ onComplete: () => void;
+}
+
+interface TourStep {
+ title: string;
+ description: string;
+ emoji: string;
+ tip?: string;
+}
+
+const TOUR_STEPS: TourStep[] = [
+ {
+ title: "Welcome to Celestia! ✨",
+ description: "Your personal astrology companion is ready to reveal the cosmic blueprint of your life. Let's take a quick tour to help you make the most of your dashboard.",
+ emoji: "🌟",
+ tip: "This tour will only take a minute. You can skip it anytime!"
+ },
+ {
+ title: "Your Cosmic Dashboard",
+ description: "Navigate between different sections using the tabs at the top. Explore your Birth Chart, Daily Forecasts, Transits, Compatibility, and more. Each section reveals different aspects of your astrological profile.",
+ emoji: "🧭",
+ tip: "Pro tip: Press ESC to quickly return to the Overview from any tab"
+ },
+ {
+ title: "The Big Three",
+ description: "Your Sun, Moon, and Ascendant signs are the foundation of your chart. The Sun represents your core identity, the Moon your emotional nature, and the Ascendant how others perceive you.",
+ emoji: "☀️",
+ tip: "Click on any planetary placement to get instant AI insights!"
+ },
+ {
+ title: "AI Assistant",
+ description: "Have questions about your chart? Click the ✨ AI Assistant tab to chat with Celestia. Ask about specific placements, get guidance on transits, or explore compatibility questions.",
+ emoji: "🤖",
+ tip: "You can also click sparkle icons ✨ throughout the dashboard for quick insights"
+ },
+ {
+ title: "Daily Forecasts",
+ description: "Visit the Daily Forecast tab each morning to see today's cosmic weather. We provide forecasts for Love, Career, Money, Health, and more. You can also view Weekly, Monthly, and Yearly forecasts.",
+ emoji: "📅",
+ tip: "Your Personal Day number changes daily and influences the energy"
+ },
+ {
+ title: "Transits & Timing",
+ description: "The Transits tab shows current planetary movements and how they affect your birth chart. These indicate the best times for important decisions, new beginnings, or careful waiting.",
+ emoji: "⏰",
+ tip: "Major transits like Saturn Return happen at specific ages and bring profound growth"
+ },
+ {
+ title: "Astrocartography",
+ description: "Curious about living or traveling elsewhere? The Astrocartography Map and City Scout show how different locations activate different parts of your chart.",
+ emoji: "🌍",
+ tip: "Venus lines are great for romance and creativity, Jupiter lines for opportunity!"
+ },
+ {
+ title: "Need Help?",
+ description: "Click the ? icon in the top navigation to access the Help Center anytime. You'll find detailed guides on birth charts, forecasts, compatibility, and all our features.",
+ emoji: "❓",
+ tip: "Hover over terms with a dotted underline to see quick definitions"
+ },
+ {
+ title: "You're All Set!",
+ description: "Your cosmic journey begins now. Explore your dashboard, ask the AI assistant questions, and discover the hidden patterns in your stars. The universe has much to reveal to you!",
+ emoji: "🚀",
+ tip: "Check back daily for updated forecasts and transits"
+ }
+];
+
+const OnboardingTour: React.FC = ({ isOpen, onClose, onComplete }) => {
+ const [currentStep, setCurrentStep] = useState(0);
+
+ const handleSkip = () => {
+ onClose();
+ };
+
+ const handleComplete = () => {
+ onComplete();
+ onClose();
+ };
+
+ const handleNext = () => {
+ if (currentStep < TOUR_STEPS.length - 1) {
+ setCurrentStep(currentStep + 1);
+ } else {
+ handleComplete();
+ }
+ };
+
+ const handlePrevious = () => {
+ if (currentStep > 0) {
+ setCurrentStep(currentStep - 1);
+ }
+ };
+
+ useEffect(() => {
+ const handleEscape = (e: KeyboardEvent) => {
+ if (e.key === 'Escape' && isOpen) {
+ onClose();
+ }
+ };
+ window.addEventListener('keydown', handleEscape);
+ return () => window.removeEventListener('keydown', handleEscape);
+ }, [isOpen, onClose]);
+
+ if (!isOpen) return null;
+
+ const step = TOUR_STEPS[currentStep];
+ const progress = ((currentStep + 1) / TOUR_STEPS.length) * 100;
+
+ return (
+
+
+
+ {/* Header */}
+
+
+
+
+
+
+
+
Celestia Onboarding
+
Step {currentStep + 1} of {TOUR_STEPS.length}
+
+
+
+
+
+ {/* Progress Bar */}
+
+
+
+
+
+ {/* Content */}
+
+
{step.emoji}
+
{step.title}
+
+ {step.description}
+
+ {step.tip && (
+
+
+ 💡 Tip: {step.tip}
+
+
+ )}
+
+
+ {/* Footer */}
+
+
+
+
+ {TOUR_STEPS.map((_, idx) => (
+
+ ))}
+
+
+
+
+
+
+ );
+};
+
+export default OnboardingTour;
diff --git a/components/TransitsCalendar.tsx b/components/TransitsCalendar.tsx
index 100c9cb..1a9e90a 100644
--- a/components/TransitsCalendar.tsx
+++ b/components/TransitsCalendar.tsx
@@ -1,11 +1,12 @@
/**
* TransitsCalendar Component
- * Display upcoming transits in a calendar view
+ * Display upcoming transits in a calendar view using REAL astronomical calculations
*/
import React, { useState, useMemo } from 'react';
import { Transit, PlanetaryPosition } from '../types';
import { Calendar, ChevronLeft, ChevronRight, Zap } from 'lucide-react';
+import { calculateTransits } from '../services/astronomyService';
interface TransitsCalendarProps {
natalPositions: PlanetaryPosition[];
@@ -13,43 +14,35 @@ interface TransitsCalendarProps {
const PLANET_SYMBOLS: { [key: string]: string } = {
'Sun': '☉', 'Moon': '☽', 'Mercury': '☿', 'Venus': '♀', 'Mars': '♂',
- 'Jupiter': '♃', 'Saturn': '♄', 'Uranus': '♅', 'Neptune': '♆', 'Pluto': '♇'
+ 'Jupiter': '♃', 'Saturn': '♄', 'Uranus': '♅', 'Neptune': '♆', 'Pluto': '♇',
+ 'Chiron': '⚷'
};
const ASPECT_SYMBOLS: { [key: string]: string } = {
'Conjunction': '☌', 'Opposition': '☍', 'Trine': '△',
- 'Square': '□', 'Sextile': '⚹'
+ 'Square': '□', 'Sextile': '⚹',
+ 'Semi-Sextile': '⚺', 'Quincunx': '⚻'
};
const TransitsCalendar: React.FC = ({ natalPositions }) => {
const [currentMonth, setCurrentMonth] = useState(new Date());
- // Generate mock transits for demonstration
- // In production, this would use calculateTransits from astronomyService
- const generateMockTransits = useMemo(() => {
- const transits: Transit[] = [];
- const today = new Date();
-
- for (let i = 0; i < 30; i++) {
- const date = new Date(today);
- date.setDate(date.getDate() + i);
-
- // Random transit for demo
- const transitingPlanets = ['Sun', 'Moon', 'Mercury', 'Venus', 'Mars', 'Jupiter', 'Saturn'];
- const aspects: any[] = ['Conjunction', 'Opposition', 'Trine', 'Square', 'Sextile'];
-
- transits.push({
- transitingPlanet: transitingPlanets[Math.floor(Math.random() * transitingPlanets.length)],
- natalPlanet: natalPositions[Math.floor(Math.random() * natalPositions.length)]?.planet || 'Sun',
- aspect: aspects[Math.floor(Math.random() * aspects.length)],
- date: date.toISOString().split('T')[0],
- orb: Math.random() * 3,
- description: 'Transit aspect description',
- intensity: Math.floor(Math.random() * 10) + 1
- });
+ // Calculate REAL transits using astronomical calculations
+ const upcomingTransits = useMemo(() => {
+ if (!natalPositions || natalPositions.length === 0) {
+ return [];
}
- return transits;
+ const today = new Date();
+ const endDate = new Date(today);
+ endDate.setDate(endDate.getDate() + 90); // Calculate 90 days of transits
+
+ try {
+ return calculateTransits(natalPositions, today, endDate);
+ } catch (error) {
+ console.error('Error calculating transits:', error);
+ return [];
+ }
}, [natalPositions]);
const getDaysInMonth = (date: Date) => {
@@ -73,7 +66,13 @@ const TransitsCalendar: React.FC = ({ natalPositions }) =
const getTransitsForDate = (day: number) => {
const dateStr = new Date(currentMonth.getFullYear(), currentMonth.getMonth(), day)
.toISOString().split('T')[0];
- return generateMockTransits.filter(t => t.date === dateStr);
+ return upcomingTransits.filter(t => {
+ // t.date is a Date object, convert to YYYY-MM-DD string for comparison
+ const transitDateStr = t.date instanceof Date
+ ? t.date.toISOString().split('T')[0]
+ : String(t.date).split('T')[0];
+ return transitDateStr === dateStr;
+ });
};
const daysInMonth = getDaysInMonth(currentMonth);
diff --git a/services/astronomyService.ts b/services/astronomyService.ts
index a3080cf..dbd63e7 100644
--- a/services/astronomyService.ts
+++ b/services/astronomyService.ts
@@ -24,7 +24,8 @@ const ZODIAC_SIGNS = [
// Planet list for calculations
const PLANETS = [
'Sun', 'Moon', 'Mercury', 'Venus', 'Mars',
- 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Pluto'
+ 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Pluto',
+ 'Chiron' // Added - asteroid representing healing and wisdom
];
/**
@@ -141,10 +142,139 @@ function isRetrograde(date: Date, body: Astronomy.Body): boolean {
}
}
+/**
+ * Helper: Convert Date to Julian Day Number
+ */
+function julianDate(date: Date): number {
+ return date.getTime() / 86400000 + 2440587.5;
+}
+
+/**
+ * Calculate Lunar Nodes (North and South)
+ * The nodes are where the Moon's orbit crosses the ecliptic plane
+ */
+export function calculateLunarNodes(
+ birthDate: Date,
+ latitude: number,
+ longitude: number
+): { northNode: PlanetaryPosition; southNode: PlanetaryPosition } {
+ // Mean lunar node calculation (more stable than true node)
+ const T = (julianDate(birthDate) - 2451545.0) / 36525;
+
+ // Formula from astronomical algorithms
+ const meanNode = 125.04452 - 1934.136261 * T + 0.0020708 * T * T + T * T * T / 450000;
+
+ const northNodeLon = ((meanNode % 360) + 360) % 360;
+ const southNodeLon = (northNodeLon + 180) % 360;
+
+ const northZodiac = getZodiacSign(northNodeLon);
+ const southZodiac = getZodiacSign(southNodeLon);
+
+ const northHouse = calculateHouseForPosition(northNodeLon, birthDate, latitude, longitude);
+ const southHouse = calculateHouseForPosition(southNodeLon, birthDate, latitude, longitude);
+
+ return {
+ northNode: {
+ planet: 'North Node',
+ sign: northZodiac.sign,
+ degree: northZodiac.degree,
+ absoluteDegree: northNodeLon,
+ house: northHouse,
+ retrograde: true, // Nodes always move retrograde
+ summary: `North Node in ${northZodiac.sign} - Your soul's growth direction`
+ },
+ southNode: {
+ planet: 'South Node',
+ sign: southZodiac.sign,
+ degree: southZodiac.degree,
+ absoluteDegree: southNodeLon,
+ house: southHouse,
+ retrograde: true,
+ summary: `South Node in ${southZodiac.sign} - Your past life talents`
+ }
+ };
+}
+
+/**
+ * Calculate Black Moon Lilith
+ * Lilith is the lunar apogee (farthest point of the Moon's orbit from Earth)
+ */
+export function calculateLilith(
+ birthDate: Date,
+ latitude: number,
+ longitude: number
+): PlanetaryPosition {
+ const T = (julianDate(birthDate) - 2451545.0) / 36525;
+
+ // Mean Lilith formula (most commonly used in Western astrology)
+ const lilithLon = 83.35324 + 40.66246 * T + 0.111404 * T * T;
+ const normalizedLon = ((lilithLon % 360) + 360) % 360;
+
+ const zodiac = getZodiacSign(normalizedLon);
+ const house = calculateHouseForPosition(normalizedLon, birthDate, latitude, longitude);
+
+ return {
+ planet: 'Lilith',
+ sign: zodiac.sign,
+ degree: zodiac.degree,
+ absoluteDegree: normalizedLon,
+ house: house,
+ retrograde: false,
+ summary: `Lilith in ${zodiac.sign} - Your shadow self and repressed power`
+ };
+}
+
+/**
+ * Calculate Part of Fortune
+ * Formula: Ascendant + Moon - Sun (day birth)
+ * or Ascendant + Sun - Moon (night birth)
+ */
+export function calculatePartOfFortune(
+ ascendantLon: number,
+ sunLon: number,
+ moonLon: number,
+ isDayBirth: boolean,
+ birthDate: Date,
+ latitude: number,
+ longitude: number
+): PlanetaryPosition {
+ let fortuneLon: number;
+
+ if (isDayBirth) {
+ fortuneLon = ascendantLon + moonLon - sunLon;
+ } else {
+ fortuneLon = ascendantLon + sunLon - moonLon;
+ }
+
+ const normalizedLon = ((fortuneLon % 360) + 360) % 360;
+ const zodiac = getZodiacSign(normalizedLon);
+ const house = calculateHouseForPosition(normalizedLon, birthDate, latitude, longitude);
+
+ return {
+ planet: 'Part of Fortune',
+ sign: zodiac.sign,
+ degree: zodiac.degree,
+ absoluteDegree: normalizedLon,
+ house: house,
+ retrograde: false,
+ summary: `Part of Fortune in ${zodiac.sign} - Your path to joy and success`
+ };
+}
+
+/**
+ * Determine if birth was during day or night
+ * Day if Sun is above horizon (houses 7-12, from Descendant to Ascendant)
+ * Night if Sun is below horizon (houses 1-6, from Ascendant to Descendant)
+ */
+export function isDayBirth(sunLon: number, ascendantLon: number): boolean {
+ const diff = ((sunLon - ascendantLon + 360) % 360);
+ // Sun is above horizon when 180° or more from Ascendant (houses 7-12)
+ return diff >= 180;
+}
+
/**
* Calculate houses using specified house system
- * Currently only supports Equal House and Whole Sign systems
- * Other systems (Placidus, Koch, etc.) are not yet implemented
+ * Supports Placidus, Equal House, and Whole Sign systems
*/
export function calculateHouses(
birthDate: Date,
@@ -154,15 +284,13 @@ export function calculateHouses(
): HousePosition[] {
const houses: HousePosition[] = [];
- // Validate house system support
- if (houseSystem !== 'Equal' && houseSystem !== 'Whole Sign') {
- console.warn(`House system '${houseSystem}' not yet implemented. Falling back to Equal House.`);
- }
-
- // Calculate Ascendant (Rising Sign)
+ // Calculate Ascendant and MC for all systems
const ascendant = calculateAscendant(birthDate, latitude, longitude);
+ const mc = calculateMidheaven(birthDate, longitude);
- if (houseSystem === 'Whole Sign') {
+ if (houseSystem === 'Placidus') {
+ return calculatePlacidusHouses(birthDate, latitude, longitude, ascendant, mc);
+ } else if (houseSystem === 'Whole Sign') {
// Whole Sign: Each house is a whole sign, starting from the sign of the Ascendant
const ascSignIndex = Math.floor(ascendant / 30);
for (let i = 0; i < 12; i++) {
@@ -178,7 +306,7 @@ export function calculateHouses(
});
}
} else {
- // Equal House: 30° per house from Ascendant
+ // Equal House: 30° per house from Ascendant (default)
for (let i = 0; i < 12; i++) {
const houseDegree = (ascendant + (i * 30)) % 360;
const zodiac = getZodiacSign(houseDegree);
@@ -195,6 +323,159 @@ export function calculateHouses(
return houses;
}
+/**
+ * Calculate Midheaven (MC) - the point of the ecliptic at the southern meridian
+ * @param birthDate - The date and time of birth
+ * @param latitude - Geographic latitude (not used in current simplified calculation, but kept for API consistency)
+ * @param longitude - Geographic longitude
+ * @returns Midheaven in degrees (0-360)
+ */
+export function calculateMidheaven(birthDate: Date, latitude: number, longitude: number): number {
+ // Calculate Local Sidereal Time
+ const gmst = Astronomy.SiderealTime(birthDate);
+ const lst = (gmst + longitude / 15) % 24;
+
+ // Convert LST to Right Ascension of MC (RAMC)
+ const ramc = lst * 15; // Convert hours to degrees
+
+ // Simplified MC calculation
+ // For more accuracy, would need to account for obliquity and latitude
+ const mc = ramc % 360;
+
+ return mc;
+}
+
+/**
+ * Calculate Placidus houses
+ * Placidus uses time-based trisection of semi-arcs
+ */
+function calculatePlacidusHouses(
+ birthDate: Date,
+ latitude: number,
+ longitude: number,
+ ascendant: number,
+ mc: number
+): HousePosition[] {
+ const houses: HousePosition[] = [];
+ const obliquity = 23.4397; // Mean obliquity of the ecliptic (degrees)
+
+ // Get RAMC (Right Ascension of Midheaven)
+ const gmst = Astronomy.SiderealTime(birthDate);
+ const lst = (gmst + longitude / 15) % 24;
+ const ramc = lst * 15; // RAMC in degrees
+
+ // Calculate intermediate cusps using Placidus formula
+ // Houses 1, 4, 7, 10 are the angles
+ const cusps: number[] = new Array(12);
+
+ // Angles (these are direct calculations)
+ cusps[0] = ascendant; // 1st house (Ascendant)
+ cusps[9] = mc; // 10th house (MC)
+ cusps[6] = (ascendant + 180) % 360; // 7th house (Descendant)
+ cusps[3] = (mc + 180) % 360; // 4th house (IC)
+
+ // Calculate intermediate cusps for each quadrant
+ // Using semi-arc trisection method (simplified)
+
+ // Houses 11 and 12 (between MC and Ascendant)
+ cusps[10] = calculatePlacidusIntermediateCusp(ramc, latitude, obliquity, 11);
+ cusps[11] = calculatePlacidusIntermediateCusp(ramc, latitude, obliquity, 12);
+
+ // Houses 2 and 3 (between Ascendant and IC)
+ cusps[1] = calculatePlacidusIntermediateCusp(ramc, latitude, obliquity, 2);
+ cusps[2] = calculatePlacidusIntermediateCusp(ramc, latitude, obliquity, 3);
+
+ // Houses 5 and 6 (between IC and Descendant)
+ cusps[4] = calculatePlacidusIntermediateCusp(ramc, latitude, obliquity, 5);
+ cusps[5] = calculatePlacidusIntermediateCusp(ramc, latitude, obliquity, 6);
+
+ // Houses 8 and 9 (between Descendant and MC)
+ cusps[7] = calculatePlacidusIntermediateCusp(ramc, latitude, obliquity, 8);
+ cusps[8] = calculatePlacidusIntermediateCusp(ramc, latitude, obliquity, 9);
+
+ // Create house positions from cusps
+ for (let i = 0; i < 12; i++) {
+ const houseDegree = cusps[i] % 360;
+ const zodiac = getZodiacSign(houseDegree);
+
+ houses.push({
+ house: i + 1,
+ sign: zodiac.sign,
+ degree: zodiac.degree,
+ absoluteDegree: houseDegree
+ });
+ }
+
+ return houses;
+}
+
+/**
+ * Calculate intermediate house cusp for Placidus system
+ * This is a simplified calculation - full Placidus requires iterative solutions
+ */
+function calculatePlacidusIntermediateCusp(
+ ramc: number,
+ latitude: number,
+ obliquity: number,
+ house: number
+): number {
+ // Convert to radians
+ const latRad = (latitude * Math.PI) / 180;
+ const oblRad = (obliquity * Math.PI) / 180;
+
+ // Calculate the meridian distance for this house
+ // Houses are divided by trisecting the diurnal and nocturnal semi-arcs
+ let md: number; // Meridian distance
+
+ switch (house) {
+ case 11:
+ md = ramc + 30;
+ break;
+ case 12:
+ md = ramc + 60;
+ break;
+ case 2:
+ md = ramc + 120;
+ break;
+ case 3:
+ md = ramc + 150;
+ break;
+ case 5:
+ md = ramc + 210;
+ break;
+ case 6:
+ md = ramc + 240;
+ break;
+ case 8:
+ md = ramc + 300;
+ break;
+ case 9:
+ md = ramc + 330;
+ break;
+ default:
+ md = ramc;
+ }
+
+ // Simplified ecliptic longitude calculation
+ // Full Placidus would use pole height and semi-arc calculations
+ const mdRad = (md * Math.PI) / 180;
+
+ // Approximate conversion from equatorial to ecliptic coordinates
+ const tanLat = Math.tan(latRad);
+ const tanObl = Math.tan(oblRad);
+
+ // Simplified formula (accurate implementation would be iterative)
+ let eclipticLon = md;
+
+ // Apply latitude correction
+ if (Math.abs(latitude) < 66) { // Avoid polar regions
+ const correction = Math.atan(Math.tan(mdRad) * Math.cos(oblRad)) * (180 / Math.PI);
+ eclipticLon = (md + (correction - md) * 0.3) % 360;
+ }
+
+ return (eclipticLon + 360) % 360;
+}
+
/**
* Calculate Ascendant (Rising Sign) - the eastern horizon at birth
*/
@@ -218,20 +499,6 @@ export function calculateAscendant(
return ascendantDegree;
}
-/**
- * Calculate Midheaven (MC) - the highest point in the sky at birth
- */
-export function calculateMidheaven(
- birthDate: Date,
- latitude: number,
- longitude: number
-): number {
- // MC is approximately 90° from Ascendant (in Equal House)
- // More accurate calculation would use proper celestial mechanics
- const ascendant = calculateAscendant(birthDate, latitude, longitude);
- return (ascendant + 90) % 360;
-}
-
/**
* Calculate which house a planet is in based on its longitude
*/
@@ -426,6 +693,180 @@ export function calculateTransits(
return transits;
}
+/**
+ * Calculate secondary progressions
+ * In secondary progressions, one day after birth equals one year of life
+ * This shows internal psychological development and timing
+ */
+export interface ProgressedPositions {
+ progressedDate: Date; // The actual date we're calculating for
+ ageInYears: number;
+ sun: PlanetaryPosition;
+ moon: PlanetaryPosition;
+ mercury: PlanetaryPosition;
+ venus: PlanetaryPosition;
+ mars: PlanetaryPosition;
+ ascendant: PlanetaryPosition;
+ mc: number; // Midheaven degree
+}
+
+export function calculateSecondaryProgressions(
+ birthDate: Date,
+ birthLatitude: number,
+ birthLongitude: number,
+ currentDate: Date = new Date()
+): ProgressedPositions {
+ // Calculate age in years
+ const ageInMs = currentDate.getTime() - birthDate.getTime();
+ const ageInYears = ageInMs / (1000 * 60 * 60 * 24 * 365.25);
+
+ // In secondary progressions: 1 day = 1 year
+ // So we calculate planetary positions for birthDate + age in days
+ const progressedDate = new Date(birthDate);
+ progressedDate.setDate(progressedDate.getDate() + Math.floor(ageInYears));
+
+ // Calculate progressed planetary positions
+ const progressedPlanets: PlanetaryPosition[] = [];
+
+ // Calculate progressed Sun
+ try {
+ const sunEcliptic = Astronomy.Ecliptic(Astronomy.GeoVector(Astronomy.Body.Sun, progressedDate, false));
+ const sunLon = sunEcliptic.elon;
+ const sunZodiac = getZodiacSign(sunLon);
+
+ progressedPlanets.push({
+ planet: 'Progressed Sun',
+ sign: sunZodiac.sign,
+ degree: sunZodiac.degree,
+ absoluteDegree: sunLon,
+ house: 0, // Would need birth time to calculate
+ retrograde: false,
+ summary: `Progressed Sun in ${sunZodiac.sign} at ${sunZodiac.degree.toFixed(2)}°`
+ });
+ } catch (error) {
+ console.error('Error calculating progressed Sun:', error);
+ }
+
+ // Calculate progressed Moon (moves quickly - about 1 degree per month in progressions)
+ try {
+ const moonEcliptic = Astronomy.Ecliptic(Astronomy.GeoVector(Astronomy.Body.Moon, progressedDate, false));
+ const moonLon = moonEcliptic.elon;
+ const moonZodiac = getZodiacSign(moonLon);
+
+ progressedPlanets.push({
+ planet: 'Progressed Moon',
+ sign: moonZodiac.sign,
+ degree: moonZodiac.degree,
+ absoluteDegree: moonLon,
+ house: 0,
+ retrograde: false,
+ summary: `Progressed Moon in ${moonZodiac.sign} at ${moonZodiac.degree.toFixed(2)}°`
+ });
+ } catch (error) {
+ console.error('Error calculating progressed Moon:', error);
+ }
+
+ // Calculate progressed Mercury
+ try {
+ const mercuryEcliptic = Astronomy.Ecliptic(Astronomy.GeoVector(Astronomy.Body.Mercury, progressedDate, false));
+ const mercuryLon = mercuryEcliptic.elon;
+ const mercuryZodiac = getZodiacSign(mercuryLon);
+
+ progressedPlanets.push({
+ planet: 'Progressed Mercury',
+ sign: mercuryZodiac.sign,
+ degree: mercuryZodiac.degree,
+ absoluteDegree: mercuryLon,
+ house: 0,
+ retrograde: isRetrograde(progressedDate, Astronomy.Body.Mercury),
+ summary: `Progressed Mercury in ${mercuryZodiac.sign} at ${mercuryZodiac.degree.toFixed(2)}°`
+ });
+ } catch (error) {
+ console.error('Error calculating progressed Mercury:', error);
+ }
+
+ // Calculate progressed Venus
+ try {
+ const venusEcliptic = Astronomy.Ecliptic(Astronomy.GeoVector(Astronomy.Body.Venus, progressedDate, false));
+ const venusLon = venusEcliptic.elon;
+ const venusZodiac = getZodiacSign(venusLon);
+
+ progressedPlanets.push({
+ planet: 'Progressed Venus',
+ sign: venusZodiac.sign,
+ degree: venusZodiac.degree,
+ absoluteDegree: venusLon,
+ house: 0,
+ retrograde: isRetrograde(progressedDate, Astronomy.Body.Venus),
+ summary: `Progressed Venus in ${venusZodiac.sign} at ${venusZodiac.degree.toFixed(2)}°`
+ });
+ } catch (error) {
+ console.error('Error calculating progressed Venus:', error);
+ }
+
+ // Calculate progressed Mars
+ try {
+ const marsEcliptic = Astronomy.Ecliptic(Astronomy.GeoVector(Astronomy.Body.Mars, progressedDate, false));
+ const marsLon = marsEcliptic.elon;
+ const marsZodiac = getZodiacSign(marsLon);
+
+ progressedPlanets.push({
+ planet: 'Progressed Mars',
+ sign: marsZodiac.sign,
+ degree: marsZodiac.degree,
+ absoluteDegree: marsLon,
+ house: 0,
+ retrograde: isRetrograde(progressedDate, Astronomy.Body.Mars),
+ summary: `Progressed Mars in ${marsZodiac.sign} at ${marsZodiac.degree.toFixed(2)}°`
+ });
+ } catch (error) {
+ console.error('Error calculating progressed Mars:', error);
+ }
+
+ // Calculate progressed Ascendant (using Mean Quotidian method)
+ // Progressed ASC moves about 1 degree per year
+ const natalAsc = calculateAscendant(birthDate, birthLatitude, birthLongitude);
+ const progressedAscDegree = (natalAsc + ageInYears) % 360;
+ const progressedAscZodiac = getZodiacSign(progressedAscDegree);
+
+ const progressedAscendant: PlanetaryPosition = {
+ planet: 'Progressed Ascendant',
+ sign: progressedAscZodiac.sign,
+ degree: progressedAscZodiac.degree,
+ absoluteDegree: progressedAscDegree,
+ house: 1,
+ retrograde: false,
+ summary: `Progressed Ascendant in ${progressedAscZodiac.sign} at ${progressedAscZodiac.degree.toFixed(2)}°`
+ };
+
+ // Calculate progressed MC
+ const natalMC = calculateMidheaven(birthDate, birthLongitude);
+ const progressedMC = (natalMC + ageInYears) % 360;
+
+ // Create fallback positions in case of calculation errors
+ const createFallback = (planetName: string): PlanetaryPosition => ({
+ planet: planetName,
+ sign: 'Aries',
+ degree: 0,
+ absoluteDegree: 0,
+ house: 0,
+ retrograde: false,
+ summary: `${planetName} (calculation unavailable)`
+ });
+
+ return {
+ progressedDate,
+ ageInYears,
+ sun: progressedPlanets.find(p => p.planet === 'Progressed Sun') || createFallback('Progressed Sun'),
+ moon: progressedPlanets.find(p => p.planet === 'Progressed Moon') || createFallback('Progressed Moon'),
+ mercury: progressedPlanets.find(p => p.planet === 'Progressed Mercury') || createFallback('Progressed Mercury'),
+ venus: progressedPlanets.find(p => p.planet === 'Progressed Venus') || createFallback('Progressed Venus'),
+ mars: progressedPlanets.find(p => p.planet === 'Progressed Mars') || createFallback('Progressed Mars'),
+ ascendant: progressedAscendant,
+ mc: progressedMC
+ };
+}
+
/**
* Validate birth data
*/
diff --git a/services/geminiService.ts b/services/geminiService.ts
index a5df4a8..5d4f179 100644
--- a/services/geminiService.ts
+++ b/services/geminiService.ts
@@ -218,8 +218,48 @@ export const generateFullReport = async (data: UserBirthData): Promise p.planet === 'Sun');
+ const moonPos = planetaryPositions.find(p => p.planet === 'Moon');
+ const partOfFortune = sunPos && moonPos
+ ? AstroCalc.calculatePartOfFortune(
+ ascendant,
+ sunPos.absoluteDegree!,
+ moonPos.absoluteDegree!,
+ AstroCalc.isDayBirth(sunPos.absoluteDegree!, ascendant),
+ birthDateTime,
+ birthLat,
+ birthLng
+ )
+ : null;
+
+ // Add Ascendant as a planetary position
+ const ascendantPos = {
+ planet: 'Ascendant',
+ sign: ascendantSign.sign,
+ degree: ascendantSign.degree,
+ absoluteDegree: ascendant,
+ house: 1,
+ retrograde: false,
+ summary: `Ascendant in ${ascendantSign.sign} - Your rising sign and outer personality`
+ };
+
+ // Combine all positions
+ const allPlanetaryPositions = [
+ ...planetaryPositions,
+ ascendantPos,
+ northNode,
+ southNode,
+ lilith,
+ ...(partOfFortune ? [partOfFortune] : [])
+ ];
+
+ // Calculate aspects (including new points)
+ const aspects = AstroCalc.calculateAspects(allPlanetaryPositions);
// === NUMEROLOGY CALCULATIONS ===
const numerology = NumService.calculateCompleteNumerology(data.date, data.name);
@@ -249,8 +289,8 @@ export const generateFullReport = async (data: UserBirthData): Promise `${p.planet}: ${p.sign} ${p.degree.toFixed(2)}°, House ${p.house}${p.retrograde ? ' (R)' : ''}`).join('\n')}
+ Planetary Positions (including significant points):
+ ${allPlanetaryPositions.map(p => `${p.planet}: ${p.sign} ${p.degree.toFixed(2)}°, House ${p.house}${p.retrograde ? ' (R)' : ''}`).join('\n')}
Major Aspects:
${aspects.slice(0, 10).map(a => `${a.planet1} ${a.type} ${a.planet2} (orb ${a.orb.toFixed(2)}°)`).join('\n')}
@@ -294,7 +334,7 @@ export const generateFullReport = async (data: UserBirthData): Promise