Spaces:
Runtime error
Runtime error
Create test
#2
by
issamlaradji
- opened
- .gitattributes +0 -4
- .gitignore +2 -69
- 1d_similarity_visualization.html +0 -0
- Dockerfile +6 -3
- app.py +124 -696
- chunks.json +114 -0
- closest_chunk.txt +3 -0
- static/images/icon2.png β embeddings.pkl +2 -2
- rag_utils.py +3 -3
- religions.csv +0 -109
- religions_corpus.txt +196 -0
- requirements.txt +0 -3
- static/design-tokens.css +0 -79
- static/images/Abstract Color Gradient.png +0 -3
- static/images/icon1.png +0 -3
- static/images/icon3.png +0 -3
- static/landing.css +258 -327
- static/script.js +9 -407
- static/style.css +284 -462
- static/video/Animation (Light theme).mp4 +0 -3
- templates/index.html +20 -139
- templates/landing.html +30 -26
- test +1 -0
- tsne_visualization.html +0 -0
.gitattributes
CHANGED
|
@@ -33,7 +33,3 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
-
*.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
-
*.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 38 |
-
static/images/*.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
-
static/video/*.mp4 filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
.gitignore
CHANGED
|
@@ -1,70 +1,3 @@
|
|
| 1 |
-
|
| 2 |
users_data.json
|
| 3 |
-
|
| 4 |
-
# Environment Variables - Contains API Keys
|
| 5 |
-
.env
|
| 6 |
-
|
| 7 |
-
# Firebase Service Account Key - NEVER COMMIT THIS!
|
| 8 |
-
serviceAccountKey.json
|
| 9 |
-
*serviceAccountKey*.json
|
| 10 |
-
firebase-adminsdk-*.json
|
| 11 |
-
|
| 12 |
-
# Python Virtual Environment
|
| 13 |
-
.venv/
|
| 14 |
-
venv/
|
| 15 |
-
env/
|
| 16 |
-
ENV/
|
| 17 |
-
|
| 18 |
-
# Python Cache
|
| 19 |
-
__pycache__/
|
| 20 |
-
*.py[cod]
|
| 21 |
-
*$py.class
|
| 22 |
-
*.so
|
| 23 |
-
|
| 24 |
-
# Flask
|
| 25 |
-
instance/
|
| 26 |
-
.webassets-cache
|
| 27 |
-
|
| 28 |
-
# IDE/Editor
|
| 29 |
-
.vscode/
|
| 30 |
-
.idea/
|
| 31 |
-
*.swp
|
| 32 |
-
*.swo
|
| 33 |
-
*~
|
| 34 |
-
.DS_Store
|
| 35 |
-
|
| 36 |
-
# Logs
|
| 37 |
-
*.log
|
| 38 |
-
|
| 39 |
-
# Distribution / packaging
|
| 40 |
-
.Python
|
| 41 |
-
build/
|
| 42 |
-
develop-eggs/
|
| 43 |
-
dist/
|
| 44 |
-
downloads/
|
| 45 |
-
eggs/
|
| 46 |
-
.eggs/
|
| 47 |
-
lib/
|
| 48 |
-
lib64/
|
| 49 |
-
parts/
|
| 50 |
-
sdist/
|
| 51 |
-
var/
|
| 52 |
-
wheels/
|
| 53 |
-
*.egg-info/
|
| 54 |
-
.installed.cfg
|
| 55 |
-
*.egg
|
| 56 |
-
|
| 57 |
-
# Testing
|
| 58 |
-
.pytest_cache/
|
| 59 |
-
.coverage
|
| 60 |
-
htmlcov/
|
| 61 |
-
|
| 62 |
-
# RAG test data
|
| 63 |
-
rag_data/
|
| 64 |
-
|
| 65 |
-
# Other
|
| 66 |
-
*.bak
|
| 67 |
-
*.tmp
|
| 68 |
-
|
| 69 |
-
docs/
|
| 70 |
-
etc/
|
|
|
|
| 1 |
+
.venv
|
| 2 |
users_data.json
|
| 3 |
+
.vscode
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1d_similarity_visualization.html
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Dockerfile
CHANGED
|
@@ -11,8 +11,11 @@ RUN pip install --no-cache-dir --upgrade -r requirements.txt
|
|
| 11 |
|
| 12 |
COPY --chown=user . /app
|
| 13 |
|
| 14 |
-
#
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
# Run with Gunicorn
|
| 18 |
-
CMD ["gunicorn", "-w", "1", "-b", "0.0.0.0:
|
|
|
|
| 11 |
|
| 12 |
COPY --chown=user . /app
|
| 13 |
|
| 14 |
+
# Install Flask
|
| 15 |
+
RUN pip install flask gunicorn pymupdf tiktoken
|
| 16 |
+
|
| 17 |
+
# Expose default port
|
| 18 |
+
EXPOSE 7860
|
| 19 |
|
| 20 |
# Run with Gunicorn
|
| 21 |
+
CMD ["gunicorn", "-w", "1", "-b", "0.0.0.0:7860", "app:app"]
|
app.py
CHANGED
|
@@ -9,294 +9,119 @@ from flask import Flask, render_template, request, jsonify, session, redirect, u
|
|
| 9 |
from werkzeug.security import generate_password_hash, check_password_hash
|
| 10 |
import json
|
| 11 |
import os
|
| 12 |
-
import re
|
| 13 |
-
import secrets
|
| 14 |
from dotenv import load_dotenv
|
| 15 |
from together import Together
|
| 16 |
from rag_utils import load_religions_from_csv, prepare_religion_rag_context
|
| 17 |
-
from openai import OpenAI
|
| 18 |
-
import firebase_admin
|
| 19 |
-
from firebase_admin import credentials, auth, firestore
|
| 20 |
|
| 21 |
load_dotenv()
|
| 22 |
|
| 23 |
app = Flask(__name__)
|
| 24 |
-
app.secret_key =
|
| 25 |
|
| 26 |
# Session configuration for production deployment
|
| 27 |
-
app.config['SESSION_COOKIE_SECURE'] =
|
| 28 |
app.config['SESSION_COOKIE_HTTPONLY'] = True
|
| 29 |
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'
|
| 30 |
app.config['PERMANENT_SESSION_LIFETIME'] = 3600 # 1 hour
|
| 31 |
|
| 32 |
-
# Initialize Firebase Admin SDK
|
| 33 |
-
try:
|
| 34 |
-
firebase_cred_path = os.getenv('FIREBASE_CREDENTIALS_PATH', 'serviceAccountKey.json')
|
| 35 |
-
if os.path.exists(firebase_cred_path):
|
| 36 |
-
cred = credentials.Certificate(firebase_cred_path)
|
| 37 |
-
firebase_admin.initialize_app(cred)
|
| 38 |
-
db = firestore.client()
|
| 39 |
-
print("β
Firebase initialized successfully")
|
| 40 |
-
else:
|
| 41 |
-
print(f"β οΈ Firebase credentials not found at {firebase_cred_path}")
|
| 42 |
-
db = None
|
| 43 |
-
except Exception as e:
|
| 44 |
-
print(f"β οΈ Firebase initialization failed: {e}")
|
| 45 |
-
db = None
|
| 46 |
-
|
| 47 |
-
# Firebase Web Config (for frontend)
|
| 48 |
-
FIREBASE_CONFIG = {
|
| 49 |
-
'apiKey': os.getenv('FIREBASE_WEB_API_KEY'),
|
| 50 |
-
'authDomain': os.getenv('FIREBASE_AUTH_DOMAIN'),
|
| 51 |
-
'projectId': os.getenv('FIREBASE_PROJECT_ID'),
|
| 52 |
-
'storageBucket': os.getenv('FIREBASE_STORAGE_BUCKET', f"{os.getenv('FIREBASE_PROJECT_ID')}.appspot.com"),
|
| 53 |
-
'messagingSenderId': os.getenv('FIREBASE_MESSAGING_SENDER_ID'),
|
| 54 |
-
'appId': os.getenv('FIREBASE_APP_ID')
|
| 55 |
-
}
|
| 56 |
-
|
| 57 |
# File to store user data - defaults to current directory (writable in Docker)
|
| 58 |
-
# Keep for backward compatibility during transition
|
| 59 |
USERS_FILE = os.getenv("USERS_FILE", "users_data.json")
|
| 60 |
|
| 61 |
# Together API for chatbot
|
| 62 |
TOGETHER_API_KEY = os.getenv("TOGETHER_API_KEY")
|
| 63 |
client = Together(api_key=TOGETHER_API_KEY) if TOGETHER_API_KEY else None
|
| 64 |
|
| 65 |
-
# OpenAI for Whisper transcription
|
| 66 |
-
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
| 67 |
-
openai_client = OpenAI(api_key=OPENAI_API_KEY) if OPENAI_API_KEY else None
|
| 68 |
-
|
| 69 |
# Load detailed religion data at startup
|
| 70 |
RELIGIONS_CSV = load_religions_from_csv('religions.csv')
|
| 71 |
|
| 72 |
-
|
| 73 |
-
# Aliases map inconsistent keys to canonical ones
|
| 74 |
-
TRADITION_ALIASES = {
|
| 75 |
-
"secular": "humanism",
|
| 76 |
-
"secularism": "humanism",
|
| 77 |
-
"spiritualism": "spiritual_not_religious",
|
| 78 |
-
"wicca": "paganism",
|
| 79 |
-
"zen": "buddhism",
|
| 80 |
-
"pantheism": "paganism",
|
| 81 |
-
"unitarian": "spiritual_not_religious",
|
| 82 |
-
"deism": "agnosticism"
|
| 83 |
-
}
|
| 84 |
-
|
| 85 |
-
def canon(key):
|
| 86 |
-
"""Normalize tradition key to canonical form"""
|
| 87 |
-
return TRADITION_ALIASES.get(key, key)
|
| 88 |
-
|
| 89 |
-
# Question importance weights (higher = more significant)
|
| 90 |
-
QUESTION_WEIGHTS = {
|
| 91 |
-
1: 5, # Nature of the divine (most fundamental)
|
| 92 |
-
2: 3, # Spiritual connection style
|
| 93 |
-
3: 4, # Afterlife beliefs
|
| 94 |
-
4: 4, # Moral/ethical foundation
|
| 95 |
-
5: 3, # Prayer practices
|
| 96 |
-
6: 3, # Ritual/practice style
|
| 97 |
-
7: 3, # Human-nature relationship
|
| 98 |
-
8: 3, # View on suffering
|
| 99 |
-
9: 2 # Community importance
|
| 100 |
-
}
|
| 101 |
-
|
| 102 |
-
# Assessment Questions ----------------------------
|
| 103 |
QUESTIONS = [
|
| 104 |
{
|
| 105 |
"id": 1,
|
| 106 |
"question": "What is your view on the nature of the divine?",
|
| 107 |
"options": {
|
| 108 |
-
"One supreme God who created everything": {
|
| 109 |
-
|
| 110 |
-
},
|
| 111 |
-
"
|
| 112 |
-
|
| 113 |
-
},
|
| 114 |
-
"A universal energy or force": {
|
| 115 |
-
"taoism": 5, "buddhism": 4, "new_age": 4, "spiritual_not_religious": 3
|
| 116 |
-
},
|
| 117 |
-
"No divine being, focus on human potential": {
|
| 118 |
-
"humanism": 5, "atheism": 5, "stoicism": 3, "confucianism": 2
|
| 119 |
-
},
|
| 120 |
-
"Uncertain or unknowable": {
|
| 121 |
-
"agnosticism": 5, "spiritual_not_religious": 2
|
| 122 |
-
}
|
| 123 |
}
|
| 124 |
},
|
| 125 |
{
|
| 126 |
"id": 2,
|
| 127 |
"question": "How do you prefer to connect with spirituality?",
|
| 128 |
"options": {
|
| 129 |
-
"Through organized worship and community": {
|
| 130 |
-
|
| 131 |
-
},
|
| 132 |
-
"Through
|
| 133 |
-
|
| 134 |
-
},
|
| 135 |
-
"Through nature and natural cycles": {
|
| 136 |
-
"paganism": 5, "indigenous": 5, "shintoism": 4
|
| 137 |
-
},
|
| 138 |
-
"Through reason and philosophy": {
|
| 139 |
-
"stoicism": 5, "humanism": 4, "confucianism": 3
|
| 140 |
-
},
|
| 141 |
-
"I don't feel the need for spiritual connection": {
|
| 142 |
-
"atheism": 5, "humanism": 2
|
| 143 |
-
}
|
| 144 |
}
|
| 145 |
},
|
| 146 |
{
|
| 147 |
"id": 3,
|
| 148 |
"question": "What is your belief about the afterlife?",
|
| 149 |
"options": {
|
| 150 |
-
"Heaven or Hell based on faith/deeds": {
|
| 151 |
-
|
| 152 |
-
},
|
| 153 |
-
"
|
| 154 |
-
|
| 155 |
-
},
|
| 156 |
-
"Ancestral realm or spiritual world": {
|
| 157 |
-
"indigenous": 4, "paganism": 3, "shintoism": 3, "confucianism": 2
|
| 158 |
-
},
|
| 159 |
-
"No afterlife, this life is all there is": {
|
| 160 |
-
"atheism": 5, "humanism": 4, "stoicism": 2
|
| 161 |
-
},
|
| 162 |
-
"Unsure or open to possibilities": {
|
| 163 |
-
"agnosticism": 4, "new_age": 3, "spiritual_not_religious": 3
|
| 164 |
-
}
|
| 165 |
}
|
| 166 |
},
|
| 167 |
{
|
| 168 |
"id": 4,
|
| 169 |
"question": "What guides your moral and ethical decisions?",
|
| 170 |
"options": {
|
| 171 |
-
"Sacred texts and religious teachings": {
|
| 172 |
-
|
| 173 |
-
},
|
| 174 |
-
"
|
| 175 |
-
|
| 176 |
-
},
|
| 177 |
-
"Harmony with nature and balance": {
|
| 178 |
-
"taoism": 5, "indigenous": 4, "shintoism": 3, "paganism": 3
|
| 179 |
-
},
|
| 180 |
-
"Reason, empathy, and human rights": {
|
| 181 |
-
"humanism": 5, "atheism": 3, "stoicism": 3
|
| 182 |
-
},
|
| 183 |
-
"Personal intuition and inner wisdom": {
|
| 184 |
-
"spiritual_not_religious": 5, "new_age": 4
|
| 185 |
-
},
|
| 186 |
-
"Virtue, duty, and social harmony": {
|
| 187 |
-
"confucianism": 5, "stoicism": 4
|
| 188 |
-
}
|
| 189 |
}
|
| 190 |
},
|
| 191 |
{
|
| 192 |
"id": 5,
|
| 193 |
-
"question": "
|
| 194 |
"options": {
|
| 195 |
-
"
|
| 196 |
-
|
| 197 |
-
},
|
| 198 |
-
"
|
| 199 |
-
|
| 200 |
-
},
|
| 201 |
-
"Daily meditation or mindfulness practice": {
|
| 202 |
-
"buddhism": 5, "hinduism": 4, "jainism": 4
|
| 203 |
-
},
|
| 204 |
-
"Occasional prayer or reflection when needed": {
|
| 205 |
-
"christianity": 2, "judaism": 2, "spiritual_not_religious": 3, "new_age": 2
|
| 206 |
-
},
|
| 207 |
-
"Meditation for inner peace, not religious practice": {
|
| 208 |
-
"stoicism": 3, "humanism": 2, "buddhism": 2
|
| 209 |
-
},
|
| 210 |
-
"I don't pray or meditate": {
|
| 211 |
-
"atheism": 4, "humanism": 3
|
| 212 |
-
}
|
| 213 |
}
|
| 214 |
},
|
| 215 |
{
|
| 216 |
"id": 6,
|
| 217 |
-
"question": "What role do rituals and ceremonies play in your life?",
|
| 218 |
-
"options": {
|
| 219 |
-
"Essential - weekly services and holy day observances": {
|
| 220 |
-
"christianity": 4, "islam": 4, "judaism": 5, "hinduism": 3
|
| 221 |
-
},
|
| 222 |
-
"Important - seasonal celebrations and nature rituals": {
|
| 223 |
-
"paganism": 5, "indigenous": 5, "shintoism": 4
|
| 224 |
-
},
|
| 225 |
-
"Helpful - personal rituals that feel meaningful": {
|
| 226 |
-
"new_age": 4, "spiritual_not_religious": 4, "hinduism": 2
|
| 227 |
-
},
|
| 228 |
-
"Minimal - prefer contemplation and philosophy": {
|
| 229 |
-
"stoicism": 4, "humanism": 3, "confucianism": 2, "agnosticism": 2
|
| 230 |
-
},
|
| 231 |
-
"None - I don't practice rituals": {
|
| 232 |
-
"atheism": 4, "humanism": 2
|
| 233 |
-
}
|
| 234 |
-
}
|
| 235 |
-
},
|
| 236 |
-
{
|
| 237 |
-
"id": 7,
|
| 238 |
"question": "How do you view the relationship between humans and nature?",
|
| 239 |
"options": {
|
| 240 |
-
"Humans are stewards of God's creation": {
|
| 241 |
-
|
| 242 |
-
},
|
| 243 |
-
"
|
| 244 |
-
|
| 245 |
-
},
|
| 246 |
-
"Nature itself is divine and should be revered": {
|
| 247 |
-
"paganism": 5, "indigenous": 4, "shintoism": 5, "taoism": 3
|
| 248 |
-
},
|
| 249 |
-
"Nature follows natural laws we can study": {
|
| 250 |
-
"atheism": 4, "humanism": 4, "stoicism": 2
|
| 251 |
-
},
|
| 252 |
-
"We should live in harmony with natural flow": {
|
| 253 |
-
"taoism": 5, "buddhism": 3, "shintoism": 3, "indigenous": 3
|
| 254 |
-
}
|
| 255 |
}
|
| 256 |
},
|
| 257 |
{
|
| 258 |
-
"id":
|
| 259 |
"question": "What is your view on suffering and its purpose?",
|
| 260 |
"options": {
|
| 261 |
-
"A test of faith or part of God's plan": {
|
| 262 |
-
|
| 263 |
-
},
|
| 264 |
-
"
|
| 265 |
-
|
| 266 |
-
},
|
| 267 |
-
"Karma from past actions and choices": {
|
| 268 |
-
"hinduism": 5, "sikhism": 4, "buddhism": 3, "jainism": 3
|
| 269 |
-
},
|
| 270 |
-
"Natural part of life without cosmic meaning": {
|
| 271 |
-
"atheism": 5, "humanism": 3, "stoicism": 2
|
| 272 |
-
},
|
| 273 |
-
"An opportunity for spiritual growth": {
|
| 274 |
-
"new_age": 4, "spiritual_not_religious": 3, "christianity": 2
|
| 275 |
-
},
|
| 276 |
-
"To be accepted with virtue and equanimity": {
|
| 277 |
-
"stoicism": 5, "buddhism": 2, "confucianism": 2
|
| 278 |
-
}
|
| 279 |
}
|
| 280 |
},
|
| 281 |
{
|
| 282 |
-
"id":
|
| 283 |
"question": "How important is community in your spiritual life?",
|
| 284 |
"options": {
|
| 285 |
-
"Very important
|
| 286 |
-
|
| 287 |
-
},
|
| 288 |
-
"
|
| 289 |
-
|
| 290 |
-
},
|
| 291 |
-
"Community of like-minded spiritual seekers": {
|
| 292 |
-
"paganism": 4, "spiritual_not_religious": 4, "new_age": 3
|
| 293 |
-
},
|
| 294 |
-
"Not important - spirituality is deeply personal": {
|
| 295 |
-
"spiritual_not_religious": 3, "agnosticism": 3, "taoism": 2
|
| 296 |
-
},
|
| 297 |
-
"Prefer secular community over religious": {
|
| 298 |
-
"humanism": 4, "atheism": 4, "stoicism": 2
|
| 299 |
-
}
|
| 300 |
}
|
| 301 |
}
|
| 302 |
]
|
|
@@ -316,60 +141,11 @@ RELIGIONS = {
|
|
| 316 |
"new_age": {"name": "New Age Spirituality", "description": "Eclectic approach emphasizing personal growth.", "practices": "Meditation, energy work, crystals, yoga", "core_beliefs": "Personal transformation, universal consciousness"},
|
| 317 |
"spiritual_not_religious": {"name": "Spiritual But Not Religious", "description": "Personal spirituality without organized religion.", "practices": "Personal practices, meditation, self-reflection", "core_beliefs": "Individual journey, authenticity, diverse wisdom"},
|
| 318 |
"sikhism": {"name": "Sikhism", "description": "One God emphasizing service, equality, and meditation.", "practices": "Prayer, meditation, community service, 5 Ks", "core_beliefs": "One God, equality, honest living, sharing"},
|
| 319 |
-
"indigenous": {"name": "Indigenous Spirituality", "description": "Traditional practices honoring ancestors and land.", "practices": "Ceremonies, storytelling, seasonal rituals", "core_beliefs": "Land connection, ancestor veneration, reciprocity"}
|
| 320 |
-
"jainism": {"name": "Jainism", "description": "Ancient path emphasizing non-violence and spiritual purification.", "practices": "Meditation, fasting, non-violence, self-discipline", "core_beliefs": "Ahimsa (non-violence), karma liberation, asceticism"},
|
| 321 |
-
"shintoism": {"name": "Shinto", "description": "Japanese tradition honoring kami spirits and natural harmony.", "practices": "Shrine visits, purification rituals, festivals", "core_beliefs": "Kami reverence, purity, harmony with nature"},
|
| 322 |
-
"stoicism": {"name": "Stoicism", "description": "Philosophy emphasizing virtue, reason, and acceptance of fate.", "practices": "Contemplation, virtue practice, rational thinking", "core_beliefs": "Virtue, reason, acceptance, inner peace"},
|
| 323 |
-
"confucianism": {"name": "Confucianism", "description": "Philosophy emphasizing moral cultivation and social harmony.", "practices": "Ritual propriety, study, self-cultivation", "core_beliefs": "Filial piety, benevolence, social harmony"}
|
| 324 |
}
|
| 325 |
|
| 326 |
-
|
| 327 |
-
# ============================================================================
|
| 328 |
-
# FIRESTORE HELPER FUNCTIONS
|
| 329 |
-
# ============================================================================
|
| 330 |
-
|
| 331 |
-
def get_user_by_uid(uid):
|
| 332 |
-
"""Get user data from Firestore by Firebase UID"""
|
| 333 |
-
if not db:
|
| 334 |
-
return None
|
| 335 |
-
try:
|
| 336 |
-
user_ref = db.collection('users').document(uid)
|
| 337 |
-
user_doc = user_ref.get()
|
| 338 |
-
if user_doc.exists:
|
| 339 |
-
return user_doc.to_dict()
|
| 340 |
-
return None
|
| 341 |
-
except Exception as e:
|
| 342 |
-
print(f"Error getting user {uid}: {e}")
|
| 343 |
-
return None
|
| 344 |
-
|
| 345 |
-
def create_or_update_user(uid, user_data):
|
| 346 |
-
"""Create or update user in Firestore"""
|
| 347 |
-
if not db:
|
| 348 |
-
return False
|
| 349 |
-
try:
|
| 350 |
-
user_ref = db.collection('users').document(uid)
|
| 351 |
-
user_ref.set(user_data, merge=True)
|
| 352 |
-
return True
|
| 353 |
-
except Exception as e:
|
| 354 |
-
print(f"Error saving user {uid}: {e}")
|
| 355 |
-
return False
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
def verify_firebase_token(id_token):
|
| 360 |
-
"""Verify Firebase ID token and return decoded token"""
|
| 361 |
-
try:
|
| 362 |
-
decoded_token = auth.verify_id_token(id_token)
|
| 363 |
-
return decoded_token
|
| 364 |
-
except Exception as e:
|
| 365 |
-
print(f"Token verification error: {e}")
|
| 366 |
-
return None
|
| 367 |
-
|
| 368 |
-
# ============================================================================
|
| 369 |
-
# LEGACY JSON FILE FUNCTIONS (for backward compatibility)
|
| 370 |
-
# ============================================================================
|
| 371 |
-
|
| 372 |
def load_users():
|
|
|
|
| 373 |
try:
|
| 374 |
if os.path.exists(USERS_FILE):
|
| 375 |
with open(USERS_FILE, 'r') as f:
|
|
@@ -396,8 +172,6 @@ def initialize_default_user():
|
|
| 396 |
if not users: # Only create if no users exist
|
| 397 |
users['test'] = {
|
| 398 |
'password': generate_password_hash('test'),
|
| 399 |
-
'email': 'test@example.com',
|
| 400 |
-
'verified': True,
|
| 401 |
'answers': [],
|
| 402 |
'results': []
|
| 403 |
}
|
|
@@ -405,76 +179,27 @@ def initialize_default_user():
|
|
| 405 |
print("β
Default test user created (username: test, password: test)")
|
| 406 |
|
| 407 |
def calculate_results(answers):
|
| 408 |
-
"""
|
| 409 |
-
Calculate which spiritual paths align with user's answers
|
| 410 |
-
Uses weighted scoring with canonical tradition keys and tie-breakers
|
| 411 |
-
"""
|
| 412 |
scores = {}
|
| 413 |
-
coverage = {} # Track number of questions contributing to each tradition (for tie-breaking)
|
| 414 |
|
| 415 |
-
# Calculate weighted scores
|
| 416 |
for answer in answers:
|
| 417 |
question = next((q for q in QUESTIONS if q["id"] == answer["question_id"]), None)
|
| 418 |
if question and answer["answer"] in question["options"]:
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
|
| 422 |
-
# Track which traditions are scored in this question (for tie-breaker)
|
| 423 |
-
touched_this_question = set()
|
| 424 |
-
|
| 425 |
-
for tradition_key, base_points in points_map.items():
|
| 426 |
-
# Normalize tradition key to canonical form
|
| 427 |
-
canonical_key = canon(tradition_key)
|
| 428 |
-
|
| 429 |
-
# Calculate weighted score
|
| 430 |
-
weighted_score = base_points * question_weight
|
| 431 |
-
scores[canonical_key] = scores.get(canonical_key, 0) + weighted_score
|
| 432 |
-
touched_this_question.add(canonical_key)
|
| 433 |
-
|
| 434 |
-
# Update coverage count for tie-breaking
|
| 435 |
-
for key in touched_this_question:
|
| 436 |
-
coverage[key] = coverage.get(key, 0) + 1
|
| 437 |
-
|
| 438 |
-
# Calculate maximum possible score for percentage calculation
|
| 439 |
-
max_possible_score = 0
|
| 440 |
-
for answer in answers:
|
| 441 |
-
question = next((q for q in QUESTIONS if q["id"] == answer["question_id"]), None)
|
| 442 |
-
if question:
|
| 443 |
-
# Find the highest point value among all options for this question
|
| 444 |
-
max_option_points = 0
|
| 445 |
-
for option_scores in question["options"].values():
|
| 446 |
-
if option_scores:
|
| 447 |
-
max_option_points = max(max_option_points, max(option_scores.values()))
|
| 448 |
-
|
| 449 |
-
question_weight = QUESTION_WEIGHTS.get(answer["question_id"], 1)
|
| 450 |
-
max_possible_score += max_option_points * question_weight
|
| 451 |
|
| 452 |
-
# Sort by score
|
| 453 |
-
|
| 454 |
-
sorted_scores = sorted(
|
| 455 |
-
scores.items(),
|
| 456 |
-
key=lambda x: (x[1], coverage.get(x[0], 0)),
|
| 457 |
-
reverse=True
|
| 458 |
-
)
|
| 459 |
|
| 460 |
-
#
|
| 461 |
recommendations = []
|
| 462 |
-
for
|
| 463 |
-
if
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
if max_possible_score > 0:
|
| 469 |
-
tradition_info["percentage"] = round((score / max_possible_score) * 100)
|
| 470 |
-
else:
|
| 471 |
-
tradition_info["percentage"] = 0
|
| 472 |
-
|
| 473 |
-
recommendations.append(tradition_info)
|
| 474 |
-
|
| 475 |
-
# Stop after top 3
|
| 476 |
-
if len(recommendations) == 3:
|
| 477 |
-
break
|
| 478 |
|
| 479 |
return recommendations
|
| 480 |
|
|
@@ -484,36 +209,22 @@ def landing():
|
|
| 484 |
|
| 485 |
@app.route("/assessment")
|
| 486 |
def assessment():
|
| 487 |
-
|
| 488 |
-
user_id = session.get('user_id')
|
| 489 |
-
username = session.get('username')
|
| 490 |
-
|
| 491 |
-
if not user_id and not username:
|
| 492 |
return redirect(url_for('login'))
|
| 493 |
|
| 494 |
-
|
| 495 |
-
|
| 496 |
-
|
| 497 |
-
user_data = get_user_by_uid(user_id) or {}
|
| 498 |
-
display_name = session.get('email', 'User')
|
| 499 |
-
has_results = 'results' in user_data and user_data['results']
|
| 500 |
-
else:
|
| 501 |
-
# Legacy user
|
| 502 |
-
users = load_users()
|
| 503 |
-
user_data = users.get(username, {})
|
| 504 |
-
display_name = username
|
| 505 |
-
has_results = 'results' in user_data and user_data['results']
|
| 506 |
|
| 507 |
return render_template(
|
| 508 |
"index.html",
|
| 509 |
title="Spiritual Path Finder",
|
| 510 |
-
message=f"Welcome, {
|
| 511 |
-
username=
|
| 512 |
logged_in=True,
|
| 513 |
questions=QUESTIONS,
|
| 514 |
has_results=has_results,
|
| 515 |
-
results=user_data.get('results', []) if has_results else []
|
| 516 |
-
firebase_config=FIREBASE_CONFIG
|
| 517 |
)
|
| 518 |
|
| 519 |
@app.route("/login", methods=["GET", "POST"])
|
|
@@ -523,77 +234,39 @@ def login():
|
|
| 523 |
data = request.get_json()
|
| 524 |
if not data:
|
| 525 |
return jsonify({"success": False, "message": "Invalid request"}), 400
|
|
|
|
|
|
|
|
|
|
| 526 |
|
| 527 |
-
|
| 528 |
-
|
| 529 |
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
|
| 535 |
-
|
| 536 |
-
uid = decoded_token['uid']
|
| 537 |
-
email = decoded_token.get('email', '')
|
| 538 |
-
|
| 539 |
-
# Check if user exists in Firestore, create if not
|
| 540 |
-
user_data = get_user_by_uid(uid)
|
| 541 |
-
if not user_data:
|
| 542 |
-
# Create new user document
|
| 543 |
-
create_or_update_user(uid, {
|
| 544 |
-
'email': email,
|
| 545 |
-
'answers': [],
|
| 546 |
-
'results': [],
|
| 547 |
-
'created_at': firestore.SERVER_TIMESTAMP
|
| 548 |
-
})
|
| 549 |
-
|
| 550 |
-
# Store UID in session
|
| 551 |
-
session['user_id'] = uid
|
| 552 |
-
session['email'] = email
|
| 553 |
-
session.permanent = True
|
| 554 |
-
return jsonify({"success": True})
|
| 555 |
-
else:
|
| 556 |
-
# Legacy username/password flow (backward compatibility)
|
| 557 |
-
username = data.get('username', '').strip()
|
| 558 |
-
password = data.get('password', '')
|
| 559 |
-
|
| 560 |
-
if not username or not password:
|
| 561 |
-
return jsonify({"success": False, "message": "Username and password required"}), 400
|
| 562 |
-
|
| 563 |
-
users = load_users()
|
| 564 |
-
if username not in users:
|
| 565 |
-
return jsonify({"success": False, "message": "Invalid credentials"}), 401
|
| 566 |
-
|
| 567 |
-
user_data = users[username]
|
| 568 |
-
|
| 569 |
-
# Check if email is verified
|
| 570 |
-
if not user_data.get('verified', True):
|
| 571 |
-
return jsonify({"success": False, "message": "Please verify your email first. Check your inbox."}), 403
|
| 572 |
-
|
| 573 |
-
stored = user_data['password']
|
| 574 |
-
|
| 575 |
-
# Try hash-based verification first
|
| 576 |
-
if stored.startswith(('scrypt:', 'pbkdf2:')):
|
| 577 |
if check_password_hash(stored, password):
|
| 578 |
session['username'] = username
|
| 579 |
-
session.permanent = True
|
| 580 |
return jsonify({"success": True})
|
| 581 |
-
|
| 582 |
-
|
|
|
|
|
|
|
|
|
|
| 583 |
users[username]['password'] = generate_password_hash(password)
|
| 584 |
if not save_users(users):
|
| 585 |
return jsonify({"success": False, "message": "Error saving data"}), 500
|
| 586 |
session['username'] = username
|
| 587 |
-
session.permanent = True
|
| 588 |
return jsonify({"success": True})
|
| 589 |
-
|
| 590 |
-
|
| 591 |
except Exception as e:
|
| 592 |
print(f"Login error: {e}")
|
| 593 |
return jsonify({"success": False, "message": "Server error"}), 500
|
| 594 |
|
| 595 |
-
|
| 596 |
-
return render_template("index.html", logged_in=False, is_signup=False, firebase_config=FIREBASE_CONFIG)
|
| 597 |
|
| 598 |
@app.route("/signup", methods=["GET", "POST"])
|
| 599 |
def signup():
|
|
@@ -602,239 +275,44 @@ def signup():
|
|
| 602 |
data = request.get_json()
|
| 603 |
if not data:
|
| 604 |
return jsonify({"success": False, "message": "Invalid request"}), 400
|
| 605 |
-
|
| 606 |
-
# Firebase authentication - verify ID token from frontend
|
| 607 |
-
id_token = data.get('idToken')
|
| 608 |
-
|
| 609 |
-
if id_token:
|
| 610 |
-
# Firebase signup flow (user already created by Firebase Auth on frontend)
|
| 611 |
-
decoded_token = verify_firebase_token(id_token)
|
| 612 |
-
if not decoded_token:
|
| 613 |
-
return jsonify({"success": False, "message": "Invalid authentication token"}), 401
|
| 614 |
-
|
| 615 |
-
uid = decoded_token['uid']
|
| 616 |
-
email = decoded_token.get('email', '')
|
| 617 |
-
|
| 618 |
-
# Create user document in Firestore
|
| 619 |
-
user_data = {
|
| 620 |
-
'email': email,
|
| 621 |
-
'answers': [],
|
| 622 |
-
'results': [],
|
| 623 |
-
'created_at': firestore.SERVER_TIMESTAMP
|
| 624 |
-
}
|
| 625 |
-
|
| 626 |
-
if create_or_update_user(uid, user_data):
|
| 627 |
-
session['user_id'] = uid
|
| 628 |
-
session['email'] = email
|
| 629 |
-
session.permanent = True
|
| 630 |
-
return jsonify({
|
| 631 |
-
"success": True,
|
| 632 |
-
"message": "Account created successfully!"
|
| 633 |
-
})
|
| 634 |
-
else:
|
| 635 |
-
return jsonify({"success": False, "message": "Error creating user profile"}), 500
|
| 636 |
-
else:
|
| 637 |
-
# Legacy username/password flow (backward compatibility)
|
| 638 |
-
username = data.get('username', '').strip()
|
| 639 |
-
password = data.get('password', '')
|
| 640 |
-
email = data.get('email', '').strip().lower()
|
| 641 |
-
|
| 642 |
-
if not username or not password:
|
| 643 |
-
return jsonify({"success": False, "message": "Username and password required"}), 400
|
| 644 |
-
|
| 645 |
-
if not email:
|
| 646 |
-
return jsonify({"success": False, "message": "Email is required"}), 400
|
| 647 |
|
| 648 |
-
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
users = load_users()
|
| 652 |
-
|
| 653 |
-
if username in users:
|
| 654 |
-
return jsonify({"success": False, "message": "Username already exists"}), 409
|
| 655 |
-
|
| 656 |
-
# Check if email already exists
|
| 657 |
-
for user_data in users.values():
|
| 658 |
-
if user_data.get('email') == email:
|
| 659 |
-
return jsonify({"success": False, "message": "Email already registered"}), 409
|
| 660 |
-
|
| 661 |
-
# Generate verification token
|
| 662 |
-
token = secrets.token_urlsafe(32)
|
| 663 |
-
VERIFICATION_TOKENS[token] = {
|
| 664 |
-
'username': username,
|
| 665 |
-
'email': email,
|
| 666 |
-
'password': password,
|
| 667 |
-
'timestamp': os.path.getmtime(USERS_FILE) if os.path.exists(USERS_FILE) else 0
|
| 668 |
-
}
|
| 669 |
-
|
| 670 |
-
# Send verification email
|
| 671 |
-
send_verification_email(email, token)
|
| 672 |
-
|
| 673 |
-
# Create user with verified status (auto-verify in dev mode)
|
| 674 |
-
users[username] = {
|
| 675 |
-
'password': generate_password_hash(password),
|
| 676 |
-
'email': email,
|
| 677 |
-
'verified': True, # Auto-verify in dev mode
|
| 678 |
-
'answers': [],
|
| 679 |
-
'results': []
|
| 680 |
-
}
|
| 681 |
-
|
| 682 |
-
if not save_users(users):
|
| 683 |
-
return jsonify({"success": False, "message": "Error saving user data"}), 500
|
| 684 |
-
|
| 685 |
-
return jsonify({
|
| 686 |
-
"success": True,
|
| 687 |
-
"message": "Account created! Please check your email to verify your account.",
|
| 688 |
-
"verification_sent": True
|
| 689 |
-
})
|
| 690 |
-
except Exception as e:
|
| 691 |
-
print(f"Signup error: {e}")
|
| 692 |
-
return jsonify({"success": False, "message": "Server error"}), 500
|
| 693 |
-
|
| 694 |
-
# Pass Firebase config to template
|
| 695 |
-
return render_template("index.html", logged_in=False, is_signup=True, firebase_config=FIREBASE_CONFIG)
|
| 696 |
-
|
| 697 |
-
@app.route("/forgot-password", methods=["GET", "POST"])
|
| 698 |
-
def forgot_password():
|
| 699 |
-
if request.method == "POST":
|
| 700 |
-
try:
|
| 701 |
-
data = request.get_json()
|
| 702 |
-
if not data:
|
| 703 |
-
return jsonify({"success": False, "message": "Invalid request"}), 400
|
| 704 |
-
|
| 705 |
-
email = data.get('email', '').strip().lower()
|
| 706 |
|
| 707 |
-
if not
|
| 708 |
-
return jsonify({"success": False, "message": "
|
| 709 |
-
|
| 710 |
-
if not validate_email(email):
|
| 711 |
-
return jsonify({"success": False, "message": "Invalid email format"}), 400
|
| 712 |
|
| 713 |
users = load_users()
|
| 714 |
|
| 715 |
-
|
| 716 |
-
|
| 717 |
-
for username, user_data in users.items():
|
| 718 |
-
if user_data.get('email') == email:
|
| 719 |
-
user_found = username
|
| 720 |
-
break
|
| 721 |
-
|
| 722 |
-
if not user_found:
|
| 723 |
-
# Don't reveal that email doesn't exist (security best practice)
|
| 724 |
-
return jsonify({
|
| 725 |
-
"success": True,
|
| 726 |
-
"message": "If that email exists, a reset link has been sent."
|
| 727 |
-
})
|
| 728 |
|
| 729 |
-
#
|
| 730 |
-
|
| 731 |
-
|
| 732 |
-
'
|
| 733 |
-
'
|
| 734 |
-
'type': 'password_reset',
|
| 735 |
-
'timestamp': os.path.getmtime(USERS_FILE) if os.path.exists(USERS_FILE) else 0
|
| 736 |
}
|
| 737 |
|
| 738 |
-
|
| 739 |
-
|
| 740 |
-
|
| 741 |
-
|
| 742 |
-
|
| 743 |
-
"message": "Password reset link sent to your email. Please check your inbox."
|
| 744 |
-
})
|
| 745 |
except Exception as e:
|
| 746 |
-
print(f"
|
| 747 |
return jsonify({"success": False, "message": "Server error"}), 500
|
| 748 |
|
| 749 |
-
return render_template("index.html", logged_in=False, is_signup=
|
| 750 |
-
|
| 751 |
-
@app.route("/reset-password")
|
| 752 |
-
def reset_password_page():
|
| 753 |
-
"""Handle password reset via token - show form to enter new password"""
|
| 754 |
-
token = request.args.get('token')
|
| 755 |
-
if not token or token not in VERIFICATION_TOKENS:
|
| 756 |
-
return render_template("index.html", logged_in=False, is_signup=False,
|
| 757 |
-
reset_error="Invalid or expired reset token"), 400
|
| 758 |
-
|
| 759 |
-
token_data = VERIFICATION_TOKENS[token]
|
| 760 |
-
if token_data.get('type') != 'password_reset':
|
| 761 |
-
return render_template("index.html", logged_in=False, is_signup=False,
|
| 762 |
-
reset_error="Invalid token type"), 400
|
| 763 |
-
|
| 764 |
-
# Store token in session temporarily for password reset form
|
| 765 |
-
session['reset_token'] = token
|
| 766 |
-
return render_template("index.html", logged_in=False, is_signup=False,
|
| 767 |
-
show_reset_form=True, reset_token=token)
|
| 768 |
-
|
| 769 |
-
@app.route("/reset-password-submit", methods=["POST"])
|
| 770 |
-
def reset_password_submit():
|
| 771 |
-
"""Handle password reset submission"""
|
| 772 |
-
try:
|
| 773 |
-
data = request.get_json()
|
| 774 |
-
token = data.get('token')
|
| 775 |
-
new_password = data.get('password', '')
|
| 776 |
-
|
| 777 |
-
if not token or token not in VERIFICATION_TOKENS:
|
| 778 |
-
return jsonify({"success": False, "message": "Invalid or expired token"}), 400
|
| 779 |
-
|
| 780 |
-
if not new_password:
|
| 781 |
-
return jsonify({"success": False, "message": "Password is required"}), 400
|
| 782 |
-
|
| 783 |
-
token_data = VERIFICATION_TOKENS[token]
|
| 784 |
-
if token_data.get('type') != 'password_reset':
|
| 785 |
-
return jsonify({"success": False, "message": "Invalid token type"}), 400
|
| 786 |
-
|
| 787 |
-
# Reset password
|
| 788 |
-
users = load_users()
|
| 789 |
-
username = token_data['username']
|
| 790 |
-
if username in users:
|
| 791 |
-
users[username]['password'] = generate_password_hash(new_password)
|
| 792 |
-
save_users(users)
|
| 793 |
-
del VERIFICATION_TOKENS[token]
|
| 794 |
-
session.pop('reset_token', None)
|
| 795 |
-
return jsonify({"success": True, "message": "Password reset successfully"})
|
| 796 |
-
|
| 797 |
-
return jsonify({"success": False, "message": "User not found"}), 404
|
| 798 |
-
except Exception as e:
|
| 799 |
-
print(f"Password reset submit error: {e}")
|
| 800 |
-
return jsonify({"success": False, "message": "Server error"}), 500
|
| 801 |
-
|
| 802 |
-
@app.route("/verify-email")
|
| 803 |
-
def verify_email():
|
| 804 |
-
"""Handle email verification"""
|
| 805 |
-
token = request.args.get('token')
|
| 806 |
-
if not token or token not in VERIFICATION_TOKENS:
|
| 807 |
-
return render_template("index.html", logged_in=False, is_signup=False,
|
| 808 |
-
verify_error="Invalid or expired verification token"), 400
|
| 809 |
-
|
| 810 |
-
token_data = VERIFICATION_TOKENS[token]
|
| 811 |
-
users = load_users()
|
| 812 |
-
username = token_data['username']
|
| 813 |
-
|
| 814 |
-
if username in users:
|
| 815 |
-
users[username]['verified'] = True
|
| 816 |
-
save_users(users)
|
| 817 |
-
del VERIFICATION_TOKENS[token]
|
| 818 |
-
return render_template("index.html", logged_in=False, is_signup=False,
|
| 819 |
-
verify_success=True)
|
| 820 |
-
|
| 821 |
-
return render_template("index.html", logged_in=False, is_signup=False,
|
| 822 |
-
verify_error="User not found"), 404
|
| 823 |
|
| 824 |
@app.route("/logout")
|
| 825 |
def logout():
|
| 826 |
-
# Clear both Firebase and legacy session data
|
| 827 |
-
session.pop('user_id', None)
|
| 828 |
-
session.pop('email', None)
|
| 829 |
session.pop('username', None)
|
| 830 |
-
return redirect(url_for('
|
| 831 |
|
| 832 |
@app.route("/submit_assessment", methods=["POST"])
|
| 833 |
def submit_assessment():
|
| 834 |
-
|
| 835 |
-
username = session.get('username')
|
| 836 |
-
|
| 837 |
-
if not user_id and not username:
|
| 838 |
return jsonify({"success": False, "message": "Not logged in"})
|
| 839 |
|
| 840 |
data = request.json
|
|
@@ -846,53 +324,28 @@ def submit_assessment():
|
|
| 846 |
# Calculate results
|
| 847 |
results = calculate_results(answers)
|
| 848 |
|
| 849 |
-
# Save to
|
| 850 |
-
|
| 851 |
-
|
| 852 |
-
|
| 853 |
-
|
| 854 |
-
|
| 855 |
-
|
| 856 |
-
'updated_at': firestore.SERVER_TIMESTAMP
|
| 857 |
-
})
|
| 858 |
return jsonify({"success": True, "results": results})
|
| 859 |
-
else:
|
| 860 |
-
# Legacy user - save to JSON
|
| 861 |
-
users = load_users()
|
| 862 |
-
if username in users:
|
| 863 |
-
users[username]['answers'] = answers
|
| 864 |
-
users[username]['results'] = results
|
| 865 |
-
save_users(users)
|
| 866 |
-
return jsonify({"success": True, "results": results})
|
| 867 |
|
| 868 |
return jsonify({"success": False, "message": "User not found"})
|
| 869 |
|
| 870 |
@app.route("/reset_assessment", methods=["POST"])
|
| 871 |
def reset_assessment():
|
| 872 |
-
|
| 873 |
-
username = session.get('username')
|
| 874 |
-
|
| 875 |
-
if not user_id and not username:
|
| 876 |
return jsonify({"success": False, "message": "Not logged in"})
|
| 877 |
|
| 878 |
-
|
| 879 |
-
if
|
| 880 |
-
|
| 881 |
-
|
| 882 |
-
|
| 883 |
-
'answers': [],
|
| 884 |
-
'results': [],
|
| 885 |
-
'updated_at': firestore.SERVER_TIMESTAMP
|
| 886 |
-
})
|
| 887 |
return jsonify({"success": True})
|
| 888 |
-
else:
|
| 889 |
-
# Legacy user - reset in JSON
|
| 890 |
-
users = load_users()
|
| 891 |
-
if username in users:
|
| 892 |
-
users[username]['answers'] = []
|
| 893 |
-
users[username]['results'] = []
|
| 894 |
-
save_users(users)
|
| 895 |
-
return jsonify({"success": True})
|
| 896 |
|
| 897 |
return jsonify({"success": False, "message": "User not found"})
|
| 898 |
|
|
@@ -902,7 +355,7 @@ def chat():
|
|
| 902 |
RAG-enhanced chat endpoint for spiritual guidance
|
| 903 |
Uses retrieval-augmented generation with religion-specific context
|
| 904 |
"""
|
| 905 |
-
if '
|
| 906 |
return jsonify({"success": False, "message": "Not logged in"})
|
| 907 |
|
| 908 |
if not client:
|
|
@@ -937,13 +390,13 @@ def chat():
|
|
| 937 |
if religion_key in RELIGIONS_CSV:
|
| 938 |
# Rich context from CSV using RAG utilities
|
| 939 |
csv_data = RELIGIONS_CSV[religion_key]
|
| 940 |
-
context_chunks = prepare_religion_rag_context(csv_data)
|
| 941 |
context = f"""REFERENCE DATA FOR {csv_data['name']}:
|
| 942 |
|
| 943 |
{context_chunks[0]}"""
|
| 944 |
else:
|
| 945 |
# Fallback to basic data
|
| 946 |
-
basic_context = prepare_religion_rag_context(religion_data)
|
| 947 |
context = f"""REFERENCE DATA FOR {religion_data['name']}:
|
| 948 |
|
| 949 |
{basic_context[0]}"""
|
|
@@ -974,7 +427,7 @@ INSTRUCTIONS:
|
|
| 974 |
response = client.chat.completions.create(
|
| 975 |
model="meta-llama/Meta-Llama-3-8B-Instruct-Lite",
|
| 976 |
messages=messages,
|
| 977 |
-
max_tokens=
|
| 978 |
temperature=0.7,
|
| 979 |
)
|
| 980 |
|
|
@@ -991,31 +444,6 @@ INSTRUCTIONS:
|
|
| 991 |
"message": f"Chat error: {str(e)}"
|
| 992 |
})
|
| 993 |
|
| 994 |
-
@app.route("/transcribe", methods=["POST"])
|
| 995 |
-
def transcribe():
|
| 996 |
-
"""Convert audio to text using Whisper"""
|
| 997 |
-
if 'username' not in session:
|
| 998 |
-
return jsonify({"success": False, "message": "Not logged in"})
|
| 999 |
-
|
| 1000 |
-
if not openai_client:
|
| 1001 |
-
return jsonify({"success": False, "message": "Whisper not configured"})
|
| 1002 |
-
|
| 1003 |
-
audio_file = request.files.get('audio')
|
| 1004 |
-
if not audio_file:
|
| 1005 |
-
return jsonify({"success": False, "message": "No audio file"})
|
| 1006 |
-
|
| 1007 |
-
try:
|
| 1008 |
-
# Convert FileStorage to bytes
|
| 1009 |
-
audio_bytes = audio_file.read()
|
| 1010 |
-
|
| 1011 |
-
transcript = openai_client.audio.transcriptions.create(
|
| 1012 |
-
model="whisper-1",
|
| 1013 |
-
file=("recording.webm", audio_bytes, "audio/webm")
|
| 1014 |
-
)
|
| 1015 |
-
return jsonify({"success": True, "text": transcript.text})
|
| 1016 |
-
except Exception as e:
|
| 1017 |
-
return jsonify({"success": False, "message": str(e)})
|
| 1018 |
-
|
| 1019 |
@app.route("/debug")
|
| 1020 |
def debug():
|
| 1021 |
"""
|
|
|
|
| 9 |
from werkzeug.security import generate_password_hash, check_password_hash
|
| 10 |
import json
|
| 11 |
import os
|
|
|
|
|
|
|
| 12 |
from dotenv import load_dotenv
|
| 13 |
from together import Together
|
| 14 |
from rag_utils import load_religions_from_csv, prepare_religion_rag_context
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
load_dotenv()
|
| 17 |
|
| 18 |
app = Flask(__name__)
|
| 19 |
+
app.secret_key = 'spiritual-journey-finder-2024'
|
| 20 |
|
| 21 |
# Session configuration for production deployment
|
| 22 |
+
app.config['SESSION_COOKIE_SECURE'] = False # For HTTP
|
| 23 |
app.config['SESSION_COOKIE_HTTPONLY'] = True
|
| 24 |
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'
|
| 25 |
app.config['PERMANENT_SESSION_LIFETIME'] = 3600 # 1 hour
|
| 26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
# File to store user data - defaults to current directory (writable in Docker)
|
|
|
|
| 28 |
USERS_FILE = os.getenv("USERS_FILE", "users_data.json")
|
| 29 |
|
| 30 |
# Together API for chatbot
|
| 31 |
TOGETHER_API_KEY = os.getenv("TOGETHER_API_KEY")
|
| 32 |
client = Together(api_key=TOGETHER_API_KEY) if TOGETHER_API_KEY else None
|
| 33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
# Load detailed religion data at startup
|
| 35 |
RELIGIONS_CSV = load_religions_from_csv('religions.csv')
|
| 36 |
|
| 37 |
+
# Assessment Questions
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
QUESTIONS = [
|
| 39 |
{
|
| 40 |
"id": 1,
|
| 41 |
"question": "What is your view on the nature of the divine?",
|
| 42 |
"options": {
|
| 43 |
+
"One supreme God who created everything": {"christianity": 3, "islam": 3, "judaism": 3},
|
| 44 |
+
"Multiple gods and goddesses": {"hinduism": 3, "paganism": 3},
|
| 45 |
+
"A universal energy or force": {"buddhism": 2, "taoism": 3, "new_age": 3},
|
| 46 |
+
"No divine being, focus on human potential": {"humanism": 3, "atheism": 3},
|
| 47 |
+
"Uncertain or unknowable": {"agnosticism": 3}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
}
|
| 49 |
},
|
| 50 |
{
|
| 51 |
"id": 2,
|
| 52 |
"question": "How do you prefer to connect with spirituality?",
|
| 53 |
"options": {
|
| 54 |
+
"Through organized worship and community": {"christianity": 2, "islam": 2, "judaism": 2},
|
| 55 |
+
"Through personal meditation and reflection": {"buddhism": 3, "hinduism": 2, "taoism": 2},
|
| 56 |
+
"Through nature and natural cycles": {"paganism": 3, "indigenous": 3},
|
| 57 |
+
"Through reason and philosophy": {"humanism": 2, "stoicism": 3},
|
| 58 |
+
"I don't feel the need for spiritual connection": {"atheism": 3}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
}
|
| 60 |
},
|
| 61 |
{
|
| 62 |
"id": 3,
|
| 63 |
"question": "What is your belief about the afterlife?",
|
| 64 |
"options": {
|
| 65 |
+
"Heaven or Hell based on faith/deeds": {"christianity": 3, "islam": 3},
|
| 66 |
+
"Reincarnation until enlightenment": {"hinduism": 3, "buddhism": 3},
|
| 67 |
+
"Ancestral realm or spiritual world": {"indigenous": 2, "paganism": 2},
|
| 68 |
+
"No afterlife, this life is all there is": {"atheism": 3, "humanism": 2},
|
| 69 |
+
"Unsure or open to possibilities": {"agnosticism": 2, "new_age": 2}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
}
|
| 71 |
},
|
| 72 |
{
|
| 73 |
"id": 4,
|
| 74 |
"question": "What guides your moral and ethical decisions?",
|
| 75 |
"options": {
|
| 76 |
+
"Sacred texts and religious teachings": {"christianity": 3, "islam": 3, "judaism": 3},
|
| 77 |
+
"Universal principles of compassion and mindfulness": {"buddhism": 3, "jainism": 3},
|
| 78 |
+
"Harmony with nature and balance": {"taoism": 3, "indigenous": 2},
|
| 79 |
+
"Reason, empathy, and human rights": {"humanism": 3, "secularism": 3},
|
| 80 |
+
"Personal intuition and inner wisdom": {"new_age": 2, "spiritualism": 3}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
}
|
| 82 |
},
|
| 83 |
{
|
| 84 |
"id": 5,
|
| 85 |
+
"question": "What role does ritual or practice play in your life?",
|
| 86 |
"options": {
|
| 87 |
+
"Regular prayer and worship are essential": {"islam": 3, "christianity": 2, "judaism": 2},
|
| 88 |
+
"Daily meditation or mindfulness practice": {"buddhism": 3, "hinduism": 2, "zen": 3},
|
| 89 |
+
"Seasonal celebrations and ceremonies": {"paganism": 3, "wicca": 3},
|
| 90 |
+
"Minimal to no ritual, prefer intellectual engagement": {"humanism": 2, "deism": 2},
|
| 91 |
+
"Flexible, whatever feels meaningful to me": {"new_age": 2, "spiritual_not_religious": 3}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
}
|
| 93 |
},
|
| 94 |
{
|
| 95 |
"id": 6,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
"question": "How do you view the relationship between humans and nature?",
|
| 97 |
"options": {
|
| 98 |
+
"Humans are stewards of God's creation": {"christianity": 2, "islam": 2, "judaism": 2},
|
| 99 |
+
"All life is interconnected and sacred": {"buddhism": 2, "hinduism": 2, "jainism": 3},
|
| 100 |
+
"Nature itself is divine": {"paganism": 3, "pantheism": 3, "indigenous": 3},
|
| 101 |
+
"Nature follows natural laws we can understand": {"atheism": 2, "humanism": 2},
|
| 102 |
+
"We should live in harmony with natural flow": {"taoism": 3, "shintoism": 2}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
}
|
| 104 |
},
|
| 105 |
{
|
| 106 |
+
"id": 7,
|
| 107 |
"question": "What is your view on suffering and its purpose?",
|
| 108 |
"options": {
|
| 109 |
+
"A test of faith or part of God's plan": {"christianity": 2, "islam": 2},
|
| 110 |
+
"Result of attachment and desire": {"buddhism": 3, "stoicism": 2},
|
| 111 |
+
"Karma from past actions": {"hinduism": 3, "sikhism": 2},
|
| 112 |
+
"Random or result of natural causes": {"atheism": 3, "secular": 2},
|
| 113 |
+
"An opportunity for growth and learning": {"new_age": 2, "spiritualism": 2}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
}
|
| 115 |
},
|
| 116 |
{
|
| 117 |
+
"id": 8,
|
| 118 |
"question": "How important is community in your spiritual life?",
|
| 119 |
"options": {
|
| 120 |
+
"Very important, prefer group worship": {"christianity": 2, "islam": 2, "sikhism": 3},
|
| 121 |
+
"Somewhat important, but personal practice matters more": {"buddhism": 2, "hinduism": 2},
|
| 122 |
+
"Community of like-minded seekers": {"paganism": 2, "unitarian": 3},
|
| 123 |
+
"Not important, spirituality is personal": {"spiritual_not_religious": 3, "deism": 2},
|
| 124 |
+
"Prefer secular community over religious": {"humanism": 2, "atheism": 2}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
}
|
| 126 |
}
|
| 127 |
]
|
|
|
|
| 141 |
"new_age": {"name": "New Age Spirituality", "description": "Eclectic approach emphasizing personal growth.", "practices": "Meditation, energy work, crystals, yoga", "core_beliefs": "Personal transformation, universal consciousness"},
|
| 142 |
"spiritual_not_religious": {"name": "Spiritual But Not Religious", "description": "Personal spirituality without organized religion.", "practices": "Personal practices, meditation, self-reflection", "core_beliefs": "Individual journey, authenticity, diverse wisdom"},
|
| 143 |
"sikhism": {"name": "Sikhism", "description": "One God emphasizing service, equality, and meditation.", "practices": "Prayer, meditation, community service, 5 Ks", "core_beliefs": "One God, equality, honest living, sharing"},
|
| 144 |
+
"indigenous": {"name": "Indigenous Spirituality", "description": "Traditional practices honoring ancestors and land.", "practices": "Ceremonies, storytelling, seasonal rituals", "core_beliefs": "Land connection, ancestor veneration, reciprocity"}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
}
|
| 146 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
def load_users():
|
| 148 |
+
"""Load users from JSON file"""
|
| 149 |
try:
|
| 150 |
if os.path.exists(USERS_FILE):
|
| 151 |
with open(USERS_FILE, 'r') as f:
|
|
|
|
| 172 |
if not users: # Only create if no users exist
|
| 173 |
users['test'] = {
|
| 174 |
'password': generate_password_hash('test'),
|
|
|
|
|
|
|
| 175 |
'answers': [],
|
| 176 |
'results': []
|
| 177 |
}
|
|
|
|
| 179 |
print("β
Default test user created (username: test, password: test)")
|
| 180 |
|
| 181 |
def calculate_results(answers):
|
| 182 |
+
"""Calculate which spiritual paths align with user's answers"""
|
|
|
|
|
|
|
|
|
|
| 183 |
scores = {}
|
|
|
|
| 184 |
|
|
|
|
| 185 |
for answer in answers:
|
| 186 |
question = next((q for q in QUESTIONS if q["id"] == answer["question_id"]), None)
|
| 187 |
if question and answer["answer"] in question["options"]:
|
| 188 |
+
points = question["options"][answer["answer"]]
|
| 189 |
+
for religion, score in points.items():
|
| 190 |
+
scores[religion] = scores.get(religion, 0) + score
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
|
| 192 |
+
# Sort by score
|
| 193 |
+
sorted_scores = sorted(scores.items(), key=lambda x: x[1], reverse=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 194 |
|
| 195 |
+
# Get top 3 recommendations
|
| 196 |
recommendations = []
|
| 197 |
+
for religion_key, score in sorted_scores[:3]:
|
| 198 |
+
if religion_key in RELIGIONS:
|
| 199 |
+
religion_info = RELIGIONS[religion_key].copy()
|
| 200 |
+
religion_info["score"] = score
|
| 201 |
+
religion_info["percentage"] = round((score / (len(answers) * 3)) * 100)
|
| 202 |
+
recommendations.append(religion_info)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
|
| 204 |
return recommendations
|
| 205 |
|
|
|
|
| 209 |
|
| 210 |
@app.route("/assessment")
|
| 211 |
def assessment():
|
| 212 |
+
if 'username' not in session:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
return redirect(url_for('login'))
|
| 214 |
|
| 215 |
+
users = load_users()
|
| 216 |
+
user_data = users.get(session['username'], {})
|
| 217 |
+
has_results = 'results' in user_data and user_data['results']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 218 |
|
| 219 |
return render_template(
|
| 220 |
"index.html",
|
| 221 |
title="Spiritual Path Finder",
|
| 222 |
+
message=f"Welcome, {session['username']}! π",
|
| 223 |
+
username=session['username'],
|
| 224 |
logged_in=True,
|
| 225 |
questions=QUESTIONS,
|
| 226 |
has_results=has_results,
|
| 227 |
+
results=user_data.get('results', []) if has_results else []
|
|
|
|
| 228 |
)
|
| 229 |
|
| 230 |
@app.route("/login", methods=["GET", "POST"])
|
|
|
|
| 234 |
data = request.get_json()
|
| 235 |
if not data:
|
| 236 |
return jsonify({"success": False, "message": "Invalid request"}), 400
|
| 237 |
+
|
| 238 |
+
username = data.get('username', '').strip()
|
| 239 |
+
password = data.get('password', '')
|
| 240 |
|
| 241 |
+
if not username or not password:
|
| 242 |
+
return jsonify({"success": False, "message": "Username and password required"}), 400
|
| 243 |
|
| 244 |
+
users = load_users()
|
| 245 |
+
if username in users:
|
| 246 |
+
stored = users[username]['password']
|
| 247 |
+
|
| 248 |
+
# 1) Try hash-based verification (works for any Werkzeug scheme)
|
| 249 |
+
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 250 |
if check_password_hash(stored, password):
|
| 251 |
session['username'] = username
|
|
|
|
| 252 |
return jsonify({"success": True})
|
| 253 |
+
except Exception:
|
| 254 |
+
pass # if stored isn't a hash string, we'll try plaintext next
|
| 255 |
+
|
| 256 |
+
# 2) Legacy plaintext fallback β upgrade to a hash
|
| 257 |
+
if stored == password:
|
| 258 |
users[username]['password'] = generate_password_hash(password)
|
| 259 |
if not save_users(users):
|
| 260 |
return jsonify({"success": False, "message": "Error saving data"}), 500
|
| 261 |
session['username'] = username
|
|
|
|
| 262 |
return jsonify({"success": True})
|
| 263 |
+
|
| 264 |
+
return jsonify({"success": False, "message": "Invalid credentials"})
|
| 265 |
except Exception as e:
|
| 266 |
print(f"Login error: {e}")
|
| 267 |
return jsonify({"success": False, "message": "Server error"}), 500
|
| 268 |
|
| 269 |
+
return render_template("index.html", logged_in=False, is_signup=False)
|
|
|
|
| 270 |
|
| 271 |
@app.route("/signup", methods=["GET", "POST"])
|
| 272 |
def signup():
|
|
|
|
| 275 |
data = request.get_json()
|
| 276 |
if not data:
|
| 277 |
return jsonify({"success": False, "message": "Invalid request"}), 400
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 278 |
|
| 279 |
+
username = data.get('username', '').strip()
|
| 280 |
+
password = data.get('password', '')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 281 |
|
| 282 |
+
if not username or not password:
|
| 283 |
+
return jsonify({"success": False, "message": "Username and password required"}), 400
|
|
|
|
|
|
|
|
|
|
| 284 |
|
| 285 |
users = load_users()
|
| 286 |
|
| 287 |
+
if username in users:
|
| 288 |
+
return jsonify({"success": False, "message": "Username already exists"})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 289 |
|
| 290 |
+
# Create new user with hashed password
|
| 291 |
+
users[username] = {
|
| 292 |
+
'password': generate_password_hash(password),
|
| 293 |
+
'answers': [],
|
| 294 |
+
'results': []
|
|
|
|
|
|
|
| 295 |
}
|
| 296 |
|
| 297 |
+
if not save_users(users):
|
| 298 |
+
return jsonify({"success": False, "message": "Error saving user data"}), 500
|
| 299 |
+
|
| 300 |
+
session['username'] = username
|
| 301 |
+
return jsonify({"success": True})
|
|
|
|
|
|
|
| 302 |
except Exception as e:
|
| 303 |
+
print(f"Signup error: {e}")
|
| 304 |
return jsonify({"success": False, "message": "Server error"}), 500
|
| 305 |
|
| 306 |
+
return render_template("index.html", logged_in=False, is_signup=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 307 |
|
| 308 |
@app.route("/logout")
|
| 309 |
def logout():
|
|
|
|
|
|
|
|
|
|
| 310 |
session.pop('username', None)
|
| 311 |
+
return redirect(url_for('login'))
|
| 312 |
|
| 313 |
@app.route("/submit_assessment", methods=["POST"])
|
| 314 |
def submit_assessment():
|
| 315 |
+
if 'username' not in session:
|
|
|
|
|
|
|
|
|
|
| 316 |
return jsonify({"success": False, "message": "Not logged in"})
|
| 317 |
|
| 318 |
data = request.json
|
|
|
|
| 324 |
# Calculate results
|
| 325 |
results = calculate_results(answers)
|
| 326 |
|
| 327 |
+
# Save to user data
|
| 328 |
+
users = load_users()
|
| 329 |
+
if session['username'] in users:
|
| 330 |
+
users[session['username']]['answers'] = answers
|
| 331 |
+
users[session['username']]['results'] = results
|
| 332 |
+
save_users(users)
|
| 333 |
+
|
|
|
|
|
|
|
| 334 |
return jsonify({"success": True, "results": results})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 335 |
|
| 336 |
return jsonify({"success": False, "message": "User not found"})
|
| 337 |
|
| 338 |
@app.route("/reset_assessment", methods=["POST"])
|
| 339 |
def reset_assessment():
|
| 340 |
+
if 'username' not in session:
|
|
|
|
|
|
|
|
|
|
| 341 |
return jsonify({"success": False, "message": "Not logged in"})
|
| 342 |
|
| 343 |
+
users = load_users()
|
| 344 |
+
if session['username'] in users:
|
| 345 |
+
users[session['username']]['answers'] = []
|
| 346 |
+
users[session['username']]['results'] = []
|
| 347 |
+
save_users(users)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 348 |
return jsonify({"success": True})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 349 |
|
| 350 |
return jsonify({"success": False, "message": "User not found"})
|
| 351 |
|
|
|
|
| 355 |
RAG-enhanced chat endpoint for spiritual guidance
|
| 356 |
Uses retrieval-augmented generation with religion-specific context
|
| 357 |
"""
|
| 358 |
+
if 'username' not in session:
|
| 359 |
return jsonify({"success": False, "message": "Not logged in"})
|
| 360 |
|
| 361 |
if not client:
|
|
|
|
| 390 |
if religion_key in RELIGIONS_CSV:
|
| 391 |
# Rich context from CSV using RAG utilities
|
| 392 |
csv_data = RELIGIONS_CSV[religion_key]
|
| 393 |
+
context_chunks = prepare_religion_rag_context(csv_data, use_chunks=False)
|
| 394 |
context = f"""REFERENCE DATA FOR {csv_data['name']}:
|
| 395 |
|
| 396 |
{context_chunks[0]}"""
|
| 397 |
else:
|
| 398 |
# Fallback to basic data
|
| 399 |
+
basic_context = prepare_religion_rag_context(religion_data, use_chunks=False)
|
| 400 |
context = f"""REFERENCE DATA FOR {religion_data['name']}:
|
| 401 |
|
| 402 |
{basic_context[0]}"""
|
|
|
|
| 427 |
response = client.chat.completions.create(
|
| 428 |
model="meta-llama/Meta-Llama-3-8B-Instruct-Lite",
|
| 429 |
messages=messages,
|
| 430 |
+
max_tokens=200,
|
| 431 |
temperature=0.7,
|
| 432 |
)
|
| 433 |
|
|
|
|
| 444 |
"message": f"Chat error: {str(e)}"
|
| 445 |
})
|
| 446 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 447 |
@app.route("/debug")
|
| 448 |
def debug():
|
| 449 |
"""
|
chunks.json
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
"============================================================\nReligion: Christianity\n============================================================\n\nDescription: Christianity is a major monotheistic religion originating from the life, teachings, and death of Jesus of Nazareth in the 1st century CE.",
|
| 3 |
+
"death of Jesus of Nazareth in the 1st century CE. It is the world's largest religion with over two billion adherents, emphasizing faith in Jesus Christ as the Son of God who offers salvation through his death and resurrection.",
|
| 4 |
+
"fers salvation through his death and resurrection. The religion has profoundly influenced global culture, ethics, and institutions, evolving through historical interactions with diverse civilizations and adapting to various contexts while maintaining a focus on redemption and community.",
|
| 5 |
+
"maintaining a focus on redemption and community.\n\nPractices: Key practices include prayer (personal and communal communication with God), Bible study (reading and interpreting sacred scriptures), attending church services (worship, preaching, and fellowship), and sacraments such as communion (commem",
|
| 6 |
+
"lowship), and sacraments such as communion (commemorating Jesus' Last Supper) and baptism (symbolizing spiritual rebirth). Other observances involve fasting, charity, mission work, and celebrating holidays like Christmas (Jesus' birth) and Easter (resurrection).",
|
| 7 |
+
"hristmas (Jesus' birth) and Easter (resurrection). Practices vary by denomination, from liturgical rituals in Catholicism to charismatic worship in Pentecostalism.",
|
| 8 |
+
"licism to charismatic worship in Pentecostalism.\n\nCore Beliefs: Central beliefs include the Trinity (one God in three persons: Father, Son, Holy Spirit), salvation through faith in Jesus Christ (who atoned for humanity's sins), the resurrection and eternal life, original sin (humanity's fallen state",
|
| 9 |
+
"ternal life, original sin (humanity's fallen state), and the authority of the Bible. Additional doctrines encompass grace (God's unmerited favor), the church as the body of believers, eschatology (end times and judgment), and ethical living based on love, forgiveness, and justice.",
|
| 10 |
+
"al living based on love, forgiveness, and justice. Monotheism is foundational, rejecting polytheism and atheism.\n\nCommon Questions: Common questions include: Why does God allow evil and suffering? Is faith irrational or opposed to science? Why is Jesus the only way to heaven? Can one lose salvation?",
|
| 11 |
+
"us the only way to heaven? Can one lose salvation? Why are there hypocrites in Christianity? How to take the Bible literally? How should Christians respond to issues like LGBTQ+ rights, racism, and injustice? Interesting facts: Christianity emerged from Judaism; not all ministers wear special attire",
|
| 12 |
+
"rom Judaism; not all ministers wear special attire; churches are communities, not just buildings; over 2 billion followers worldwide; the Bible has no contradictions claimed by believers but debated by skeptics.\n\n\n\n============================================================\nReligion: Islam",
|
| 13 |
+
"=================================\nReligion: Islam\n============================================================\n\nDescription: Islam is a monotheistic religion founded in 7th-century Arabia by the Prophet Muhammad, emphasizing submission to the will of Allah (God) as revealed in the Quran.",
|
| 14 |
+
"the will of Allah (God) as revealed in the Quran. With over 1.5 billion adherents worldwide, it integrates spiritual devotion with social, legal, and ethical guidelines, fostering a sense of global community (ummah) and influencing diverse cultures through conquests, trade, and mysticism.",
|
| 15 |
+
"cultures through conquests, trade, and mysticism. It promotes justice, compassion, and personal accountability in both individual and communal life.\n\nPractices: Core practices, known as the Five Pillars, include Shahada (profession of faith), Salat (five daily prayers), Zakat (charity to the needy)",
|
| 16 |
+
"(five daily prayers), Zakat (charity to the needy), Sawm (fasting during Ramadan), and Hajj (pilgrimage to Mecca). Additional observances involve Halal dietary laws, ethical business conduct, community service, and Sufi mysticism (meditation, dhikr remembrance of God).",
|
| 17 |
+
"mysticism (meditation, dhikr remembrance of God). Practices emphasize discipline, social equity, and spiritual purification, varying between Sunni and Shia traditions.",
|
| 18 |
+
"tion, varying between Sunni and Shia traditions.\n\nCore Beliefs: Fundamental beliefs are Tawhid (oneness of Allah), prophethood (Muhammad as the final prophet completing revelations from Adam to Jesus), angels, holy books (Quran as ultimate scripture), Day of Judgment (accountability for deeds), and",
|
| 19 |
+
", Day of Judgment (accountability for deeds), and predestination (Allah's will). Sources include Quran, Sunnah (Prophet's traditions), Ijma (consensus), and Ijtihad (reasoned interpretation).",
|
| 20 |
+
"consensus), and Ijtihad (reasoned interpretation). Ethics stress justice, mercy, and community, with variations in Sunni (Hadith-focused) and Shia (Imam-guided) interpretations.",
|
| 21 |
+
"focused) and Shia (Imam-guided) interpretations.\n\nCommon Questions: Common questions: Why is Islam perceived as violent? What are the Five Pillars? Who was Muhammad? Do Muslims believe in Jesus? What is the difference between Sunni and Shia? Why do Muslims fast during Ramadan? What is Jihad? Interes",
|
| 22 |
+
"uslims fast during Ramadan? What is Jihad? Interesting facts: Islam recognizes previous prophets like Abraham and Jesus; the Quran contains scientific facts ahead of its time; Muslims believe in one God without partners; major festivals include Eid al-Fitr and Eid al-Adha; over 1.",
|
| 23 |
+
"ivals include Eid al-Fitr and Eid al-Adha; over 1.8 billion followers worldwide; emphasizes charity and community.\n\n\n\n============================================================\nReligion: Buddhism\n============================================================",
|
| 24 |
+
"================================================\n\nDescription: Buddhism is a philosophy and religion founded by Siddhartha Gautama (the Buddha) in northeastern India between the 6th and 4th centuries BCE, focusing on overcoming suffering through enlightenment.",
|
| 25 |
+
"ing on overcoming suffering through enlightenment. With global influence in Asia and beyond, it emphasizes ethical living, meditation, and wisdom, adapting to diverse cultures while promoting compassion and mindfulness as paths to nirvana (liberation from rebirth).",
|
| 26 |
+
"s as paths to nirvana (liberation from rebirth).\n\nPractices: Core practices include meditation (vipassana for insight, samatha for calm), mindfulness (awareness in daily life), following the Eightfold Path (right view, intention, speech, action, livelihood, effort, mindfulness, concentration), and o",
|
| 27 |
+
"lihood, effort, mindfulness, concentration), and observing precepts (ethical guidelines like non-violence). Rituals vary: Theravada focuses on monastic discipline, Mahayana on bodhisattva vows and chants, Vajrayana on tantric rituals and mantras.",
|
| 28 |
+
"chants, Vajrayana on tantric rituals and mantras. Lay practices involve offerings, festivals, and pilgrimage.\n\nCore Beliefs: Key beliefs are the Four Noble Truths (suffering, its cause in desire, cessation through detachment, path to end it), Three Jewels (Buddha, Dharma teachings, Sangha community",
|
| 29 |
+
"Jewels (Buddha, Dharma teachings, Sangha community), karma (actions' consequences), samsara (cycle of rebirth), nirvana (enlightenment), and impermanence (anicca).",
|
| 30 |
+
"irvana (enlightenment), and impermanence (anicca). Variations: Theravada emphasizes individual liberation, Mahayana universal salvation via bodhisattvas, Vajrayana rapid enlightenment through esoteric methods. Rejects a creator god, focusing on self-reliance.",
|
| 31 |
+
"ejects a creator god, focusing on self-reliance.\n\nCommon Questions: Common questions: Who was the Buddha? Is Buddhism a religion or philosophy? Do Buddhists believe in God? What is karma and reincarnation? How does one achieve enlightenment? Why is suffering central? Interesting facts: Originated 2,",
|
| 32 |
+
"uffering central? Interesting facts: Originated 2,500 years ago in India; about 535 million followers; no creator god; focuses on ending suffering; diverse schools like Theravada, Mahayana; mindfulness practices influence modern psychology; Buddha means 'awakened one'; no single holy book but many s",
|
| 33 |
+
"ans 'awakened one'; no single holy book but many scriptures.\n\n\n\n============================================================\nReligion: Hinduism\n============================================================",
|
| 34 |
+
"================================================\n\nDescription: Hinduism is an ancient, diverse tradition originating in the Indian subcontinent around the 2nd millennium BCE, encompassing varied philosophies, rituals, and beliefs aimed at spiritual realization.",
|
| 35 |
+
"tuals, and beliefs aimed at spiritual realization. As the world's oldest living religion with nearly one billion adherents, it adapts regionally and emphasizes dharma (duty), karma (actions' effects), and moksha (liberation), influencing art, ethics, and society globally through texts and practices.",
|
| 36 |
+
"and society globally through texts and practices.\n\nPractices: Practices include yoga (physical and meditative disciplines), meditation (for inner peace), puja (worship with offerings), festivals (Diwali, Holi), pilgrimage (to sacred sites like Varanasi), and rites of passage (samskaras like marriag",
|
| 37 |
+
"asi), and rites of passage (samskaras like marriage). Daily routines involve mantra chanting, vegetarianism for some, and community service. Variations span devotional bhakti, philosophical jnana, and action-oriented karma paths.",
|
| 38 |
+
"sophical jnana, and action-oriented karma paths.\n\nCore Beliefs: Core beliefs include dharma (cosmic order and duty), karma (cause and effect across lives), samsara (rebirth cycle), moksha (liberation), and Brahman (ultimate reality). Deities represent aspects of the divine (e.g.",
|
| 39 |
+
"ty). Deities represent aspects of the divine (e.g., Vishnu, Shiva, Devi), with paths like bhakti (devotion), jnana (knowledge), and yoga. Scriptures: Vedas, Upanishads, epics like Ramayana. Emphasizes pluralism, with regional variations in worship and philosophy.",
|
| 40 |
+
"h regional variations in worship and philosophy.\n\nCommon Questions: Common questions: Why so many gods? Do Hindus believe in reincarnation? What is karma? Why worship cows? Is Hinduism a religion or way of life? Interesting facts: Oldest religion, over 1.",
|
| 41 |
+
"life? Interesting facts: Oldest religion, over 1.1 billion followers mostly in India; no single founder; diverse schools of philosophy; Vedas are ancient scriptures; emphasizes ahimsa (non-violence); multiple paths to truth; polytheistic yet monistic; festivals like Diwali celebrate light over dark",
|
| 42 |
+
"c; festivals like Diwali celebrate light over darkness.\n\n\n\n============================================================\nReligion: Judaism\n============================================================",
|
| 43 |
+
"================================================\n\nDescription: Judaism is a monotheistic religion developed among ancient Hebrews, centered on a covenant with God revealed through prophets like Abraham and Moses.",
|
| 44 |
+
"revealed through prophets like Abraham and Moses. With about 14 million adherents, it integrates theology, law, and culture, emphasizing ethical living and community while adapting through history, influencing Western civilization profoundly.",
|
| 45 |
+
"ry, influencing Western civilization profoundly.\n\nPractices: Practices include Shabbat observance (weekly rest and prayer), Torah study (scriptural learning), daily prayer (three times), kosher dietary laws, and life-cycle events (bar/bat mitzvah, circumcision).",
|
| 46 |
+
"life-cycle events (bar/bat mitzvah, circumcision). Holidays: Passover, Rosh Hashanah, Yom Kippur. Community involvement via synagogue services and charity (tzedakah). Variations in Orthodox (strict), Conservative (balanced), Reform (modern).",
|
| 47 |
+
"rict), Conservative (balanced), Reform (modern).\n\nCore Beliefs: Beliefs include one transcendent God, Torah as divine law, covenant with Israel, ethical monotheism, messianic hope, resurrection, and free will. Prophets guide moral response; history reveals God's purpose.",
|
| 48 |
+
"ide moral response; history reveals God's purpose. Emphasizes justice, peace, and human responsibility. Denominations differ in interpretation but share core ethical-historical monotheism.",
|
| 49 |
+
"on but share core ethical-historical monotheism.\n\nCommon Questions: Common questions: Why write G-d? What is the Wailing Wall? Is Judaism a religion or ethnicity? Why kosher laws? What are the branches (Orthodox, Reform)? Interesting facts: Based on Torah; one God; 613 mitzvot; emerged 4,000 years a",
|
| 50 |
+
"Torah; one God; 613 mitzvot; emerged 4,000 years ago; Jews, Israelites, Hebrews same; no proselytizing; emphasis on deeds over beliefs; guardian angels in tradition; diverse customs like not climbing trees on Shabbat.\n\n\n\n============================================================\nReligion: Taoism",
|
| 51 |
+
"================================\nReligion: Taoism\n============================================================\n\nDescription: Taoism (Daoism) is an indigenous Chinese tradition over 2,000 years old, emphasizing harmony with the Tao (the Way), a fundamental force underlying reality.",
|
| 52 |
+
"(the Way), a fundamental force underlying reality. It balances yielding, joyful attitudes with metaphysical exploration, influencing Asian cultures through philosophy, religion, and folk practices.",
|
| 53 |
+
"hrough philosophy, religion, and folk practices.\n\nPractices: Practices include meditation (for inner harmony), tai chi (movement for energy flow), wu wei (effortless action), simplicity in living, and rituals like Tao worship or alchemy.",
|
| 54 |
+
"n living, and rituals like Tao worship or alchemy. Religious aspects involve priestly ceremonies; philosophical focus on contemplation. Blends with Confucianism and Buddhism in folk traditions.",
|
| 55 |
+
"th Confucianism and Buddhism in folk traditions.\n\nCore Beliefs: Core beliefs: Tao as the natural order, yin-yang balance (complementary forces), harmony with nature, metaphysical engagement. Texts: Tao Te Ching, Zhuangzi. Variations: philosophical (mystical ideas) vs. religious (ritual worship).",
|
| 56 |
+
"l (mystical ideas) vs. religious (ritual worship). Rejects ego-dissolution, affirms reality's nature.\n\nCommon Questions: Common questions: What is the Tao? Who was Lao Tzu? Is Taoism a religion or philosophy? What is wu wei? How to apply Taoism daily? Interesting facts: Over 2,000 years old; influen",
|
| 57 |
+
"? Interesting facts: Over 2,000 years old; influences Chinese medicine; yin-yang symbol; no absolutes; monasteries called Gong and Guan; ethics based on charity, thrift; Tao indefinable; self-cultivation goal.\n\n\n\n============================================================\nReligion: Modern Paganism",
|
| 58 |
+
"=======================\nReligion: Modern Paganism\n============================================================\n\nDescription: Modern Paganism (Neopaganism) is a contemporary revival of pre-Christian, nature-based spiritualities, emerging in the 20th century amid environmental and feminist movements.",
|
| 59 |
+
"century amid environmental and feminist movements. It honors ancient traditions while adapting to modern contexts, emphasizing sacredness in nature and personal empowerment, with diverse, decentralized communities worldwide.",
|
| 60 |
+
"th diverse, decentralized communities worldwide.\n\nPractices: Practices include seasonal celebrations (solstices, equinoxes), rituals (circle casting, offerings), nature work (environmental activism, herbalism), divination (tarot, runes), and meditation.",
|
| 61 |
+
"alism), divination (tarot, runes), and meditation. Group covens or solitary paths; festivals like Beltane. Eclectic, drawing from Celtic, Norse, or Wiccan traditions.",
|
| 62 |
+
"rawing from Celtic, Norse, or Wiccan traditions.\n\nCore Beliefs: Beliefs: Nature as sacred, polytheism or pantheism (multiple deities or divine in all), cycles of life/death/rebirth, personal responsibility, magic as natural force. Rejects dogma; emphasizes harmony, diversity, and ethical living.",
|
| 63 |
+
"emphasizes harmony, diversity, and ethical living. Variations: Wicca (witchcraft-focused), Druidry (Celtic-inspired), Heathenry (Norse).\n\nCommon Questions: Common questions: What is Paganism? Is it witchcraft? Do Pagans worship Satan? How does it differ from ancient paganism? Interesting facts: Umbr",
|
| 64 |
+
"fer from ancient paganism? Interesting facts: Umbrella term for non-mainstream religions; revival, not continuous; includes Wicca, Druidry; nature-centric; no central authority; eclectic practices; influenced by 19th-20th century movements; celebrates Wheel of the Year; rejects dogma; modern inventi",
|
| 65 |
+
"s Wheel of the Year; rejects dogma; modern invention with ancient inspirations.\n\n\n\n============================================================\nReligion: Secular Humanism\n============================================================",
|
| 66 |
+
"================================================\n\nDescription: Secular Humanism is a modern ethical philosophy emphasizing human reason, values, and dignity without supernatural beliefs, rooted in Renaissance humanism but distinct in its non-theistic focus.",
|
| 67 |
+
"e humanism but distinct in its non-theistic focus. It promotes rational inquiry, science, and social justice as paths to fulfillment and societal improvement.",
|
| 68 |
+
"s paths to fulfillment and societal improvement.\n\nPractices: Practices include critical thinking (evidence-based decision-making), ethical living (compassion, justice), community service (volunteering, activism), and secular ceremonies (humanist weddings, namings).",
|
| 69 |
+
"d secular ceremonies (humanist weddings, namings). Education and dialogue foster personal growth; no rituals, but celebrations of life milestones.\n\nCore Beliefs: Beliefs: Human dignity and potential, reason and science as guides, secular ethics (morality from empathy, not divine command), rejection",
|
| 70 |
+
"lity from empathy, not divine command), rejection of supernaturalism. Anthropocentric focus on this life; variations like pragmatic or Christian humanism, but secular emphasizes autonomy and progress.",
|
| 71 |
+
"m, but secular emphasizes autonomy and progress.\n\nCommon Questions: Common questions: Is humanism a religion? What is secularism? Why focus on reason? Can humanists have morals without God? Interesting facts: Man-centered ethics; no supernatural; based on naturalism; promotes science; history from R",
|
| 72 |
+
"ed on naturalism; promotes science; history from Renaissance; emphasizes human agency; not anti-religion but non-theistic; goal is self-remediation; positive worldview.\n\n\n\n============================================================\nReligion: Atheism",
|
| 73 |
+
"===============================\nReligion: Atheism\n============================================================\n\nDescription: Atheism is the absence of belief in gods or spiritual beings, emphasizing empirical evidence and rational critique of metaphysical claims.",
|
| 74 |
+
"ence and rational critique of metaphysical claims. It promotes a naturalistic worldview focused on human experience and ethics, often in opposition to religious doctrines, with historical roots in philosophy and science.",
|
| 75 |
+
"with historical roots in philosophy and science.\n\nPractices: Practices involve evidence-based thinking (scientific inquiry, skepticism), secular community (atheist groups, discussions), and ethical activism (human rights, separation of church/state).",
|
| 76 |
+
"tivism (human rights, separation of church/state). No rituals; focus on rational discourse, education, and living meaningfully without faith.\n\nCore Beliefs: Beliefs: No gods exist (or low probability), natural explanations for phenomena, focus on this life.",
|
| 77 |
+
"al explanations for phenomena, focus on this life. Rejects spiritual beings; variations: fallibilistic (open to evidence), incoherence-based (God concepts illogical). Emphasizes burden of proof on theists, empirical reliability.",
|
| 78 |
+
"rden of proof on theists, empirical reliability.\n\nCommon Questions: Common questions: Why no God? Where does morality come from? Do atheists have faith? What about afterlife? Why be moral? Interesting facts: Not a religion, lack of belief; mostly men and young in U.S.",
|
| 79 |
+
"gion, lack of belief; mostly men and young in U.S.; 98% say religion unimportant; doubled in popularity; face discrimination; symbol is atomic whirl; no founder; can pray (meditate); smarter on average per some studies.\n\n\n\n============================================================",
|
| 80 |
+
"=================================================\nReligion: Agnosticism\n============================================================\n\nDescription: Agnosticism holds that the existence of gods or ultimate realities is unknowable, prioritizing evidence and reason while suspending judgment on metaphysi",
|
| 81 |
+
"and reason while suspending judgment on metaphysical claims. Coined by T.H. Huxley in 1869, it fosters intellectual humility amid scientific and philosophical debates.",
|
| 82 |
+
"ility amid scientific and philosophical debates.\n\nPractices: Practices include rigorous inquiry (following evidence, Clifford's ethics against insufficient belief), critical reflection (questioning claims), and openness to data.",
|
| 83 |
+
"ection (questioning claims), and openness to data. No formal rituals; involves ethical living based on reason, potentially contemplative for personal growth.\n\nCore Beliefs: Beliefs: Unknowability of gods/transcendent realities, method over creed (pursue reason, recognize limits).",
|
| 84 |
+
"thod over creed (pursue reason, recognize limits). Variations: secular (nonreligious skepticism), religious (minimal doctrine with evidence), philosophical (Hume/Kant unknowables). Distinguishes from atheism by not denying, but suspending belief.",
|
| 85 |
+
"m atheism by not denying, but suspending belief.\n\nCommon Questions: Common questions: How differs from atheism? Can agnostics be religious? Is it a middle ground? What after death? Interesting facts: Absence of knowledge about gods; coined 1869; honest approach to big questions; can overlap with ath",
|
| 86 |
+
"st approach to big questions; can overlap with atheism; views existence as unknowable; promotes humility; no certain evidence for gods; kids' view: 'not sure' about big questions.\n\n\n\n============================================================\nReligion: New Age Spirituality",
|
| 87 |
+
"==================\nReligion: New Age Spirituality\n============================================================\n\nDescription: New Age Spirituality is an eclectic movement from the 1970s-80s, blending esotericism, theosophy, and mysticism to anticipate an era of peace through personal transformation.",
|
| 88 |
+
"e an era of peace through personal transformation. Rooted in 19th-century theosophy, it promotes holistic growth and global awakening, influencing wellness and alternative therapies.",
|
| 89 |
+
"influencing wellness and alternative therapies.\n\nPractices: Practices include meditation (energy work, channeling), energy healing (crystals, reiki), yoga, astrology, and rituals (affirmations, vision boards). Eclectic: tarot, shamanism, nature communion.",
|
| 90 |
+
"ds). Eclectic: tarot, shamanism, nature communion. Focus on self-transformation and sharing divine energy.\n\nCore Beliefs: Beliefs: Imminent New Age of enlightenment (Aquarian shift), personal spiritual transformation (sadhana path), interconnectedness, reincarnation, Ascended Masters.",
|
| 91 |
+
"terconnectedness, reincarnation, Ascended Masters. Variations: theosophical (Maitreya focus), psychedelic-influenced. Emphasizes active manifestation over passive waiting.",
|
| 92 |
+
"sizes active manifestation over passive waiting.\n\nCommon Questions: Common questions: What is channeling? Why use crystals? Is yoga New Age? Do they believe in reincarnation? What is the Aquarian Age? Interesting facts: Umbrella for contemporary movement; not organized religion; planetary transforma",
|
| 93 |
+
"ment; not organized religion; planetary transformation; integrates astrology, tarot; spiritual healing; influenced by Western esotericism; emblematic universities like Naropa; focuses on human potential.\n\n\n\n============================================================",
|
| 94 |
+
"=================================================\nReligion: Spiritual But Not Religious\n============================================================\n\nDescription: Spiritual But Not Religious (SBNR) is a stance prioritizing personal spirituality over organized religion, focusing on individual well-be",
|
| 95 |
+
"organized religion, focusing on individual well-being and exploration. Emerging in the 1960s-2000s amid deinstitutionalization, it appeals to unaffiliated seekers valuing autonomy and eclecticism.",
|
| 96 |
+
"liated seekers valuing autonomy and eclecticism.\n\nPractices: Practices include meditation (mindfulness, TM), nature connection, eclectic rituals (Tarot, I Ching), and self-reflection. Therapeutic: yoga, journaling for emotional support. Avoids communal worship; experimental and as-needed.",
|
| 97 |
+
"ds communal worship; experimental and as-needed.\n\nCore Beliefs: Beliefs: Spirituality as private empowerment, anti-dogmatic (religion as rigid), focus on mind-body-spirit harmony. Variations: dissenters (reject religion), explorers (wanderlust), seekers (looking for home).",
|
| 98 |
+
"xplorers (wanderlust), seekers (looking for home). Emphasizes curiosity, intellectual freedom, personal path.\n\nCommon Questions: Common questions: What does SBNR mean? Do they believe in God? Why reject religion? What practices? Interesting facts: Connected to true self; most Americans spiritual; ad",
|
| 99 |
+
"nnected to true self; most Americans spiritual; addresses evil/misery; values ethical values; personal divine experience; anti-dogma; hunger for ritual without structure; integrates with other beliefs.\n\n\n\n============================================================\nReligion: Sikhism",
|
| 100 |
+
"===============================\nReligion: Sikhism\n============================================================\n\nDescription: Sikhism is a monotheistic faith founded by Guru Nanak in 15th-century Punjab, emphasizing equality, service, and devotion.",
|
| 101 |
+
"njab, emphasizing equality, service, and devotion. With 25 million adherents, it follows 10 Gurus' teachings, now in the Guru Granth Sahib, promoting ethical living and community amid historical independence from Hinduism.",
|
| 102 |
+
"nity amid historical independence from Hinduism.\n\nPractices: Practices include daily prayer/meditation (Nitnem), community service (seva), langar (free meals), wearing 5 Ks (kesh, kangha, kara, kachera, kirpan), and gurdwara attendance. Festivals: Vaisakhi, Diwali.",
|
| 103 |
+
"gurdwara attendance. Festivals: Vaisakhi, Diwali. Focus on honest living and sharing.\n\nCore Beliefs: Beliefs: One formless God, equality of all, Gurmat (Guru's way), liberation via devotion, rejection of caste/rituals. Scriptures: Guru Granth Sahib.",
|
| 104 |
+
"n of caste/rituals. Scriptures: Guru Granth Sahib. Influences: Sant (nirgun devotion), Nath (meditation ascent). Emphasizes ethical monotheism, service.",
|
| 105 |
+
"ascent). Emphasizes ethical monotheism, service.\n\nCommon Questions: Common questions: What do Sikhs teach about other religions? Who are the Gurus? Why wear turbans/5 Ks? What is langar? Interesting facts: Founded 1469 by Guru Nanak; 27 million followers; originated in Punjab; equality of men/women;",
|
| 106 |
+
"wers; originated in Punjab; equality of men/women; no caste; daily prayer; emblem Khanda; greets with Sat Sri Akal; emphasizes humanity and charity.\n\n\n\n============================================================\nReligion: Indigenous Spirituality",
|
| 107 |
+
"===============\nReligion: Indigenous Spirituality\n============================================================\n\nDescription: Indigenous Spirituality encompasses diverse traditional beliefs of native peoples worldwide, deeply connected to land, ancestors, and nature.",
|
| 108 |
+
", deeply connected to land, ancestors, and nature. Rooted in ancient oral histories, it emphasizes holistic well-being, resilience, and reciprocity, varying by community but sharing themes of interconnectedness and cultural identity.",
|
| 109 |
+
"mes of interconnectedness and cultural identity.\n\nPractices: Practices include ceremonies (sweat lodges, vision quests), storytelling, seasonal rituals (harvest dances), and healing (herbal medicine, shamanic journeys). Community-focused: elder guidance, sacred sites pilgrimage.",
|
| 110 |
+
"-focused: elder guidance, sacred sites pilgrimage. Emphasizes respect for nature and ancestors.\n\nCore Beliefs: Beliefs: Interconnectedness of all (humans, animals, spirits), land as sacred, ancestor veneration, balance/harmony.",
|
| 111 |
+
"d as sacred, ancestor veneration, balance/harmony. Variations: Native American (Great Spirit, totemism), Aboriginal (Dreamtime, kinship). Holistic: mind-body-spirit integration; resilience through cultural practices.",
|
| 112 |
+
"egration; resilience through cultural practices.\n\nCommon Questions: Common questions: What is Indigenous spirituality? Do they have a Great Spirit? How linked to land? Myths about 'having it easy'? Interesting facts: Diverse, no single belief; spirituality in daily life; no division spiritual/secula",
|
| 113 |
+
"uality in daily life; no division spiritual/secular; kinship with nature; ceremonies vary by tribe; addresses appropriation; hunger for rituals; combined with other faiths sometimes."
|
| 114 |
+
]
|
closest_chunk.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
s as paths to nirvana (liberation from rebirth).
|
| 2 |
+
|
| 3 |
+
Practices: Core practices include meditation (vipassana for insight, samatha for calm), mindfulness (awareness in daily life), following the Eightfold Path (right view, intention, speech, action, livelihood, effort, mindfulness, concentration), and o
|
static/images/icon2.png β embeddings.pkl
RENAMED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a70efdf0c758156daf495242a3a19c1bccfce1e38e307720c81ebd16b90f3ed8
|
| 3 |
+
size 172195
|
rag_utils.py
CHANGED
|
@@ -8,14 +8,14 @@ def load_religions_from_csv(csv_path):
|
|
| 8 |
with open(csv_path, 'r', encoding='utf-8') as f:
|
| 9 |
reader = csv.DictReader(f)
|
| 10 |
for row in reader:
|
| 11 |
-
religions[row['
|
| 12 |
print(f"β
Loaded {len(religions)} religions from CSV")
|
| 13 |
return religions
|
| 14 |
except Exception as e:
|
| 15 |
print(f"β οΈ Error loading religions CSV: {e}")
|
| 16 |
return {}
|
| 17 |
|
| 18 |
-
def prepare_religion_rag_context(religion_data):
|
| 19 |
"""Prepare context string from religion data"""
|
| 20 |
parts = []
|
| 21 |
|
|
@@ -28,4 +28,4 @@ def prepare_religion_rag_context(religion_data):
|
|
| 28 |
if 'common_curiosities' in religion_data:
|
| 29 |
parts.append(f"Common Questions: {religion_data['common_curiosities']}")
|
| 30 |
|
| 31 |
-
return ['\n\n'.join(parts)]
|
|
|
|
| 8 |
with open(csv_path, 'r', encoding='utf-8') as f:
|
| 9 |
reader = csv.DictReader(f)
|
| 10 |
for row in reader:
|
| 11 |
+
religions[row['key']] = row
|
| 12 |
print(f"β
Loaded {len(religions)} religions from CSV")
|
| 13 |
return religions
|
| 14 |
except Exception as e:
|
| 15 |
print(f"β οΈ Error loading religions CSV: {e}")
|
| 16 |
return {}
|
| 17 |
|
| 18 |
+
def prepare_religion_rag_context(religion_data, use_chunks=True):
|
| 19 |
"""Prepare context string from religion data"""
|
| 20 |
parts = []
|
| 21 |
|
|
|
|
| 28 |
if 'common_curiosities' in religion_data:
|
| 29 |
parts.append(f"Common Questions: {religion_data['common_curiosities']}")
|
| 30 |
|
| 31 |
+
return ['\n\n'.join(parts)] if not use_chunks else parts
|
religions.csv
DELETED
|
@@ -1,109 +0,0 @@
|
|
| 1 |
-
id,religion,category,topic,content,keywords,question_relevance
|
| 2 |
-
1,christianity,core_belief,nature_of_divine,"Christianity is a monotheistic religion centered on belief in one God who exists as three persons: Father, Son (Jesus Christ), and Holy Spirit. Christians believe God is loving, just, and personal, actively involved in human affairs.","monotheism,trinity,personal god,jesus christ",q1_q4
|
| 3 |
-
2,christianity,practice,spiritual_connection,"Christians connect with God through personal prayer, communal worship, reading the Bible, and participating in sacraments like communion and baptism. Church community is central to faith practice.","prayer,worship,bible,communion,church",q2_q5
|
| 4 |
-
3,christianity,belief,afterlife,Christianity teaches that faith in Jesus Christ leads to eternal life in Heaven with God. Those who reject Christ face separation from God (Hell). Salvation is through grace and faith.,"heaven,hell,salvation,eternal life,grace",q3
|
| 5 |
-
4,christianity,ethics,moral_guidance,"Christian ethics are based on Biblical teachings, especially Jesus' commands to love God and love others. The Ten Commandments and Jesus' Sermon on the Mount provide moral framework.","bible,ten commandments,love,scripture,jesus teaching",q4
|
| 6 |
-
5,christianity,practice,nature_relationship,"Christians view humans as stewards of God's creation, called to care for the Earth responsibly. Nature reveals God's glory but is distinct from God.","stewardship,creation care,dominion",q6
|
| 7 |
-
6,christianity,belief,suffering,"Suffering is often seen as a test of faith, opportunity for spiritual growth, or part of God's mysterious plan. Jesus' suffering on the cross gives meaning to human suffering.","test of faith,cross,redemptive suffering,gods plan",q7
|
| 8 |
-
7,islam,core_belief,nature_of_divine,"Islam is strictly monotheistic, believing in one God (Allah) who is merciful, compassionate, and transcendent. Allah is the creator and sustainer of all existence, revealed through Prophet Muhammad.","monotheism,allah,tawhid,prophet muhammad",q1_q4
|
| 9 |
-
8,islam,practice,spiritual_connection,"Muslims connect with Allah through five daily prayers (salat), reciting Quran, and following the Five Pillars. Prayer involves physical prostration showing submission to Allah.","five pillars,salat,prayer,quran,submission",q2_q5
|
| 10 |
-
9,islam,belief,afterlife,Muslims believe in Day of Judgment where all are resurrected and judged by Allah. Paradise (Jannah) awaits the righteous; Hell (Jahannam) for those who reject faith and do evil.,"judgment day,jannah,paradise,hell,resurrection",q3
|
| 11 |
-
10,islam,ethics,moral_guidance,"Islamic ethics come from Quran and Hadith (Prophet's teachings). Core values include justice, compassion, honesty, modesty, and following Shariah (Islamic law).","quran,hadith,shariah,justice,compassion",q4
|
| 12 |
-
11,islam,practice,nature_relationship,"Muslims see humans as Allah's khalifah (stewards) on Earth, responsible for protecting and using resources justly. Nature is a sign of Allah's power and mercy.","khalifah,stewardship,creation,signs of allah",q6
|
| 13 |
-
12,islam,belief,suffering,Suffering is a test from Allah to strengthen faith and purify the soul. Patience (sabr) during hardship is highly valued and rewarded by Allah.,"test,sabr,patience,purification,trial",q7
|
| 14 |
-
13,buddhism,core_belief,nature_of_divine,"Buddhism generally doesn't focus on a creator god. Instead, it teaches about the nature of reality, suffering, and the path to enlightenment (Nirvana). Some schools venerate Buddha and bodhisattvas.","non-theistic,enlightenment,nirvana,buddha,no creator",q1
|
| 15 |
-
14,buddhism,practice,spiritual_connection,"Buddhists practice meditation (especially mindfulness and concentration), follow the Eightfold Path, and cultivate wisdom and compassion. Personal practice is emphasized over communal worship.","meditation,mindfulness,eightfold path,personal practice",q2_q5
|
| 16 |
-
15,buddhism,belief,afterlife,Buddhism teaches rebirth (samsara) driven by karma. The goal is to achieve Nirvana - liberation from the cycle of rebirth and suffering. Rebirth isn't eternal soul but continuation of consciousness.,"rebirth,samsara,karma,nirvana,liberation",q3
|
| 17 |
-
16,buddhism,ethics,moral_guidance,"Buddhist ethics center on the Four Noble Truths and Eightfold Path. Core principles include non-harm (ahimsa), compassion (karuna), and mindful awareness. Actions create karma.","four noble truths,ahimsa,compassion,karma,mindfulness",q4
|
| 18 |
-
17,buddhism,belief,interconnection,Buddhism teaches dependent origination - all phenomena are interconnected. Harming nature harms oneself. All sentient beings deserve compassion and should be treated with respect.,"interconnection,dependent origination,sentient beings,compassion",q6
|
| 19 |
-
18,buddhism,belief,suffering,"Suffering (dukkha) is caused by attachment, craving, and ignorance of reality's true nature. The path to end suffering is through understanding, letting go of attachment, and following the Eightfold Path.","dukkha,attachment,craving,four noble truths,cessation",q7
|
| 20 |
-
19,hinduism,core_belief,nature_of_divine,"Hinduism embraces diverse views: one supreme reality (Brahman) manifesting as many deities, or devotion to personal gods like Vishnu, Shiva, or Devi. Ultimate reality is beyond form.","brahman,polytheism,monotheism,vishnu,shiva,multiple paths",q1
|
| 21 |
-
20,hinduism,practice,spiritual_connection,"Hindus practice yoga, meditation, puja (worship), temple visits, and festivals. Multiple paths exist: devotion (bhakti), knowledge (jnana), action (karma yoga), meditation (raja yoga).","yoga,meditation,puja,bhakti,multiple paths",q2_q5
|
| 22 |
-
21,hinduism,belief,afterlife,"Hindus believe in reincarnation (samsara) based on karma. The soul (atman) is reborn until achieving moksha (liberation) - union with Brahman, ending the cycle of rebirth.","reincarnation,karma,moksha,atman,samsara,liberation",q3
|
| 23 |
-
22,hinduism,ethics,moral_guidance,"Hindu ethics center on dharma (righteous duty), which varies by role, age, and circumstance. Universal principles include non-violence (ahimsa), truthfulness, and compassion.","dharma,ahimsa,karma,righteous duty",q4
|
| 24 |
-
23,hinduism,belief,interconnection,"Hinduism teaches all life contains the divine essence (atman/Brahman). Ahimsa (non-violence) extends to all creatures. Many Hindus are vegetarian, viewing cows and other animals as sacred.","atman,brahman,sacred,ahimsa,interconnected",q6
|
| 25 |
-
24,hinduism,belief,suffering,Suffering results from karma - consequences of past actions in this or previous lives. It's an opportunity to work through karmic debt and progress spiritually toward moksha.,"karma,past lives,spiritual progress,moksha",q7
|
| 26 |
-
25,judaism,core_belief,nature_of_divine,"Judaism is strictly monotheistic, believing in one God (YHWH/Adonai) who is eternal, creator, and enters into covenant with the Jewish people. God is both transcendent and involved in history.","monotheism,yhwh,covenant,ethical monotheism",q1_q4
|
| 27 |
-
26,judaism,practice,spiritual_connection,"Jews connect with God through prayer (especially Shabbat and holidays), Torah study, following mitzvot (commandments), and community participation in synagogue.","prayer,torah,mitzvot,shabbat,synagogue",q2_q5
|
| 28 |
-
27,judaism,belief,afterlife,"Jewish views on afterlife vary. Traditional belief includes resurrection of the dead in messianic age. Some emphasize this-world focus, others believe in Olam Ha-Ba (World to Come).","resurrection,messianic age,olam haba,varied views",q3
|
| 29 |
-
28,judaism,ethics,moral_guidance,"Jewish ethics come from Torah and Talmud, emphasizing justice (tzedakah), ethical behavior, study, and repair of the world (tikkun olam). The 613 mitzvot guide daily life.","torah,talmud,tzedakah,tikkun olam,justice",q4
|
| 30 |
-
29,judaism,practice,nature_relationship,Jews are stewards (bal tashchit - don't destroy) of God's creation. Environmental care is a religious duty. Laws like kosher and sabbatical years reflect respect for creation.,"stewardship,bal tashchit,creation care",q6
|
| 31 |
-
30,judaism,belief,suffering,"Suffering raises theological questions addressed differently across Jewish thought. Some see it as test, punishment, mystery, or call to action for justice. Holocaust deeply shaped modern Jewish theology.","test,mystery,justice,theological question",q7
|
| 32 |
-
31,taoism,core_belief,nature_of_divine,"Taoism centers on the Tao - the ineffable, eternal source and pattern of all existence. It's not a personal god but the natural way of the universe, beyond words or concepts.","tao,natural way,non-theistic,universal force",q1
|
| 33 |
-
32,taoism,practice,spiritual_connection,"Taoists practice meditation, tai chi, qigong, and wu wei (effortless action). The focus is aligning with natural rhythms and simplicity rather than forceful striving.","meditation,tai chi,wu wei,simplicity,natural flow",q2_q5
|
| 34 |
-
33,taoism,belief,afterlife,Traditional Taoism includes beliefs in immortality through spiritual cultivation and alchemy. Philosophical Taoism focuses more on living well in harmony with Tao than afterlife concerns.,"immortality,spiritual cultivation,harmony,this-life focus",q3
|
| 35 |
-
34,taoism,ethics,moral_guidance,"Taoist ethics emphasize naturalness, spontaneity, simplicity, and compassion. Rather than rigid rules, guidance comes from understanding natural balance (yin-yang) and wu wei.","naturalness,wu wei,yin-yang,balance,spontaneity",q4
|
| 36 |
-
35,taoism,belief,interconnection,"Taoism sees humans as integral part of nature, not separate or superior. Living in harmony with natural cycles and respecting all life reflects the Tao. Nature is the primary teacher.","harmony with nature,natural cycles,interconnection,nature teacher",q6
|
| 37 |
-
36,taoism,belief,suffering,"Suffering arises from resistance to natural flow and clinging to desires. By accepting change, practicing wu wei, and aligning with Tao, one reduces suffering and finds peace.","resistance,acceptance,wu wei,natural flow",q7
|
| 38 |
-
37,paganism,core_belief,nature_of_divine,Modern Paganism typically honors multiple deities (polytheism) or sees divinity in nature itself (pantheism). Gods/goddesses often represent natural forces and archetypal energies.,"polytheism,pantheism,nature deities,goddess,god",q1
|
| 39 |
-
38,paganism,practice,spiritual_connection,"Pagans celebrate seasonal festivals (solstices, equinoxes), perform rituals, work with natural elements, and often practice magic. Connection with nature is central to practice.","sabbats,rituals,nature connection,magic,seasonal celebrations",q2_q5
|
| 40 |
-
39,paganism,belief,afterlife,"Pagan views vary widely: some believe in reincarnation, others in ancestral realms or otherworlds, some in merging with nature. Many focus on honoring this life fully.","reincarnation,otherworld,ancestral realm,varied views",q3
|
| 41 |
-
40,paganism,ethics,moral_guidance,"Pagan ethics often center on personal responsibility and the Wiccan Rede ('harm none'). Values include balance, reciprocity with nature, and authentic personal experience.","harm none,reciprocity,personal responsibility,balance",q4
|
| 42 |
-
41,paganism,belief,interconnection,"Pagans view nature as sacred and divine. All life is interconnected. Humans are part of nature's web, not separate or superior. Environmental stewardship is spiritual duty.","nature sacred,divine nature,interconnected,sacred earth",q6
|
| 43 |
-
42,paganism,belief,suffering,Suffering is part of natural cycles of death and rebirth. It can be transformative and teach important lessons. Balance between light and dark is natural and necessary.,"cycles,transformation,balance,death and rebirth",q7
|
| 44 |
-
43,humanism,core_belief,nature_of_divine,"Humanism is non-religious, rejecting supernatural beliefs. Focus is on human potential, reason, ethics, and science without gods or divine intervention.","atheistic,secular,non-religious,reason,human potential",q1
|
| 45 |
-
44,humanism,practice,spiritual_connection,"Humanists connect through reason, critical thinking, community service, art, philosophy, and building meaningful relationships. Fulfillment comes from human connection and contribution.","reason,community,philosophy,critical thinking,service",q2_q5
|
| 46 |
-
45,humanism,belief,afterlife,"Humanists generally don't believe in afterlife. This life is all there is, making it precious. Legacy lives through impact on others and contributions to human progress.","no afterlife,this life only,legacy,naturalistic",q3
|
| 47 |
-
46,humanism,ethics,moral_guidance,"Humanist ethics are based on reason, empathy, human rights, and wellbeing. Morality comes from human needs and social context, not divine command. Science informs ethical decisions.","reason,empathy,human rights,secular ethics,evidence-based",q4
|
| 48 |
-
47,humanism,belief,interconnection,"Humanists view humans as part of natural world, subject to natural laws. Environmental protection is important for human wellbeing and future generations, based on scientific understanding.","naturalism,science,environmentalism,evolution",q6
|
| 49 |
-
48,humanism,belief,suffering,"Suffering has natural causes, not divine purpose. Humans can reduce suffering through science, medicine, social progress, and compassionate action. Focus on solving problems, not accepting fate.","natural causes,problem-solving,progress,compassion",q7
|
| 50 |
-
49,atheism,core_belief,nature_of_divine,"Atheism is lack of belief in gods or deities. Atheists rely on naturalistic explanations, viewing universe as product of natural processes without supernatural intervention.","no god,naturalistic,non-theistic,skepticism",q1
|
| 51 |
-
50,atheism,practice,spiritual_connection,"Atheists typically don't seek spiritual connection in traditional sense. Meaning comes from relationships, experiences, learning, creativity, and contributing to society. Some find awe in nature/science.","secular,community,science,meaning-making,non-spiritual",q2_q5
|
| 52 |
-
51,atheism,belief,afterlife,Atheists don't believe in afterlife. Consciousness ends at death. This makes life precious and motivates living fully and ethically now.,"no afterlife,materialism,this life only,consciousness ends",q3
|
| 53 |
-
52,atheism,ethics,moral_guidance,"Atheist morality is based on empathy, reason, wellbeing, and social cooperation. Ethics evolved to help humans live together successfully, not from divine command.","secular ethics,empathy,reason,evolution,wellbeing",q4
|
| 54 |
-
53,atheism,belief,interconnection,"Atheists understand humans as evolved animals, part of natural world. Environmental concern comes from understanding ecology and protecting our only home, based on scientific evidence.","naturalism,evolution,science,ecology,evidence-based",q6
|
| 55 |
-
54,atheism,belief,suffering,"Suffering has natural causes - disease, accidents, natural disasters, human actions. No divine purpose or test. We reduce suffering through medicine, technology, social justice, and compassion.","natural causes,randomness,problem-solving,no divine plan",q7
|
| 56 |
-
55,agnosticism,core_belief,nature_of_divine,Agnostics hold that existence/nature of divine is unknown or unknowable. Some lack belief but remain open; others actively believe we cannot know. Focus on uncertainty rather than conviction.,"unknowable,uncertainty,open-minded,skeptical inquiry",q1
|
| 57 |
-
56,agnosticism,practice,spiritual_connection,"Agnostics may explore various practices or none at all. Often value philosophical inquiry, ethical living, and intellectual honesty over religious ritual. Open to diverse perspectives.","inquiry,philosophical,eclectic,ethical living,exploration",q2_q5
|
| 58 |
-
57,agnosticism,belief,afterlife,"Agnostics are uncertain about afterlife. Some lean toward no afterlife, others remain completely open. Emphasis on living well now given the uncertainty about what follows.","uncertain,unknown,open possibilities,this-life focus",q3
|
| 59 |
-
58,agnosticism,ethics,moral_guidance,"Agnostic ethics often based on reason, empathy, and human wellbeing without certainty about divine command. Questions and inquiry are valued over absolute answers.","reason,empathy,inquiry,questioning,open ethics",q4
|
| 60 |
-
59,agnosticism,belief,interconnection,Agnostics may appreciate scientific understanding of interconnection or remain open to spiritual interpretations. Often value environmental care based on practical concerns.,"scientific understanding,open interpretation,practical ethics",q6
|
| 61 |
-
60,agnosticism,belief,suffering,Agnostics are uncertain whether suffering has purpose or is random. May see it as natural phenomenon while remaining open to other interpretations. Focus on responding compassionately.,"uncertainty,natural and/or meaningful,compassionate response",q7
|
| 62 |
-
61,new_age,core_belief,nature_of_divine,"New Age spirituality sees divine as universal consciousness or energy pervading all existence. Often blends ideas from Eastern religions, Western esotericism, and modern psychology.","universal consciousness,divine energy,holistic,eclectic",q1
|
| 63 |
-
62,new_age,practice,spiritual_connection,"New Age practitioners use meditation, energy healing, crystals, yoga, tarot, astrology, and visualization. Emphasis on personal experience and whatever resonates individually.","meditation,crystals,energy work,personal practice,eclectic",q2_q5
|
| 64 |
-
63,new_age,belief,afterlife,"New Age views often include reincarnation, spiritual evolution across lifetimes, and eventual unity with higher consciousness. Some believe in creating own reality even after death.","reincarnation,spiritual evolution,higher consciousness,varied beliefs",q3
|
| 65 |
-
64,new_age,ethics,moral_guidance,"New Age ethics emphasize personal growth, positive thinking, manifesting desires, and universal love. 'What you put out returns to you' (Law of Attraction). Follow inner guidance.","law of attraction,personal growth,inner guidance,positive energy",q4
|
| 66 |
-
65,new_age,belief,interconnection,"New Age teaches all is one - humans, nature, cosmos connected through universal energy. Harming environment harms collective consciousness. Earth (Gaia) may be seen as living being.","oneness,universal energy,gaia,interconnected consciousness",q6
|
| 67 |
-
66,new_age,belief,suffering,Suffering provides growth opportunities and spiritual lessons. Often seen as self-created for soul evolution. Positive thinking and raising vibration can transform suffering.,"growth opportunity,spiritual lesson,soul evolution,transformation",q7
|
| 68 |
-
67,spiritual_not_religious,core_belief,nature_of_divine,"SBNR individuals have personal spiritual beliefs outside organized religion. Views vary widely - some believe in higher power, universal energy, or remain undefined. Value personal experience over doctrine.","personal spirituality,no organized religion,individual path,authentic",q1
|
| 69 |
-
68,spiritual_not_religious,practice,spiritual_connection,"SBNR people create personal practices - may include meditation, nature connection, journaling, yoga, or borrowing from various traditions. Emphasis on what feels authentic and meaningful.","personal practice,eclectic,authentic,self-directed,meaningful",q2_q5
|
| 70 |
-
69,spiritual_not_religious,belief,afterlife,"SBNR views on afterlife vary widely. Some believe in reincarnation, others in energy continuation, some remain open and uncertain. Focus on present spiritual experience over afterlife doctrine.","varied beliefs,open-minded,present-focused,personal interpretation",q3
|
| 71 |
-
70,spiritual_not_religious,ethics,moral_guidance,"SBNR ethics based on personal intuition, inner wisdom, and values like compassion and authenticity. Draw from various sources - philosophy, psychology, wisdom traditions - without dogma.","intuition,inner wisdom,authenticity,compassion,non-dogmatic",q4
|
| 72 |
-
71,spiritual_not_religious,belief,interconnection,SBNR individuals often feel deep connection to nature and all life. May see nature as sacred teacher without formal religious framework. Environmental care is spiritual practice.,"nature connection,sacred nature,interconnection,personal meaning",q6
|
| 73 |
-
72,spiritual_not_religious,belief,suffering,SBNR views on suffering are personal and varied. Many see it as growth opportunity or natural part of life's journey. Focus on finding personal meaning rather than accepting religious explanation.,"personal meaning,growth,varied interpretation,authentic response",q7
|
| 74 |
-
73,sikhism,core_belief,nature_of_divine,"Sikhism is monotheistic, believing in one formless God (Waheguru) who is creator, sustainer, and destroyer. God is timeless, without gender, and accessible to all through devotion and service.","monotheism,waheguru,one god,formless,universal access",q1_q4
|
| 75 |
-
74,sikhism,practice,spiritual_connection,"Sikhs connect with God through meditation on God's name (Naam Japna), selfless service (Seva), honest living (Kirat Karni), and sharing (Vand Chakna). Community worship at Gurdwara is important.","naam japna,seva,kirat karni,gurdwara,community",q2_q5_q8
|
| 76 |
-
75,sikhism,belief,afterlife,Sikhs believe in reincarnation based on karma until union with God is achieved. The goal is to escape reincarnation cycle and merge with divine light through righteous living.,"reincarnation,karma,union with god,liberation,mukti",q3
|
| 77 |
-
76,sikhism,ethics,moral_guidance,"Sikh ethics emphasize equality, justice, service, honest work, and devotion. The five virtues are truth, contentment, compassion, humility, and love. Fight against injustice is duty.","equality,justice,five virtues,honest living,service",q4
|
| 78 |
-
77,sikhism,belief,interconnection,"Sikhs see all creation as manifestation of one God. All humans are equal regardless of caste, gender, or religion. Environmental care is duty as God's creation must be respected.","equality,gods creation,stewardship,respect for all",q6
|
| 79 |
-
78,sikhism,belief,suffering,"Suffering is result of separation from God and ego (Haumai). It's also karma from past lives. Through devotion, service, and God's grace, one can transcend suffering.","karma,separation from god,ego,grace,transcendence",q7
|
| 80 |
-
79,indigenous,core_belief,nature_of_divine,"Indigenous spiritualities vary greatly but often include Great Spirit, creator beings, and/or spirits in all things (animism). Divine is immanent in nature, ancestors, and the land itself.","great spirit,animism,spirits,ancestors,varied traditions",q1
|
| 81 |
-
80,indigenous,practice,spiritual_connection,"Indigenous practices include ceremonies, storytelling, seasonal rituals, vision quests, and maintaining relationship with land and ancestors. Community and tradition are central.","ceremonies,storytelling,seasonal rituals,land connection,ancestral",q2_q5
|
| 82 |
-
81,indigenous,belief,afterlife,"Indigenous beliefs often include journey to spirit world or ancestral realm after death. Ancestors remain present and active. Death is transformation, not end. Varies by tradition.","spirit world,ancestors,transformation,varied beliefs,continuity",q3
|
| 83 |
-
82,indigenous,ethics,moral_guidance,"Indigenous ethics center on reciprocity with nature and community, respect for elders and ancestors, seven generations thinking, and living in balance. Wisdom comes from tradition and land.","reciprocity,respect,balance,traditional wisdom,seven generations",q4
|
| 84 |
-
83,indigenous,belief,interconnection,"Indigenous worldviews see all beings as relatives - plants, animals, rocks, rivers all have spirit. Humans are part of nature's web with responsibilities. Land is sacred, not property.","all my relations,sacred land,interconnection,reciprocity,kinship",q6
|
| 85 |
-
84,indigenous,belief,suffering,"Suffering may be seen as imbalance, result of not honoring relationships, or spiritual lesson. Healing comes through ceremony, community support, and restoring harmony.","imbalance,ceremony,healing,restoration,community",q7
|
| 86 |
-
85,jainism,core_belief,nature_of_divine,"Jainism is non-theistic, focusing on individual spiritual liberation rather than god-worship. The universe is eternal, uncreated. Tirthankaras (enlightened teachers) show the path but aren't gods.","non-theistic,tirthankaras,eternal universe,self-liberation",q1
|
| 87 |
-
86,jainism,practice,spiritual_connection,"Jains practice strict non-violence (ahimsa), meditation, fasting, self-discipline, and study. Monks/nuns follow intense ascetic practices. Lay people support monastics and follow modified vows.","ahimsa,meditation,fasting,asceticism,non-violence",q2_q5
|
| 88 |
-
87,jainism,belief,afterlife,"Jains believe in reincarnation based on karma. Liberation (moksha) comes through eliminating all karma through right conduct, non-violence, and asceticism, freeing soul from rebirth cycle.","reincarnation,karma,moksha,liberation,soul purification",q3
|
| 89 |
-
88,jainism,ethics,moral_guidance,"Jain ethics center on ahimsa (non-violence) to all living beings. Five main vows: non-violence, truth, non-stealing, celibacy/chastity, non-attachment. Compassion extends to smallest creatures.","ahimsa,non-violence,five vows,compassion,universal",q4
|
| 90 |
-
89,jainism,belief,interconnection,"Jainism teaches all beings have souls (jiva) and deserve absolute respect. Even plants, water, and air contain souls. Strict vegetarianism and extreme care not to harm any life.","jiva,all beings sacred,extreme non-violence,vegetarianism,reverence for life",q6
|
| 91 |
-
90,jainism,belief,suffering,"Suffering results from karma accumulated through violence and attachment. Liberation comes through eliminating karma via strict non-violence, asceticism, and detachment from worldly concerns.","karma,non-violence,asceticism,detachment,purification",q7
|
| 92 |
-
91,shintoism,core_belief,nature_of_divine,"Shinto honors kami - spirits in nature, ancestors, and sacred places. Kami are not all-powerful gods but spiritual essences deserving respect. No single creator deity or canonical texts.","kami,nature spirits,ancestors,polytheistic,japanese tradition",q1
|
| 93 |
-
92,shintoism,practice,spiritual_connection,"Shinto practices include shrine visits, purification rituals (misogi), festivals (matsuri), offerings to kami, and maintaining harmony with nature. Ritual purity is important.","shrines,purification,matsuri,offerings,rituals",q2_q5
|
| 94 |
-
93,shintoism,belief,afterlife,"Shinto has no clear afterlife doctrine. Ancestors become kami and are venerated. Focus is on this life, purity, and harmony rather than afterlife rewards/punishments.","ancestors become kami,this-life focus,veneration,unclear afterlife",q3
|
| 95 |
-
94,shintoism,ethics,moral_guidance,"Shinto ethics emphasize purity, harmony with nature and community, gratitude, and living naturally. Morality comes from innate goodness and maintaining balance, not divine commandments.","purity,harmony,gratitude,natural living,balance",q4
|
| 96 |
-
95,shintoism,belief,interconnection,"Shinto sees nature as sacred - mountains, rivers, trees, rocks can all house kami. Humans are part of nature, not separate. Living in harmony with natural world is spiritual imperative.","nature sacred,kami in nature,harmony,sacred places,reverence",q6
|
| 97 |
-
96,shintoism,belief,suffering,Shinto doesn't have elaborate suffering theology. Misfortune may come from spiritual impurity or disharmony. Purification rituals and harmonious living restore balance and wellbeing.,"purification,impurity,balance,harmony,restoration",q7
|
| 98 |
-
97,stoicism,core_belief,nature_of_divine,"Stoicism is philosophical tradition, not religion. Some ancient Stoics believed in divine reason (logos) pervading cosmos; modern Stoics may be theistic, atheistic, or agnostic. Focus is on virtue.","philosophy,logos,reason,virtue,varied divine views",q1
|
| 99 |
-
98,stoicism,practice,spiritual_connection,"Stoics practice contemplation, journaling, virtue cultivation, and accepting what can't be controlled. Philosophical study and rational reflection replace religious ritual.","contemplation,journaling,virtue practice,rational reflection,philosophy",q2_q5
|
| 100 |
-
99,stoicism,belief,afterlife,Ancient Stoics had varied views; many modern Stoics don't focus on afterlife. Emphasis is on living virtuously now. Some believed in soul's continuation; others focused solely on this life.,"varied views,this-life focus,virtue,unclear afterlife",q3
|
| 101 |
-
100,stoicism,ethics,moral_guidance,"Stoic ethics center on four cardinal virtues: wisdom, justice, courage, temperance. Live according to reason and nature. Focus on what you can control; accept what you cannot.","four virtues,reason,acceptance,control,wisdom",q4
|
| 102 |
-
101,stoicism,belief,interconnection,"Stoics see humans as part of rational, ordered cosmos. We're social beings with duties to others. Living according to nature means recognizing our place in larger whole.","cosmic order,social duty,rational nature,interconnection",q6
|
| 103 |
-
102,stoicism,belief,suffering,"Suffering comes from mistaken judgments and desire for control over externals. By accepting fate (amor fati), focusing on virtue, and distinguishing what we control, we achieve tranquility.","acceptance,amor fati,control,judgment,tranquility",q7
|
| 104 |
-
103,confucianism,core_belief,nature_of_divine,"Confucianism is philosophical/ethical system more than religion. Focus is on human relationships and moral cultivation, not supernatural. Some reverence for Heaven (Tian) as moral force.","philosophy,ethics,tian,human relationships,moral cultivation",q1
|
| 105 |
-
104,confucianism,practice,spiritual_connection,"Confucian practice emphasizes ritual propriety (li), ancestor veneration, study of classics, self-cultivation, and fulfilling social roles properly. Education and moral development are central.","ritual propriety,ancestor veneration,study,self-cultivation,li",q2_q5
|
| 106 |
-
105,confucianism,belief,afterlife,"Confucianism focuses on this life and proper conduct, not afterlife speculation. Ancestors are honored and remembered, continuing influence through descendants.","this-life focus,ancestor honor,unclear afterlife,legacy",q3
|
| 107 |
-
106,confucianism,ethics,moral_guidance,"Confucian ethics emphasize five relationships, filial piety, benevolence (ren), righteousness (yi), and proper ritual conduct. Moral cultivation through education and self-reflection.","five relationships,filial piety,ren,yi,moral cultivation",q4
|
| 108 |
-
107,confucianism,belief,interconnection,Confucianism sees humans as inherently social beings in web of relationships. Harmony in family and society reflects cosmic order. Proper human conduct maintains balance.,"social harmony,relationships,cosmic order,balance,interconnection",q6
|
| 109 |
-
108,confucianism,belief,suffering,"Suffering often results from social disorder, improper relationships, or lack of virtue. Remedy through moral cultivation, proper conduct, education, and restoring harmonious relationships.","moral cultivation,harmony,proper conduct,social order",q7
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
religions_corpus.txt
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
|
| 3 |
+
============================================================
|
| 4 |
+
Religion: Christianity
|
| 5 |
+
============================================================
|
| 6 |
+
|
| 7 |
+
Description: Christianity is a major monotheistic religion originating from the life, teachings, and death of Jesus of Nazareth in the 1st century CE. It is the world's largest religion with over two billion adherents, emphasizing faith in Jesus Christ as the Son of God who offers salvation through his death and resurrection. The religion has profoundly influenced global culture, ethics, and institutions, evolving through historical interactions with diverse civilizations and adapting to various contexts while maintaining a focus on redemption and community.
|
| 8 |
+
|
| 9 |
+
Practices: Key practices include prayer (personal and communal communication with God), Bible study (reading and interpreting sacred scriptures), attending church services (worship, preaching, and fellowship), and sacraments such as communion (commemorating Jesus' Last Supper) and baptism (symbolizing spiritual rebirth). Other observances involve fasting, charity, mission work, and celebrating holidays like Christmas (Jesus' birth) and Easter (resurrection). Practices vary by denomination, from liturgical rituals in Catholicism to charismatic worship in Pentecostalism.
|
| 10 |
+
|
| 11 |
+
Core Beliefs: Central beliefs include the Trinity (one God in three persons: Father, Son, Holy Spirit), salvation through faith in Jesus Christ (who atoned for humanity's sins), the resurrection and eternal life, original sin (humanity's fallen state), and the authority of the Bible. Additional doctrines encompass grace (God's unmerited favor), the church as the body of believers, eschatology (end times and judgment), and ethical living based on love, forgiveness, and justice. Monotheism is foundational, rejecting polytheism and atheism.
|
| 12 |
+
|
| 13 |
+
Common Questions: Common questions include: Why does God allow evil and suffering? Is faith irrational or opposed to science? Why is Jesus the only way to heaven? Can one lose salvation? Why are there hypocrites in Christianity? How to take the Bible literally? How should Christians respond to issues like LGBTQ+ rights, racism, and injustice? Interesting facts: Christianity emerged from Judaism; not all ministers wear special attire; churches are communities, not just buildings; over 2 billion followers worldwide; the Bible has no contradictions claimed by believers but debated by skeptics.
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
============================================================
|
| 18 |
+
Religion: Islam
|
| 19 |
+
============================================================
|
| 20 |
+
|
| 21 |
+
Description: Islam is a monotheistic religion founded in 7th-century Arabia by the Prophet Muhammad, emphasizing submission to the will of Allah (God) as revealed in the Quran. With over 1.5 billion adherents worldwide, it integrates spiritual devotion with social, legal, and ethical guidelines, fostering a sense of global community (ummah) and influencing diverse cultures through conquests, trade, and mysticism. It promotes justice, compassion, and personal accountability in both individual and communal life.
|
| 22 |
+
|
| 23 |
+
Practices: Core practices, known as the Five Pillars, include Shahada (profession of faith), Salat (five daily prayers), Zakat (charity to the needy), Sawm (fasting during Ramadan), and Hajj (pilgrimage to Mecca). Additional observances involve Halal dietary laws, ethical business conduct, community service, and Sufi mysticism (meditation, dhikr remembrance of God). Practices emphasize discipline, social equity, and spiritual purification, varying between Sunni and Shia traditions.
|
| 24 |
+
|
| 25 |
+
Core Beliefs: Fundamental beliefs are Tawhid (oneness of Allah), prophethood (Muhammad as the final prophet completing revelations from Adam to Jesus), angels, holy books (Quran as ultimate scripture), Day of Judgment (accountability for deeds), and predestination (Allah's will). Sources include Quran, Sunnah (Prophet's traditions), Ijma (consensus), and Ijtihad (reasoned interpretation). Ethics stress justice, mercy, and community, with variations in Sunni (Hadith-focused) and Shia (Imam-guided) interpretations.
|
| 26 |
+
|
| 27 |
+
Common Questions: Common questions: Why is Islam perceived as violent? What are the Five Pillars? Who was Muhammad? Do Muslims believe in Jesus? What is the difference between Sunni and Shia? Why do Muslims fast during Ramadan? What is Jihad? Interesting facts: Islam recognizes previous prophets like Abraham and Jesus; the Quran contains scientific facts ahead of its time; Muslims believe in one God without partners; major festivals include Eid al-Fitr and Eid al-Adha; over 1.8 billion followers worldwide; emphasizes charity and community.
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
============================================================
|
| 32 |
+
Religion: Buddhism
|
| 33 |
+
============================================================
|
| 34 |
+
|
| 35 |
+
Description: Buddhism is a philosophy and religion founded by Siddhartha Gautama (the Buddha) in northeastern India between the 6th and 4th centuries BCE, focusing on overcoming suffering through enlightenment. With global influence in Asia and beyond, it emphasizes ethical living, meditation, and wisdom, adapting to diverse cultures while promoting compassion and mindfulness as paths to nirvana (liberation from rebirth).
|
| 36 |
+
|
| 37 |
+
Practices: Core practices include meditation (vipassana for insight, samatha for calm), mindfulness (awareness in daily life), following the Eightfold Path (right view, intention, speech, action, livelihood, effort, mindfulness, concentration), and observing precepts (ethical guidelines like non-violence). Rituals vary: Theravada focuses on monastic discipline, Mahayana on bodhisattva vows and chants, Vajrayana on tantric rituals and mantras. Lay practices involve offerings, festivals, and pilgrimage.
|
| 38 |
+
|
| 39 |
+
Core Beliefs: Key beliefs are the Four Noble Truths (suffering, its cause in desire, cessation through detachment, path to end it), Three Jewels (Buddha, Dharma teachings, Sangha community), karma (actions' consequences), samsara (cycle of rebirth), nirvana (enlightenment), and impermanence (anicca). Variations: Theravada emphasizes individual liberation, Mahayana universal salvation via bodhisattvas, Vajrayana rapid enlightenment through esoteric methods. Rejects a creator god, focusing on self-reliance.
|
| 40 |
+
|
| 41 |
+
Common Questions: Common questions: Who was the Buddha? Is Buddhism a religion or philosophy? Do Buddhists believe in God? What is karma and reincarnation? How does one achieve enlightenment? Why is suffering central? Interesting facts: Originated 2,500 years ago in India; about 535 million followers; no creator god; focuses on ending suffering; diverse schools like Theravada, Mahayana; mindfulness practices influence modern psychology; Buddha means 'awakened one'; no single holy book but many scriptures.
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
============================================================
|
| 46 |
+
Religion: Hinduism
|
| 47 |
+
============================================================
|
| 48 |
+
|
| 49 |
+
Description: Hinduism is an ancient, diverse tradition originating in the Indian subcontinent around the 2nd millennium BCE, encompassing varied philosophies, rituals, and beliefs aimed at spiritual realization. As the world's oldest living religion with nearly one billion adherents, it adapts regionally and emphasizes dharma (duty), karma (actions' effects), and moksha (liberation), influencing art, ethics, and society globally through texts and practices.
|
| 50 |
+
|
| 51 |
+
Practices: Practices include yoga (physical and meditative disciplines), meditation (for inner peace), puja (worship with offerings), festivals (Diwali, Holi), pilgrimage (to sacred sites like Varanasi), and rites of passage (samskaras like marriage). Daily routines involve mantra chanting, vegetarianism for some, and community service. Variations span devotional bhakti, philosophical jnana, and action-oriented karma paths.
|
| 52 |
+
|
| 53 |
+
Core Beliefs: Core beliefs include dharma (cosmic order and duty), karma (cause and effect across lives), samsara (rebirth cycle), moksha (liberation), and Brahman (ultimate reality). Deities represent aspects of the divine (e.g., Vishnu, Shiva, Devi), with paths like bhakti (devotion), jnana (knowledge), and yoga. Scriptures: Vedas, Upanishads, epics like Ramayana. Emphasizes pluralism, with regional variations in worship and philosophy.
|
| 54 |
+
|
| 55 |
+
Common Questions: Common questions: Why so many gods? Do Hindus believe in reincarnation? What is karma? Why worship cows? Is Hinduism a religion or way of life? Interesting facts: Oldest religion, over 1.1 billion followers mostly in India; no single founder; diverse schools of philosophy; Vedas are ancient scriptures; emphasizes ahimsa (non-violence); multiple paths to truth; polytheistic yet monistic; festivals like Diwali celebrate light over darkness.
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
============================================================
|
| 60 |
+
Religion: Judaism
|
| 61 |
+
============================================================
|
| 62 |
+
|
| 63 |
+
Description: Judaism is a monotheistic religion developed among ancient Hebrews, centered on a covenant with God revealed through prophets like Abraham and Moses. With about 14 million adherents, it integrates theology, law, and culture, emphasizing ethical living and community while adapting through history, influencing Western civilization profoundly.
|
| 64 |
+
|
| 65 |
+
Practices: Practices include Shabbat observance (weekly rest and prayer), Torah study (scriptural learning), daily prayer (three times), kosher dietary laws, and life-cycle events (bar/bat mitzvah, circumcision). Holidays: Passover, Rosh Hashanah, Yom Kippur. Community involvement via synagogue services and charity (tzedakah). Variations in Orthodox (strict), Conservative (balanced), Reform (modern).
|
| 66 |
+
|
| 67 |
+
Core Beliefs: Beliefs include one transcendent God, Torah as divine law, covenant with Israel, ethical monotheism, messianic hope, resurrection, and free will. Prophets guide moral response; history reveals God's purpose. Emphasizes justice, peace, and human responsibility. Denominations differ in interpretation but share core ethical-historical monotheism.
|
| 68 |
+
|
| 69 |
+
Common Questions: Common questions: Why write G-d? What is the Wailing Wall? Is Judaism a religion or ethnicity? Why kosher laws? What are the branches (Orthodox, Reform)? Interesting facts: Based on Torah; one God; 613 mitzvot; emerged 4,000 years ago; Jews, Israelites, Hebrews same; no proselytizing; emphasis on deeds over beliefs; guardian angels in tradition; diverse customs like not climbing trees on Shabbat.
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
============================================================
|
| 74 |
+
Religion: Taoism
|
| 75 |
+
============================================================
|
| 76 |
+
|
| 77 |
+
Description: Taoism (Daoism) is an indigenous Chinese tradition over 2,000 years old, emphasizing harmony with the Tao (the Way), a fundamental force underlying reality. It balances yielding, joyful attitudes with metaphysical exploration, influencing Asian cultures through philosophy, religion, and folk practices.
|
| 78 |
+
|
| 79 |
+
Practices: Practices include meditation (for inner harmony), tai chi (movement for energy flow), wu wei (effortless action), simplicity in living, and rituals like Tao worship or alchemy. Religious aspects involve priestly ceremonies; philosophical focus on contemplation. Blends with Confucianism and Buddhism in folk traditions.
|
| 80 |
+
|
| 81 |
+
Core Beliefs: Core beliefs: Tao as the natural order, yin-yang balance (complementary forces), harmony with nature, metaphysical engagement. Texts: Tao Te Ching, Zhuangzi. Variations: philosophical (mystical ideas) vs. religious (ritual worship). Rejects ego-dissolution, affirms reality's nature.
|
| 82 |
+
|
| 83 |
+
Common Questions: Common questions: What is the Tao? Who was Lao Tzu? Is Taoism a religion or philosophy? What is wu wei? How to apply Taoism daily? Interesting facts: Over 2,000 years old; influences Chinese medicine; yin-yang symbol; no absolutes; monasteries called Gong and Guan; ethics based on charity, thrift; Tao indefinable; self-cultivation goal.
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
============================================================
|
| 88 |
+
Religion: Modern Paganism
|
| 89 |
+
============================================================
|
| 90 |
+
|
| 91 |
+
Description: Modern Paganism (Neopaganism) is a contemporary revival of pre-Christian, nature-based spiritualities, emerging in the 20th century amid environmental and feminist movements. It honors ancient traditions while adapting to modern contexts, emphasizing sacredness in nature and personal empowerment, with diverse, decentralized communities worldwide.
|
| 92 |
+
|
| 93 |
+
Practices: Practices include seasonal celebrations (solstices, equinoxes), rituals (circle casting, offerings), nature work (environmental activism, herbalism), divination (tarot, runes), and meditation. Group covens or solitary paths; festivals like Beltane. Eclectic, drawing from Celtic, Norse, or Wiccan traditions.
|
| 94 |
+
|
| 95 |
+
Core Beliefs: Beliefs: Nature as sacred, polytheism or pantheism (multiple deities or divine in all), cycles of life/death/rebirth, personal responsibility, magic as natural force. Rejects dogma; emphasizes harmony, diversity, and ethical living. Variations: Wicca (witchcraft-focused), Druidry (Celtic-inspired), Heathenry (Norse).
|
| 96 |
+
|
| 97 |
+
Common Questions: Common questions: What is Paganism? Is it witchcraft? Do Pagans worship Satan? How does it differ from ancient paganism? Interesting facts: Umbrella term for non-mainstream religions; revival, not continuous; includes Wicca, Druidry; nature-centric; no central authority; eclectic practices; influenced by 19th-20th century movements; celebrates Wheel of the Year; rejects dogma; modern invention with ancient inspirations.
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
============================================================
|
| 102 |
+
Religion: Secular Humanism
|
| 103 |
+
============================================================
|
| 104 |
+
|
| 105 |
+
Description: Secular Humanism is a modern ethical philosophy emphasizing human reason, values, and dignity without supernatural beliefs, rooted in Renaissance humanism but distinct in its non-theistic focus. It promotes rational inquiry, science, and social justice as paths to fulfillment and societal improvement.
|
| 106 |
+
|
| 107 |
+
Practices: Practices include critical thinking (evidence-based decision-making), ethical living (compassion, justice), community service (volunteering, activism), and secular ceremonies (humanist weddings, namings). Education and dialogue foster personal growth; no rituals, but celebrations of life milestones.
|
| 108 |
+
|
| 109 |
+
Core Beliefs: Beliefs: Human dignity and potential, reason and science as guides, secular ethics (morality from empathy, not divine command), rejection of supernaturalism. Anthropocentric focus on this life; variations like pragmatic or Christian humanism, but secular emphasizes autonomy and progress.
|
| 110 |
+
|
| 111 |
+
Common Questions: Common questions: Is humanism a religion? What is secularism? Why focus on reason? Can humanists have morals without God? Interesting facts: Man-centered ethics; no supernatural; based on naturalism; promotes science; history from Renaissance; emphasizes human agency; not anti-religion but non-theistic; goal is self-remediation; positive worldview.
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
============================================================
|
| 116 |
+
Religion: Atheism
|
| 117 |
+
============================================================
|
| 118 |
+
|
| 119 |
+
Description: Atheism is the absence of belief in gods or spiritual beings, emphasizing empirical evidence and rational critique of metaphysical claims. It promotes a naturalistic worldview focused on human experience and ethics, often in opposition to religious doctrines, with historical roots in philosophy and science.
|
| 120 |
+
|
| 121 |
+
Practices: Practices involve evidence-based thinking (scientific inquiry, skepticism), secular community (atheist groups, discussions), and ethical activism (human rights, separation of church/state). No rituals; focus on rational discourse, education, and living meaningfully without faith.
|
| 122 |
+
|
| 123 |
+
Core Beliefs: Beliefs: No gods exist (or low probability), natural explanations for phenomena, focus on this life. Rejects spiritual beings; variations: fallibilistic (open to evidence), incoherence-based (God concepts illogical). Emphasizes burden of proof on theists, empirical reliability.
|
| 124 |
+
|
| 125 |
+
Common Questions: Common questions: Why no God? Where does morality come from? Do atheists have faith? What about afterlife? Why be moral? Interesting facts: Not a religion, lack of belief; mostly men and young in U.S.; 98% say religion unimportant; doubled in popularity; face discrimination; symbol is atomic whirl; no founder; can pray (meditate); smarter on average per some studies.
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
============================================================
|
| 130 |
+
Religion: Agnosticism
|
| 131 |
+
============================================================
|
| 132 |
+
|
| 133 |
+
Description: Agnosticism holds that the existence of gods or ultimate realities is unknowable, prioritizing evidence and reason while suspending judgment on metaphysical claims. Coined by T.H. Huxley in 1869, it fosters intellectual humility amid scientific and philosophical debates.
|
| 134 |
+
|
| 135 |
+
Practices: Practices include rigorous inquiry (following evidence, Clifford's ethics against insufficient belief), critical reflection (questioning claims), and openness to data. No formal rituals; involves ethical living based on reason, potentially contemplative for personal growth.
|
| 136 |
+
|
| 137 |
+
Core Beliefs: Beliefs: Unknowability of gods/transcendent realities, method over creed (pursue reason, recognize limits). Variations: secular (nonreligious skepticism), religious (minimal doctrine with evidence), philosophical (Hume/Kant unknowables). Distinguishes from atheism by not denying, but suspending belief.
|
| 138 |
+
|
| 139 |
+
Common Questions: Common questions: How differs from atheism? Can agnostics be religious? Is it a middle ground? What after death? Interesting facts: Absence of knowledge about gods; coined 1869; honest approach to big questions; can overlap with atheism; views existence as unknowable; promotes humility; no certain evidence for gods; kids' view: 'not sure' about big questions.
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
============================================================
|
| 144 |
+
Religion: New Age Spirituality
|
| 145 |
+
============================================================
|
| 146 |
+
|
| 147 |
+
Description: New Age Spirituality is an eclectic movement from the 1970s-80s, blending esotericism, theosophy, and mysticism to anticipate an era of peace through personal transformation. Rooted in 19th-century theosophy, it promotes holistic growth and global awakening, influencing wellness and alternative therapies.
|
| 148 |
+
|
| 149 |
+
Practices: Practices include meditation (energy work, channeling), energy healing (crystals, reiki), yoga, astrology, and rituals (affirmations, vision boards). Eclectic: tarot, shamanism, nature communion. Focus on self-transformation and sharing divine energy.
|
| 150 |
+
|
| 151 |
+
Core Beliefs: Beliefs: Imminent New Age of enlightenment (Aquarian shift), personal spiritual transformation (sadhana path), interconnectedness, reincarnation, Ascended Masters. Variations: theosophical (Maitreya focus), psychedelic-influenced. Emphasizes active manifestation over passive waiting.
|
| 152 |
+
|
| 153 |
+
Common Questions: Common questions: What is channeling? Why use crystals? Is yoga New Age? Do they believe in reincarnation? What is the Aquarian Age? Interesting facts: Umbrella for contemporary movement; not organized religion; planetary transformation; integrates astrology, tarot; spiritual healing; influenced by Western esotericism; emblematic universities like Naropa; focuses on human potential.
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
============================================================
|
| 158 |
+
Religion: Spiritual But Not Religious
|
| 159 |
+
============================================================
|
| 160 |
+
|
| 161 |
+
Description: Spiritual But Not Religious (SBNR) is a stance prioritizing personal spirituality over organized religion, focusing on individual well-being and exploration. Emerging in the 1960s-2000s amid deinstitutionalization, it appeals to unaffiliated seekers valuing autonomy and eclecticism.
|
| 162 |
+
|
| 163 |
+
Practices: Practices include meditation (mindfulness, TM), nature connection, eclectic rituals (Tarot, I Ching), and self-reflection. Therapeutic: yoga, journaling for emotional support. Avoids communal worship; experimental and as-needed.
|
| 164 |
+
|
| 165 |
+
Core Beliefs: Beliefs: Spirituality as private empowerment, anti-dogmatic (religion as rigid), focus on mind-body-spirit harmony. Variations: dissenters (reject religion), explorers (wanderlust), seekers (looking for home). Emphasizes curiosity, intellectual freedom, personal path.
|
| 166 |
+
|
| 167 |
+
Common Questions: Common questions: What does SBNR mean? Do they believe in God? Why reject religion? What practices? Interesting facts: Connected to true self; most Americans spiritual; addresses evil/misery; values ethical values; personal divine experience; anti-dogma; hunger for ritual without structure; integrates with other beliefs.
|
| 168 |
+
|
| 169 |
+
|
| 170 |
+
|
| 171 |
+
============================================================
|
| 172 |
+
Religion: Sikhism
|
| 173 |
+
============================================================
|
| 174 |
+
|
| 175 |
+
Description: Sikhism is a monotheistic faith founded by Guru Nanak in 15th-century Punjab, emphasizing equality, service, and devotion. With 25 million adherents, it follows 10 Gurus' teachings, now in the Guru Granth Sahib, promoting ethical living and community amid historical independence from Hinduism.
|
| 176 |
+
|
| 177 |
+
Practices: Practices include daily prayer/meditation (Nitnem), community service (seva), langar (free meals), wearing 5 Ks (kesh, kangha, kara, kachera, kirpan), and gurdwara attendance. Festivals: Vaisakhi, Diwali. Focus on honest living and sharing.
|
| 178 |
+
|
| 179 |
+
Core Beliefs: Beliefs: One formless God, equality of all, Gurmat (Guru's way), liberation via devotion, rejection of caste/rituals. Scriptures: Guru Granth Sahib. Influences: Sant (nirgun devotion), Nath (meditation ascent). Emphasizes ethical monotheism, service.
|
| 180 |
+
|
| 181 |
+
Common Questions: Common questions: What do Sikhs teach about other religions? Who are the Gurus? Why wear turbans/5 Ks? What is langar? Interesting facts: Founded 1469 by Guru Nanak; 27 million followers; originated in Punjab; equality of men/women; no caste; daily prayer; emblem Khanda; greets with Sat Sri Akal; emphasizes humanity and charity.
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
|
| 185 |
+
============================================================
|
| 186 |
+
Religion: Indigenous Spirituality
|
| 187 |
+
============================================================
|
| 188 |
+
|
| 189 |
+
Description: Indigenous Spirituality encompasses diverse traditional beliefs of native peoples worldwide, deeply connected to land, ancestors, and nature. Rooted in ancient oral histories, it emphasizes holistic well-being, resilience, and reciprocity, varying by community but sharing themes of interconnectedness and cultural identity.
|
| 190 |
+
|
| 191 |
+
Practices: Practices include ceremonies (sweat lodges, vision quests), storytelling, seasonal rituals (harvest dances), and healing (herbal medicine, shamanic journeys). Community-focused: elder guidance, sacred sites pilgrimage. Emphasizes respect for nature and ancestors.
|
| 192 |
+
|
| 193 |
+
Core Beliefs: Beliefs: Interconnectedness of all (humans, animals, spirits), land as sacred, ancestor veneration, balance/harmony. Variations: Native American (Great Spirit, totemism), Aboriginal (Dreamtime, kinship). Holistic: mind-body-spirit integration; resilience through cultural practices.
|
| 194 |
+
|
| 195 |
+
Common Questions: Common questions: What is Indigenous spirituality? Do they have a Great Spirit? How linked to land? Myths about 'having it easy'? Interesting facts: Diverse, no single belief; spirituality in daily life; no division spiritual/secular; kinship with nature; ceremonies vary by tribe; addresses appropriation; hunger for rituals; combined with other faiths sometimes.
|
| 196 |
+
|
requirements.txt
CHANGED
|
@@ -2,6 +2,3 @@
|
|
| 2 |
Flask>=2.0.0
|
| 3 |
python-dotenv>=0.19.0
|
| 4 |
together>=0.2.0
|
| 5 |
-
gunicorn>=21.0.0
|
| 6 |
-
openai>=1.0.0
|
| 7 |
-
firebase-admin>=6.0.0
|
|
|
|
| 2 |
Flask>=2.0.0
|
| 3 |
python-dotenv>=0.19.0
|
| 4 |
together>=0.2.0
|
|
|
|
|
|
|
|
|
static/design-tokens.css
DELETED
|
@@ -1,79 +0,0 @@
|
|
| 1 |
-
:root {
|
| 2 |
-
/* π¨ Primary Colors */
|
| 3 |
-
--primary-dark: #3D3D3D;
|
| 4 |
-
--primary-black: #1A1A1A;
|
| 5 |
-
--primary-light: #6B7280;
|
| 6 |
-
|
| 7 |
-
/* Neutral Colors */
|
| 8 |
-
--bg-gray: #F5F5F5;
|
| 9 |
-
--bg-white: #FFFFFF;
|
| 10 |
-
--bg-surface-alt: #FAFAFA;
|
| 11 |
-
--border-divider: #E9ECEF;
|
| 12 |
-
|
| 13 |
-
/* Semantic Colors */
|
| 14 |
-
--background-color-1:rgb(84, 96, 235);
|
| 15 |
-
--background-color-2:rgb(151, 119, 249);
|
| 16 |
-
--success: #10B981;
|
| 17 |
-
--warning: #F59E0B;
|
| 18 |
-
--error: #EF4444;
|
| 19 |
-
--info: #6366F1;
|
| 20 |
-
|
| 21 |
-
/* Result Ranking Colors */
|
| 22 |
-
--rank-1: #FEF3C7;
|
| 23 |
-
--rank-2: #DBEAFE;
|
| 24 |
-
--rank-3: #D1FAE5;
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
/* Text Colors */
|
| 28 |
-
--text-primary: #3D3D3D;
|
| 29 |
-
--text-secondary: #6B7280;
|
| 30 |
-
--text-tertiary: #9CA3AF;
|
| 31 |
-
--text-inverse: #FFFFFF;
|
| 32 |
-
|
| 33 |
-
/* π Typography */
|
| 34 |
-
--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
| 35 |
-
|
| 36 |
-
--font-size-sm: 0.875rem; /* 14px */
|
| 37 |
-
--font-size-base: 1rem; /* 16px */
|
| 38 |
-
--font-size-lg: 1.125rem; /* 18px */
|
| 39 |
-
--font-size-xl: 1.25rem; /* 20px */
|
| 40 |
-
--font-size-2xl: 1.375rem; /* 22px */
|
| 41 |
-
--font-size-3xl: 2rem; /* 24px */
|
| 42 |
-
--font-size-4xl: 3rem; /* 28px */
|
| 43 |
-
|
| 44 |
-
--font-weight-regular: 400;
|
| 45 |
-
--font-weight-medium: 600;
|
| 46 |
-
--font-weight-bold: 700;
|
| 47 |
-
--font-weight-extrabold: 800;
|
| 48 |
-
|
| 49 |
-
/* π Spacing System (4px base unit) */
|
| 50 |
-
--space-xs: 0.5rem; /* 8px */
|
| 51 |
-
--space-sm: 0.75rem; /* 12px */
|
| 52 |
-
--space-md: 1rem; /* 16px */
|
| 53 |
-
--space-lg: 1.25rem; /* 20px */
|
| 54 |
-
--space-xl: 1.5rem; /* 24px */
|
| 55 |
-
--space-2xl: 2rem; /* 32px */
|
| 56 |
-
--space-3xl: 2.5rem; /* 40px */
|
| 57 |
-
--space-4xl: 3rem; /* 48px */
|
| 58 |
-
|
| 59 |
-
/* π² Border Radius */
|
| 60 |
-
--radius-sm: 8px;
|
| 61 |
-
--radius-md: 10px;
|
| 62 |
-
--radius-lg: 12px;
|
| 63 |
-
--radius-xl: 16px;
|
| 64 |
-
--radius-full: 50%;
|
| 65 |
-
|
| 66 |
-
/* π Shadows */
|
| 67 |
-
--shadow-sm: 0 2px 6px rgba(0, 0, 0, 0.04);
|
| 68 |
-
--shadow-md: 0 2px 8px rgba(0, 0, 0, 0.06);
|
| 69 |
-
--shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.08);
|
| 70 |
-
--shadow-xl: 0 4px 20px rgba(0, 0, 0, 0.08);
|
| 71 |
-
|
| 72 |
-
/* π Transitions */
|
| 73 |
-
--transition-fast: 0.2s;
|
| 74 |
-
--transition-base: 0.3s;
|
| 75 |
-
--transition-slow: 0.4s;
|
| 76 |
-
|
| 77 |
-
/* π± Breakpoints */
|
| 78 |
-
--breakpoint-mobile: 768px;
|
| 79 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static/images/Abstract Color Gradient.png
DELETED
Git LFS Details
|
static/images/icon1.png
DELETED
Git LFS Details
|
static/images/icon3.png
DELETED
Git LFS Details
|
static/landing.css
CHANGED
|
@@ -1,150 +1,142 @@
|
|
| 1 |
-
@import url('design-tokens.css');
|
| 2 |
-
|
| 3 |
-
/* ==========================================================================
|
| 4 |
-
RESET & BASE STYLES
|
| 5 |
-
========================================================================== */
|
| 6 |
-
|
| 7 |
* {
|
| 8 |
margin: 0;
|
| 9 |
padding: 0;
|
| 10 |
box-sizing: border-box;
|
| 11 |
}
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
body {
|
| 14 |
-
font-family:
|
| 15 |
line-height: 1.6;
|
| 16 |
-
color: var(--text-
|
| 17 |
-
background:
|
| 18 |
overflow-x: hidden;
|
| 19 |
}
|
| 20 |
|
| 21 |
-
/*
|
| 22 |
-
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
@keyframes gradientShift {
|
| 26 |
0%, 100% { transform: scale(1) rotate(0deg); }
|
| 27 |
50% { transform: scale(1.1) rotate(5deg); }
|
| 28 |
}
|
| 29 |
|
| 30 |
-
|
| 31 |
-
from {
|
| 32 |
-
opacity: 0;
|
| 33 |
-
transform: translateY(30px);
|
| 34 |
-
}
|
| 35 |
-
to {
|
| 36 |
-
opacity: 1;
|
| 37 |
-
transform: translateY(0);
|
| 38 |
-
}
|
| 39 |
-
}
|
| 40 |
-
|
| 41 |
-
/* ==========================================================================
|
| 42 |
-
NAVIGATION
|
| 43 |
-
========================================================================== */
|
| 44 |
-
|
| 45 |
.navbar {
|
| 46 |
position: fixed;
|
| 47 |
top: 0;
|
| 48 |
left: 0;
|
| 49 |
right: 0;
|
| 50 |
-
background: rgba(255, 255, 255, 0);
|
| 51 |
backdrop-filter: blur(10px);
|
| 52 |
-
border-bottom: 1px solid
|
| 53 |
z-index: 1000;
|
| 54 |
-
padding:
|
| 55 |
}
|
| 56 |
|
| 57 |
.nav-container {
|
| 58 |
max-width: 1200px;
|
| 59 |
margin: 0 auto;
|
| 60 |
-
padding: 0
|
| 61 |
display: flex;
|
| 62 |
justify-content: space-between;
|
| 63 |
align-items: center;
|
| 64 |
}
|
| 65 |
|
| 66 |
.logo {
|
| 67 |
-
font-size:
|
| 68 |
-
font-weight:
|
| 69 |
-
color: var(--text-
|
| 70 |
}
|
| 71 |
|
| 72 |
.nav-cta {
|
| 73 |
-
padding:
|
| 74 |
-
background: var(--primary
|
| 75 |
-
color:
|
| 76 |
text-decoration: none;
|
| 77 |
-
border-radius:
|
| 78 |
-
font-weight:
|
| 79 |
-
font-size:
|
| 80 |
-
transition: all
|
| 81 |
}
|
| 82 |
|
| 83 |
.nav-cta:hover {
|
| 84 |
background: var(--primary-dark);
|
| 85 |
transform: translateY(-2px);
|
| 86 |
-
box-shadow:
|
| 87 |
}
|
| 88 |
|
| 89 |
-
/*
|
| 90 |
-
|
| 91 |
-
|
|
|
|
| 92 |
|
|
|
|
| 93 |
.hero-section {
|
| 94 |
-
padding:
|
| 95 |
text-align: center;
|
| 96 |
position: relative;
|
| 97 |
-
min-height: 100vh;
|
| 98 |
-
display: flex;
|
| 99 |
-
align-items: center;
|
| 100 |
-
overflow: hidden;
|
| 101 |
-
background: transparent;
|
| 102 |
}
|
| 103 |
|
| 104 |
.hero-container {
|
| 105 |
max-width: 1000px;
|
| 106 |
margin: 0 auto;
|
| 107 |
-
position: relative;
|
| 108 |
-
z-index: 1;
|
| 109 |
-
}
|
| 110 |
-
|
| 111 |
-
.hero-video {
|
| 112 |
-
position: fixed;
|
| 113 |
-
top: 0;
|
| 114 |
-
left: 0;
|
| 115 |
-
width: 100vw;
|
| 116 |
-
height: 100vh;
|
| 117 |
-
object-fit: cover;
|
| 118 |
-
z-index: -1;
|
| 119 |
-
background: #fff;
|
| 120 |
-
opacity: .4;
|
| 121 |
-
visibility: visible;
|
| 122 |
}
|
| 123 |
|
| 124 |
.badge {
|
| 125 |
display: inline-block;
|
| 126 |
-
padding:
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
|
|
|
|
|
|
|
|
|
| 131 |
animation: fadeInUp 0.6s ease;
|
| 132 |
}
|
| 133 |
|
| 134 |
.hero-title {
|
| 135 |
font-size: 4.5rem;
|
| 136 |
-
font-weight:
|
| 137 |
line-height: 1.1;
|
| 138 |
-
margin-bottom:
|
| 139 |
-
color: var(--text-
|
| 140 |
animation: fadeInUp 0.6s ease 0.1s both;
|
| 141 |
}
|
| 142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
.hero-subtitle {
|
| 144 |
-
font-size:
|
| 145 |
-
color: var(--text-
|
| 146 |
-
max-width:
|
| 147 |
-
margin: 0 auto
|
| 148 |
line-height: 1.8;
|
| 149 |
animation: fadeInUp 0.6s ease 0.2s both;
|
| 150 |
}
|
|
@@ -153,194 +145,243 @@ body {
|
|
| 153 |
animation: fadeInUp 0.6s ease 0.3s both;
|
| 154 |
}
|
| 155 |
|
| 156 |
-
.
|
| 157 |
-
display: flex;
|
| 158 |
-
justify-content: center;
|
| 159 |
-
gap: var(--space-2xl);
|
| 160 |
-
margin-top: var(--space-2xl);
|
| 161 |
-
font-size: var(--font-size-sm);
|
| 162 |
-
color: var(--text-secondary);
|
| 163 |
-
}
|
| 164 |
-
|
| 165 |
-
/* ==========================================================================
|
| 166 |
-
BUTTONS
|
| 167 |
-
========================================================================== */
|
| 168 |
-
|
| 169 |
-
.btn-primary {
|
| 170 |
display: inline-flex;
|
| 171 |
align-items: center;
|
| 172 |
-
gap:
|
| 173 |
-
padding:
|
| 174 |
-
font-size:
|
| 175 |
-
font-weight:
|
| 176 |
text-decoration: none;
|
| 177 |
-
border-radius:
|
| 178 |
-
transition: all
|
| 179 |
cursor: pointer;
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
|
|
|
|
|
|
|
|
|
| 183 |
}
|
| 184 |
|
| 185 |
.btn-primary:hover {
|
| 186 |
-
|
| 187 |
-
box-shadow:
|
| 188 |
}
|
| 189 |
|
| 190 |
.btn-primary .arrow {
|
| 191 |
-
transition: transform
|
| 192 |
}
|
| 193 |
|
| 194 |
.btn-primary:hover .arrow {
|
| 195 |
transform: translateX(5px);
|
| 196 |
}
|
| 197 |
|
| 198 |
-
|
| 199 |
-
FEATURES SECTION
|
| 200 |
-
========================================================================== */
|
| 201 |
-
|
| 202 |
-
/* .features-section {
|
| 203 |
-
width: 100vw;
|
| 204 |
-
min-height: 100vh;
|
| 205 |
-
background: url("images/Abstract%20Color%20Gradient.png") center/cover no-repeat;
|
| 206 |
display: flex;
|
| 207 |
-
align-items: center;
|
| 208 |
justify-content: center;
|
| 209 |
-
|
| 210 |
-
|
|
|
|
|
|
|
|
|
|
| 211 |
|
| 212 |
-
/*
|
| 213 |
-
.
|
| 214 |
-
|
| 215 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
display: flex;
|
| 217 |
align-items: center;
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 238 |
}
|
| 239 |
|
| 240 |
.section-container {
|
| 241 |
max-width: 1200px;
|
| 242 |
margin: 0 auto;
|
| 243 |
-
padding: 0 var(--space-xl);
|
| 244 |
}
|
| 245 |
|
| 246 |
.section-header {
|
| 247 |
text-align: center;
|
| 248 |
-
margin-bottom:
|
| 249 |
}
|
| 250 |
|
| 251 |
.section-header h2 {
|
| 252 |
-
font-size:
|
| 253 |
-
font-weight:
|
| 254 |
-
color: var(--text-
|
| 255 |
-
margin-bottom:
|
| 256 |
-
}
|
| 257 |
-
|
| 258 |
-
.section-subtitle {
|
| 259 |
-
font-size: var(--font-size-xl); /* same as hero-subtitle */
|
| 260 |
-
color: var(--text-primary); /* hero uses primary */
|
| 261 |
-
max-width: 600px; /* hero-subtitle width */
|
| 262 |
-
margin: 0 auto var(--space-4xl); /* centered, comfortable bottom space */
|
| 263 |
-
line-height: 1.8; /* easier reading like hero */
|
| 264 |
-
animation: fadeInUp 0.6s ease 0.2s both; /* subtle entrance like hero */
|
| 265 |
}
|
| 266 |
|
| 267 |
.section-header p {
|
| 268 |
-
font-size:
|
| 269 |
-
color: var(--text-
|
| 270 |
}
|
| 271 |
|
| 272 |
.features-grid {
|
| 273 |
display: grid;
|
| 274 |
-
grid-template-columns: repeat(
|
| 275 |
-
gap:
|
| 276 |
-
justify-items: center;
|
| 277 |
}
|
| 278 |
|
| 279 |
.feature-card {
|
| 280 |
-
background:
|
| 281 |
-
padding:
|
| 282 |
-
border-radius:
|
| 283 |
-
box-shadow:
|
| 284 |
-
transition: all
|
| 285 |
}
|
| 286 |
|
| 287 |
.feature-card:hover {
|
| 288 |
transform: translateY(-8px);
|
| 289 |
-
box-shadow:
|
| 290 |
}
|
| 291 |
|
| 292 |
-
.feature-icon-
|
| 293 |
-
width:
|
| 294 |
-
height:
|
| 295 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
}
|
| 297 |
|
| 298 |
.feature-card h3 {
|
| 299 |
-
font-size:
|
| 300 |
-
font-weight:
|
| 301 |
-
color: var(--text-
|
| 302 |
-
margin-bottom:
|
| 303 |
}
|
| 304 |
|
| 305 |
.feature-card p {
|
| 306 |
-
color: var(--text-
|
| 307 |
line-height: 1.8;
|
| 308 |
}
|
| 309 |
|
| 310 |
-
/*
|
| 311 |
-
CTA SECTION
|
| 312 |
-
========================================================================== */
|
| 313 |
-
|
| 314 |
.cta-section {
|
| 315 |
-
|
| 316 |
-
display: flex;
|
| 317 |
-
align-items: center;
|
| 318 |
-
justify-content: center;
|
| 319 |
text-align: center;
|
| 320 |
-
|
|
|
|
| 321 |
}
|
| 322 |
|
| 323 |
.cta-container h2 {
|
| 324 |
-
font-size:
|
| 325 |
-
font-weight:
|
| 326 |
-
margin-bottom:
|
| 327 |
-
color: var(--text-primary);
|
| 328 |
}
|
| 329 |
|
| 330 |
.cta-container p {
|
| 331 |
-
font-size:
|
| 332 |
-
margin-bottom:
|
| 333 |
-
|
| 334 |
}
|
| 335 |
|
| 336 |
-
|
| 337 |
-
|
| 338 |
-
|
|
|
|
| 339 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 340 |
.footer {
|
| 341 |
-
background: var(--
|
| 342 |
-
color:
|
| 343 |
-
padding:
|
| 344 |
text-align: center;
|
| 345 |
}
|
| 346 |
|
|
@@ -353,172 +394,62 @@ body {
|
|
| 353 |
opacity: 0.7;
|
| 354 |
}
|
| 355 |
|
| 356 |
-
/*
|
| 357 |
-
RESPONSIVE DESIGN
|
| 358 |
-
========================================================================== */
|
| 359 |
-
|
| 360 |
-
/* Tablet and smaller desktop */
|
| 361 |
@media (max-width: 1024px) {
|
| 362 |
-
.hero-
|
| 363 |
-
|
| 364 |
}
|
| 365 |
|
| 366 |
-
.
|
| 367 |
-
|
| 368 |
-
|
| 369 |
}
|
| 370 |
|
| 371 |
-
.
|
| 372 |
-
|
| 373 |
}
|
| 374 |
}
|
| 375 |
|
| 376 |
-
/* Mobile landscape and smaller tablets */
|
| 377 |
@media (max-width: 768px) {
|
| 378 |
.nav-container {
|
| 379 |
-
padding: 0
|
| 380 |
}
|
| 381 |
-
|
| 382 |
.hero-section {
|
| 383 |
-
padding:
|
| 384 |
-
min-height: 100vh;
|
| 385 |
}
|
| 386 |
|
| 387 |
.hero-title {
|
| 388 |
font-size: 2.5rem;
|
| 389 |
-
line-height: 1.2;
|
| 390 |
}
|
| 391 |
|
| 392 |
.hero-subtitle {
|
| 393 |
-
font-size:
|
| 394 |
-
margin: 0 auto var(--space-2xl);
|
| 395 |
}
|
| 396 |
|
| 397 |
.assessment-meta {
|
| 398 |
flex-direction: column;
|
| 399 |
-
gap:
|
| 400 |
-
margin-top: var(--space-xl);
|
| 401 |
-
}
|
| 402 |
-
|
| 403 |
-
.btn-primary {
|
| 404 |
-
padding: var(--space-md) var(--space-xl);
|
| 405 |
-
font-size: var(--font-size-base);
|
| 406 |
-
width: 100%;
|
| 407 |
-
max-width: 300px;
|
| 408 |
-
justify-content: center;
|
| 409 |
}
|
| 410 |
|
| 411 |
-
.
|
| 412 |
-
|
| 413 |
-
min-height: 100vh;
|
| 414 |
-
padding: var(--space-3xl) 0;
|
| 415 |
-
}
|
| 416 |
-
|
| 417 |
-
.section-container {
|
| 418 |
-
padding: 0 var(--space-md);
|
| 419 |
}
|
| 420 |
|
| 421 |
.section-header h2 {
|
| 422 |
-
font-size: var(--font-size-2xl);
|
| 423 |
-
}
|
| 424 |
-
|
| 425 |
-
.section-header p {
|
| 426 |
-
font-size: var(--font-size-lg);
|
| 427 |
-
}
|
| 428 |
-
|
| 429 |
-
.features-grid {
|
| 430 |
-
grid-template-columns: 1fr;
|
| 431 |
-
gap: var(--space-lg);
|
| 432 |
-
}
|
| 433 |
-
|
| 434 |
-
.feature-card {
|
| 435 |
-
padding: var(--space-xl);
|
| 436 |
-
margin: 0 var(--space-sm);
|
| 437 |
-
}
|
| 438 |
-
|
| 439 |
-
.cta-section {
|
| 440 |
-
height: auto;
|
| 441 |
-
min-height: 100vh;
|
| 442 |
-
padding: var(--space-3xl) var(--space-md);
|
| 443 |
-
}
|
| 444 |
-
|
| 445 |
-
.cta-container h2 {
|
| 446 |
-
font-size: var(--font-size-2xl);
|
| 447 |
-
margin-bottom: var(--space-lg);
|
| 448 |
-
}
|
| 449 |
-
|
| 450 |
-
.cta-container p {
|
| 451 |
-
font-size: var(--font-size-lg);
|
| 452 |
-
margin-bottom: var(--space-2xl);
|
| 453 |
-
}
|
| 454 |
-
|
| 455 |
-
.nav-cta {
|
| 456 |
-
padding: var(--space-sm) var(--space-lg);
|
| 457 |
-
font-size: var(--font-size-sm);
|
| 458 |
-
}
|
| 459 |
-
}
|
| 460 |
-
|
| 461 |
-
/* Small mobile devices */
|
| 462 |
-
@media (max-width: 480px) {
|
| 463 |
-
.hero-section {
|
| 464 |
-
padding: 80px var(--space-sm) var(--space-2xl);
|
| 465 |
-
}
|
| 466 |
-
|
| 467 |
-
.hero-title {
|
| 468 |
font-size: 2rem;
|
| 469 |
}
|
| 470 |
|
| 471 |
-
.hero-subtitle {
|
| 472 |
-
font-size: var(--font-size-base);
|
| 473 |
-
}
|
| 474 |
-
|
| 475 |
-
.section-container {
|
| 476 |
-
padding: 0 var(--space-sm);
|
| 477 |
-
}
|
| 478 |
-
|
| 479 |
-
.feature-card {
|
| 480 |
-
padding: var(--space-lg);
|
| 481 |
-
margin: 0;
|
| 482 |
-
}
|
| 483 |
-
|
| 484 |
-
.cta-section {
|
| 485 |
-
padding: var(--space-2xl) var(--space-sm);
|
| 486 |
-
}
|
| 487 |
-
|
| 488 |
.cta-container h2 {
|
| 489 |
-
font-size:
|
| 490 |
-
}
|
| 491 |
-
|
| 492 |
-
.cta-container p {
|
| 493 |
-
font-size: var(--font-size-base);
|
| 494 |
}
|
| 495 |
|
| 496 |
-
.
|
| 497 |
-
|
| 498 |
-
font-size: var(--font-size-sm);
|
| 499 |
}
|
| 500 |
|
| 501 |
-
.
|
| 502 |
-
padding:
|
| 503 |
-
font-size:
|
| 504 |
}
|
| 505 |
}
|
| 506 |
-
|
| 507 |
-
/* Very small mobile devices */
|
| 508 |
-
@media (max-width: 320px) {
|
| 509 |
-
.hero-title {
|
| 510 |
-
font-size: 1.8rem;
|
| 511 |
-
}
|
| 512 |
-
|
| 513 |
-
.hero-subtitle {
|
| 514 |
-
font-size: var(--font-size-sm);
|
| 515 |
-
}
|
| 516 |
-
|
| 517 |
-
.feature-card {
|
| 518 |
-
padding: var(--space-md);
|
| 519 |
-
}
|
| 520 |
-
|
| 521 |
-
.cta-container h2 {
|
| 522 |
-
font-size: var(--font-size-lg);
|
| 523 |
-
}
|
| 524 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
* {
|
| 2 |
margin: 0;
|
| 3 |
padding: 0;
|
| 4 |
box-sizing: border-box;
|
| 5 |
}
|
| 6 |
|
| 7 |
+
:root {
|
| 8 |
+
--primary: #6366f1;
|
| 9 |
+
--primary-dark: #4f46e5;
|
| 10 |
+
--secondary: #8b5cf6;
|
| 11 |
+
--accent: #ec4899;
|
| 12 |
+
--text-dark: #1e293b;
|
| 13 |
+
--text-light: #64748b;
|
| 14 |
+
--bg-white: #ffffff;
|
| 15 |
+
--bg-light: #f8fafc;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
body {
|
| 19 |
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
| 20 |
line-height: 1.6;
|
| 21 |
+
color: var(--text-dark);
|
| 22 |
+
background: var(--bg-white);
|
| 23 |
overflow-x: hidden;
|
| 24 |
}
|
| 25 |
|
| 26 |
+
/* Animated Gradient Background */
|
| 27 |
+
.gradient-bg {
|
| 28 |
+
position: fixed;
|
| 29 |
+
top: 0;
|
| 30 |
+
left: 0;
|
| 31 |
+
width: 100%;
|
| 32 |
+
height: 100vh;
|
| 33 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
|
| 34 |
+
opacity: 0.05;
|
| 35 |
+
z-index: -1;
|
| 36 |
+
animation: gradientShift 15s ease infinite;
|
| 37 |
+
}
|
| 38 |
|
| 39 |
@keyframes gradientShift {
|
| 40 |
0%, 100% { transform: scale(1) rotate(0deg); }
|
| 41 |
50% { transform: scale(1.1) rotate(5deg); }
|
| 42 |
}
|
| 43 |
|
| 44 |
+
/* Navigation */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
.navbar {
|
| 46 |
position: fixed;
|
| 47 |
top: 0;
|
| 48 |
left: 0;
|
| 49 |
right: 0;
|
| 50 |
+
background: rgba(255, 255, 255, 0.8);
|
| 51 |
backdrop-filter: blur(10px);
|
| 52 |
+
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
| 53 |
z-index: 1000;
|
| 54 |
+
padding: 1rem 0;
|
| 55 |
}
|
| 56 |
|
| 57 |
.nav-container {
|
| 58 |
max-width: 1200px;
|
| 59 |
margin: 0 auto;
|
| 60 |
+
padding: 0 2rem;
|
| 61 |
display: flex;
|
| 62 |
justify-content: space-between;
|
| 63 |
align-items: center;
|
| 64 |
}
|
| 65 |
|
| 66 |
.logo {
|
| 67 |
+
font-size: 1.25rem;
|
| 68 |
+
font-weight: 700;
|
| 69 |
+
color: var(--text-dark);
|
| 70 |
}
|
| 71 |
|
| 72 |
.nav-cta {
|
| 73 |
+
padding: 0.625rem 1.5rem;
|
| 74 |
+
background: var(--primary);
|
| 75 |
+
color: white;
|
| 76 |
text-decoration: none;
|
| 77 |
+
border-radius: 8px;
|
| 78 |
+
font-weight: 600;
|
| 79 |
+
font-size: 0.9rem;
|
| 80 |
+
transition: all 0.3s ease;
|
| 81 |
}
|
| 82 |
|
| 83 |
.nav-cta:hover {
|
| 84 |
background: var(--primary-dark);
|
| 85 |
transform: translateY(-2px);
|
| 86 |
+
box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);
|
| 87 |
}
|
| 88 |
|
| 89 |
+
/* Main Content */
|
| 90 |
+
.main-content {
|
| 91 |
+
padding-top: 80px;
|
| 92 |
+
}
|
| 93 |
|
| 94 |
+
/* Hero Section */
|
| 95 |
.hero-section {
|
| 96 |
+
padding: 6rem 2rem 4rem;
|
| 97 |
text-align: center;
|
| 98 |
position: relative;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
}
|
| 100 |
|
| 101 |
.hero-container {
|
| 102 |
max-width: 1000px;
|
| 103 |
margin: 0 auto;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
}
|
| 105 |
|
| 106 |
.badge {
|
| 107 |
display: inline-block;
|
| 108 |
+
padding: 0.5rem 1rem;
|
| 109 |
+
background: linear-gradient(135deg, rgba(99, 102, 241, 0.1), rgba(139, 92, 246, 0.1));
|
| 110 |
+
border: 1px solid rgba(99, 102, 241, 0.2);
|
| 111 |
+
border-radius: 50px;
|
| 112 |
+
font-size: 0.875rem;
|
| 113 |
+
font-weight: 600;
|
| 114 |
+
color: var(--primary);
|
| 115 |
+
margin-bottom: 2rem;
|
| 116 |
animation: fadeInUp 0.6s ease;
|
| 117 |
}
|
| 118 |
|
| 119 |
.hero-title {
|
| 120 |
font-size: 4.5rem;
|
| 121 |
+
font-weight: 800;
|
| 122 |
line-height: 1.1;
|
| 123 |
+
margin-bottom: 1.5rem;
|
| 124 |
+
color: var(--text-dark);
|
| 125 |
animation: fadeInUp 0.6s ease 0.1s both;
|
| 126 |
}
|
| 127 |
|
| 128 |
+
.gradient-text {
|
| 129 |
+
background: linear-gradient(135deg, var(--primary), var(--secondary), var(--accent));
|
| 130 |
+
-webkit-background-clip: text;
|
| 131 |
+
-webkit-text-fill-color: transparent;
|
| 132 |
+
background-clip: text;
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
.hero-subtitle {
|
| 136 |
+
font-size: 1.25rem;
|
| 137 |
+
color: var(--text-light);
|
| 138 |
+
max-width: 700px;
|
| 139 |
+
margin: 0 auto 3rem;
|
| 140 |
line-height: 1.8;
|
| 141 |
animation: fadeInUp 0.6s ease 0.2s both;
|
| 142 |
}
|
|
|
|
| 145 |
animation: fadeInUp 0.6s ease 0.3s both;
|
| 146 |
}
|
| 147 |
|
| 148 |
+
.btn-primary, .btn-secondary {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
display: inline-flex;
|
| 150 |
align-items: center;
|
| 151 |
+
gap: 0.5rem;
|
| 152 |
+
padding: 1rem 2.5rem;
|
| 153 |
+
font-size: 1.125rem;
|
| 154 |
+
font-weight: 600;
|
| 155 |
text-decoration: none;
|
| 156 |
+
border-radius: 12px;
|
| 157 |
+
transition: all 0.3s ease;
|
| 158 |
cursor: pointer;
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
.btn-primary {
|
| 162 |
+
background: linear-gradient(135deg, var(--primary), var(--secondary));
|
| 163 |
+
color: white;
|
| 164 |
+
box-shadow: 0 10px 30px rgba(99, 102, 241, 0.3);
|
| 165 |
}
|
| 166 |
|
| 167 |
.btn-primary:hover {
|
| 168 |
+
transform: translateY(-3px);
|
| 169 |
+
box-shadow: 0 15px 40px rgba(99, 102, 241, 0.4);
|
| 170 |
}
|
| 171 |
|
| 172 |
.btn-primary .arrow {
|
| 173 |
+
transition: transform 0.3s ease;
|
| 174 |
}
|
| 175 |
|
| 176 |
.btn-primary:hover .arrow {
|
| 177 |
transform: translateX(5px);
|
| 178 |
}
|
| 179 |
|
| 180 |
+
.assessment-meta {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
display: flex;
|
|
|
|
| 182 |
justify-content: center;
|
| 183 |
+
gap: 2rem;
|
| 184 |
+
margin-top: 2rem;
|
| 185 |
+
font-size: 0.9rem;
|
| 186 |
+
color: var(--text-light);
|
| 187 |
+
}
|
| 188 |
|
| 189 |
+
/* Hero Visual */
|
| 190 |
+
.hero-visual {
|
| 191 |
+
position: relative;
|
| 192 |
+
height: 400px;
|
| 193 |
+
margin-top: 5rem;
|
| 194 |
+
max-width: 900px;
|
| 195 |
+
margin-left: auto;
|
| 196 |
+
margin-right: auto;
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
.floating-card {
|
| 200 |
+
position: absolute;
|
| 201 |
+
background: white;
|
| 202 |
+
padding: 1.25rem 1.75rem;
|
| 203 |
+
border-radius: 16px;
|
| 204 |
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
|
| 205 |
display: flex;
|
| 206 |
align-items: center;
|
| 207 |
+
gap: 0.75rem;
|
| 208 |
+
animation: float 6s ease-in-out infinite;
|
| 209 |
+
white-space: nowrap;
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
.floating-card .card-icon {
|
| 213 |
+
font-size: 1.75rem;
|
| 214 |
+
flex-shrink: 0;
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
.floating-card .card-text {
|
| 218 |
+
font-weight: 600;
|
| 219 |
+
color: var(--text-dark);
|
| 220 |
+
font-size: 0.95rem;
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
.card-1 {
|
| 224 |
+
left: 5%;
|
| 225 |
+
top: 10%;
|
| 226 |
+
animation-delay: 0s;
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
.card-2 {
|
| 230 |
+
right: 5%;
|
| 231 |
+
top: 50%;
|
| 232 |
+
animation-delay: 2s;
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
.card-3 {
|
| 236 |
+
left: 50%;
|
| 237 |
+
transform: translateX(-50%);
|
| 238 |
+
bottom: 10%;
|
| 239 |
+
animation-delay: 4s;
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
@keyframes float {
|
| 243 |
+
0%, 100% {
|
| 244 |
+
transform: translateY(0px);
|
| 245 |
+
}
|
| 246 |
+
50% {
|
| 247 |
+
transform: translateY(-20px);
|
| 248 |
+
}
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
/* Fix for card-3 animation to maintain centering */
|
| 252 |
+
.card-3 {
|
| 253 |
+
animation: floatCenter 6s ease-in-out infinite;
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
@keyframes floatCenter {
|
| 257 |
+
0%, 100% {
|
| 258 |
+
transform: translate(-50%, 0px);
|
| 259 |
+
}
|
| 260 |
+
50% {
|
| 261 |
+
transform: translate(-50%, -20px);
|
| 262 |
+
}
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
@keyframes fadeInUp {
|
| 266 |
+
from {
|
| 267 |
+
opacity: 0;
|
| 268 |
+
transform: translateY(30px);
|
| 269 |
+
}
|
| 270 |
+
to {
|
| 271 |
+
opacity: 1;
|
| 272 |
+
transform: translateY(0);
|
| 273 |
+
}
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
/* Features Section */
|
| 277 |
+
.features-section {
|
| 278 |
+
padding: 6rem 2rem;
|
| 279 |
+
background: var(--bg-light);
|
| 280 |
}
|
| 281 |
|
| 282 |
.section-container {
|
| 283 |
max-width: 1200px;
|
| 284 |
margin: 0 auto;
|
|
|
|
| 285 |
}
|
| 286 |
|
| 287 |
.section-header {
|
| 288 |
text-align: center;
|
| 289 |
+
margin-bottom: 4rem;
|
| 290 |
}
|
| 291 |
|
| 292 |
.section-header h2 {
|
| 293 |
+
font-size: 3rem;
|
| 294 |
+
font-weight: 800;
|
| 295 |
+
color: var(--text-dark);
|
| 296 |
+
margin-bottom: 1rem;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 297 |
}
|
| 298 |
|
| 299 |
.section-header p {
|
| 300 |
+
font-size: 1.25rem;
|
| 301 |
+
color: var(--text-light);
|
| 302 |
}
|
| 303 |
|
| 304 |
.features-grid {
|
| 305 |
display: grid;
|
| 306 |
+
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
| 307 |
+
gap: 2rem;
|
|
|
|
| 308 |
}
|
| 309 |
|
| 310 |
.feature-card {
|
| 311 |
+
background: white;
|
| 312 |
+
padding: 2.5rem;
|
| 313 |
+
border-radius: 20px;
|
| 314 |
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
|
| 315 |
+
transition: all 0.3s ease;
|
| 316 |
}
|
| 317 |
|
| 318 |
.feature-card:hover {
|
| 319 |
transform: translateY(-8px);
|
| 320 |
+
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.1);
|
| 321 |
}
|
| 322 |
|
| 323 |
+
.feature-icon-wrapper {
|
| 324 |
+
width: 80px;
|
| 325 |
+
height: 80px;
|
| 326 |
+
background: linear-gradient(135deg, rgba(99, 102, 241, 0.1), rgba(139, 92, 246, 0.1));
|
| 327 |
+
border-radius: 20px;
|
| 328 |
+
display: flex;
|
| 329 |
+
align-items: center;
|
| 330 |
+
justify-content: center;
|
| 331 |
+
margin-bottom: 1.5rem;
|
| 332 |
+
}
|
| 333 |
+
|
| 334 |
+
.feature-icon {
|
| 335 |
+
font-size: 2.5rem;
|
| 336 |
}
|
| 337 |
|
| 338 |
.feature-card h3 {
|
| 339 |
+
font-size: 1.5rem;
|
| 340 |
+
font-weight: 700;
|
| 341 |
+
color: var(--text-dark);
|
| 342 |
+
margin-bottom: 1rem;
|
| 343 |
}
|
| 344 |
|
| 345 |
.feature-card p {
|
| 346 |
+
color: var(--text-light);
|
| 347 |
line-height: 1.8;
|
| 348 |
}
|
| 349 |
|
| 350 |
+
/* CTA Section */
|
|
|
|
|
|
|
|
|
|
| 351 |
.cta-section {
|
| 352 |
+
padding: 6rem 2rem;
|
|
|
|
|
|
|
|
|
|
| 353 |
text-align: center;
|
| 354 |
+
background: linear-gradient(135deg, var(--primary), var(--secondary));
|
| 355 |
+
color: white;
|
| 356 |
}
|
| 357 |
|
| 358 |
.cta-container h2 {
|
| 359 |
+
font-size: 3rem;
|
| 360 |
+
font-weight: 800;
|
| 361 |
+
margin-bottom: 1rem;
|
|
|
|
| 362 |
}
|
| 363 |
|
| 364 |
.cta-container p {
|
| 365 |
+
font-size: 1.25rem;
|
| 366 |
+
margin-bottom: 2.5rem;
|
| 367 |
+
opacity: 0.9;
|
| 368 |
}
|
| 369 |
|
| 370 |
+
.btn-secondary {
|
| 371 |
+
background: white;
|
| 372 |
+
color: var(--primary);
|
| 373 |
+
}
|
| 374 |
|
| 375 |
+
.btn-secondary:hover {
|
| 376 |
+
transform: translateY(-3px);
|
| 377 |
+
box-shadow: 0 15px 40px rgba(255, 255, 255, 0.3);
|
| 378 |
+
}
|
| 379 |
+
|
| 380 |
+
/* Footer */
|
| 381 |
.footer {
|
| 382 |
+
background: var(--text-dark);
|
| 383 |
+
color: white;
|
| 384 |
+
padding: 3rem 2rem;
|
| 385 |
text-align: center;
|
| 386 |
}
|
| 387 |
|
|
|
|
| 394 |
opacity: 0.7;
|
| 395 |
}
|
| 396 |
|
| 397 |
+
/* Responsive Design */
|
|
|
|
|
|
|
|
|
|
|
|
|
| 398 |
@media (max-width: 1024px) {
|
| 399 |
+
.hero-visual {
|
| 400 |
+
height: 300px;
|
| 401 |
}
|
| 402 |
|
| 403 |
+
.floating-card {
|
| 404 |
+
padding: 1rem 1.5rem;
|
| 405 |
+
font-size: 0.85rem;
|
| 406 |
}
|
| 407 |
|
| 408 |
+
.floating-card .card-icon {
|
| 409 |
+
font-size: 1.5rem;
|
| 410 |
}
|
| 411 |
}
|
| 412 |
|
|
|
|
| 413 |
@media (max-width: 768px) {
|
| 414 |
.nav-container {
|
| 415 |
+
padding: 0 1rem;
|
| 416 |
}
|
| 417 |
+
|
| 418 |
.hero-section {
|
| 419 |
+
padding: 4rem 1rem 3rem;
|
|
|
|
| 420 |
}
|
| 421 |
|
| 422 |
.hero-title {
|
| 423 |
font-size: 2.5rem;
|
|
|
|
| 424 |
}
|
| 425 |
|
| 426 |
.hero-subtitle {
|
| 427 |
+
font-size: 1.1rem;
|
|
|
|
| 428 |
}
|
| 429 |
|
| 430 |
.assessment-meta {
|
| 431 |
flex-direction: column;
|
| 432 |
+
gap: 0.5rem;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 433 |
}
|
| 434 |
|
| 435 |
+
.hero-visual {
|
| 436 |
+
display: none;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 437 |
}
|
| 438 |
|
| 439 |
.section-header h2 {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 440 |
font-size: 2rem;
|
| 441 |
}
|
| 442 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 443 |
.cta-container h2 {
|
| 444 |
+
font-size: 2rem;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 445 |
}
|
| 446 |
|
| 447 |
+
.features-grid {
|
| 448 |
+
grid-template-columns: 1fr;
|
|
|
|
| 449 |
}
|
| 450 |
|
| 451 |
+
.btn-primary, .btn-secondary {
|
| 452 |
+
padding: 0.875rem 2rem;
|
| 453 |
+
font-size: 1rem;
|
| 454 |
}
|
| 455 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static/script.js
CHANGED
|
@@ -3,218 +3,33 @@ function sanitizeReligionName(name) {
|
|
| 3 |
return name.replace(/\s+/g, '-');
|
| 4 |
}
|
| 5 |
|
| 6 |
-
// ==================== FIREBASE AUTHENTICATION ====================
|
| 7 |
-
|
| 8 |
-
// Google Sign-In with Firebase
|
| 9 |
-
async function signInWithGoogle() {
|
| 10 |
-
if (!window.firebaseEnabled || !window.firebaseAuth) {
|
| 11 |
-
const resultDiv = document.getElementById('result');
|
| 12 |
-
if (resultDiv) {
|
| 13 |
-
resultDiv.innerHTML = '<p class="error-msg">β οΈ Firebase not configured</p>';
|
| 14 |
-
}
|
| 15 |
-
return;
|
| 16 |
-
}
|
| 17 |
-
|
| 18 |
-
const provider = new firebase.auth.GoogleAuthProvider();
|
| 19 |
-
|
| 20 |
-
// Configure provider for better popup behavior
|
| 21 |
-
provider.setCustomParameters({
|
| 22 |
-
prompt: 'select_account' // Always show account selection
|
| 23 |
-
});
|
| 24 |
-
|
| 25 |
-
try {
|
| 26 |
-
// Show loading state
|
| 27 |
-
const resultDiv = document.getElementById('result');
|
| 28 |
-
if (resultDiv) {
|
| 29 |
-
resultDiv.innerHTML = '<p style="color: #666;">Opening sign-in window...</p>';
|
| 30 |
-
}
|
| 31 |
-
|
| 32 |
-
const result = await window.firebaseAuth.signInWithPopup(provider);
|
| 33 |
-
const user = result.user;
|
| 34 |
-
|
| 35 |
-
if (resultDiv) {
|
| 36 |
-
resultDiv.innerHTML = '<p style="color: #666;">Signing in...</p>';
|
| 37 |
-
}
|
| 38 |
-
|
| 39 |
-
// Get ID token to send to backend
|
| 40 |
-
const idToken = await user.getIdToken();
|
| 41 |
-
|
| 42 |
-
// Send to backend for session creation
|
| 43 |
-
const endpoint = window.location.pathname === '/signup' ? '/signup' : '/login';
|
| 44 |
-
const response = await fetch(endpoint, {
|
| 45 |
-
method: 'POST',
|
| 46 |
-
headers: {'Content-Type': 'application/json'},
|
| 47 |
-
body: JSON.stringify({idToken}),
|
| 48 |
-
credentials: 'same-origin'
|
| 49 |
-
});
|
| 50 |
-
|
| 51 |
-
const data = await response.json();
|
| 52 |
-
|
| 53 |
-
if (data.success) {
|
| 54 |
-
window.location.href = '/assessment';
|
| 55 |
-
} else {
|
| 56 |
-
const resultDiv = document.getElementById('result');
|
| 57 |
-
if (resultDiv) {
|
| 58 |
-
resultDiv.innerHTML = `<p class="error-msg">${data.message || 'Authentication failed'}</p>`;
|
| 59 |
-
}
|
| 60 |
-
}
|
| 61 |
-
} catch (error) {
|
| 62 |
-
console.error('Google Sign-In Error:', error);
|
| 63 |
-
console.error('Error code:', error.code);
|
| 64 |
-
console.error('Error details:', error);
|
| 65 |
-
|
| 66 |
-
const resultDiv = document.getElementById('result');
|
| 67 |
-
let errorMsg = '';
|
| 68 |
-
|
| 69 |
-
// Handle specific error cases
|
| 70 |
-
if (error.code === 'auth/popup-closed-by-user') {
|
| 71 |
-
errorMsg = 'β Sign-in window was closed. Please try again and complete the sign-in process.';
|
| 72 |
-
} else if (error.code === 'auth/popup-blocked') {
|
| 73 |
-
errorMsg = 'β Pop-up was blocked by your browser. Please allow pop-ups for this site and try again.';
|
| 74 |
-
} else if (error.code === 'auth/cancelled-popup-request') {
|
| 75 |
-
errorMsg = 'β Another sign-in is in progress. Please wait a moment and try again.';
|
| 76 |
-
} else if (error.code === 'auth/unauthorized-domain') {
|
| 77 |
-
errorMsg = 'β This domain is not authorized for Google Sign-In. Please contact the administrator.';
|
| 78 |
-
} else if (error.code === 'auth/operation-not-allowed') {
|
| 79 |
-
errorMsg = 'β Google Sign-In is not enabled. Please contact the administrator.';
|
| 80 |
-
} else if (error.code === 'auth/network-request-failed') {
|
| 81 |
-
errorMsg = 'β Network error. Please check your internet connection and try again.';
|
| 82 |
-
} else {
|
| 83 |
-
errorMsg = `β ${error.message || 'Google Sign-In failed. Please try again.'}`;
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
if (resultDiv) {
|
| 87 |
-
resultDiv.innerHTML = `<p class="error-msg">${errorMsg}</p>`;
|
| 88 |
-
}
|
| 89 |
-
}
|
| 90 |
-
}
|
| 91 |
-
|
| 92 |
-
// Firebase Email/Password Authentication
|
| 93 |
-
async function authenticateWithFirebase(email, password, isSignup) {
|
| 94 |
-
if (!window.firebaseEnabled || !window.firebaseAuth) {
|
| 95 |
-
return null; // Fall back to legacy auth
|
| 96 |
-
}
|
| 97 |
-
|
| 98 |
-
try {
|
| 99 |
-
let userCredential;
|
| 100 |
-
|
| 101 |
-
if (isSignup) {
|
| 102 |
-
// Create new user with Firebase
|
| 103 |
-
userCredential = await window.firebaseAuth.createUserWithEmailAndPassword(email, password);
|
| 104 |
-
|
| 105 |
-
// Send email verification
|
| 106 |
-
await userCredential.user.sendEmailVerification();
|
| 107 |
-
} else {
|
| 108 |
-
// Sign in existing user
|
| 109 |
-
userCredential = await window.firebaseAuth.signInWithEmailAndPassword(email, password);
|
| 110 |
-
|
| 111 |
-
// Check if email is verified
|
| 112 |
-
if (!userCredential.user.emailVerified) {
|
| 113 |
-
document.getElementById('result').innerHTML =
|
| 114 |
-
'<p class="error-msg">β οΈ Please verify your email first. Check your inbox.</p>';
|
| 115 |
-
await window.firebaseAuth.signOut();
|
| 116 |
-
return null;
|
| 117 |
-
}
|
| 118 |
-
}
|
| 119 |
-
|
| 120 |
-
// Get ID token
|
| 121 |
-
const idToken = await userCredential.user.getIdToken();
|
| 122 |
-
return idToken;
|
| 123 |
-
|
| 124 |
-
} catch (error) {
|
| 125 |
-
console.error('Firebase Auth Error:', error);
|
| 126 |
-
throw error;
|
| 127 |
-
}
|
| 128 |
-
}
|
| 129 |
-
|
| 130 |
// ==================== AUTHENTICATION ====================
|
| 131 |
|
| 132 |
-
|
| 133 |
-
const
|
| 134 |
-
const username = document.getElementById('authUsername') ? document.getElementById('authUsername').value.trim() : '';
|
| 135 |
const password = document.getElementById('authPassword').value;
|
| 136 |
|
| 137 |
-
if (!
|
| 138 |
document.getElementById('result').innerHTML =
|
| 139 |
'<p class="error-msg">β οΈ Please fill in all fields</p>';
|
| 140 |
return;
|
| 141 |
}
|
| 142 |
|
| 143 |
-
const
|
| 144 |
-
const endpoint = isSignup ? '/signup' : '/login';
|
| 145 |
-
|
| 146 |
-
// Try Firebase authentication first if available
|
| 147 |
-
if (window.firebaseEnabled) {
|
| 148 |
-
try {
|
| 149 |
-
const idToken = await authenticateWithFirebase(email, password, isSignup);
|
| 150 |
-
|
| 151 |
-
if (!idToken) {
|
| 152 |
-
return; // Error already displayed
|
| 153 |
-
}
|
| 154 |
-
|
| 155 |
-
// Send token to backend
|
| 156 |
-
const response = await fetch(endpoint, {
|
| 157 |
-
method: 'POST',
|
| 158 |
-
headers: {'Content-Type': 'application/json'},
|
| 159 |
-
body: JSON.stringify({idToken}),
|
| 160 |
-
credentials: 'same-origin'
|
| 161 |
-
});
|
| 162 |
-
|
| 163 |
-
const data = await response.json();
|
| 164 |
-
|
| 165 |
-
if (data.success) {
|
| 166 |
-
if (isSignup) {
|
| 167 |
-
document.getElementById('result').innerHTML =
|
| 168 |
-
'<p class="success-msg">β
Account created! Please check your email to verify.</p>';
|
| 169 |
-
} else {
|
| 170 |
-
window.location.href = '/assessment';
|
| 171 |
-
}
|
| 172 |
-
} else {
|
| 173 |
-
document.getElementById('result').innerHTML =
|
| 174 |
-
`<p class="error-msg">${data.message || 'Authentication failed'}</p>`;
|
| 175 |
-
}
|
| 176 |
-
return;
|
| 177 |
-
} catch (error) {
|
| 178 |
-
console.error('Firebase auth error:', error);
|
| 179 |
-
document.getElementById('result').innerHTML =
|
| 180 |
-
`<p class="error-msg">${error.message || 'Authentication failed'}</p>`;
|
| 181 |
-
return;
|
| 182 |
-
}
|
| 183 |
-
}
|
| 184 |
-
|
| 185 |
-
// Legacy authentication fallback (if Firebase is disabled)
|
| 186 |
-
const body = isSignup
|
| 187 |
-
? {username, password, email}
|
| 188 |
-
: {username, password};
|
| 189 |
|
| 190 |
fetch(endpoint, {
|
| 191 |
method: 'POST',
|
| 192 |
headers: {'Content-Type': 'application/json'},
|
| 193 |
-
body: JSON.stringify(
|
| 194 |
-
credentials: 'same-origin'
|
| 195 |
-
})
|
| 196 |
-
.then(response => {
|
| 197 |
-
if (!response.ok) {
|
| 198 |
-
return response.json().then(err => Promise.reject(err));
|
| 199 |
-
}
|
| 200 |
-
return response.json();
|
| 201 |
})
|
|
|
|
| 202 |
.then(data => {
|
| 203 |
if (data.success) {
|
| 204 |
-
|
| 205 |
-
document.getElementById('result').innerHTML =
|
| 206 |
-
'<p class="success-msg">β
' + (data.message || 'Account created! Please check your email to verify.') + '</p>';
|
| 207 |
-
} else {
|
| 208 |
-
window.location.href = '/assessment';
|
| 209 |
-
}
|
| 210 |
} else {
|
| 211 |
document.getElementById('result').innerHTML =
|
| 212 |
-
`<p class="error-msg">${data.message
|
| 213 |
}
|
| 214 |
-
})
|
| 215 |
-
.catch(error => {
|
| 216 |
-
document.getElementById('result').innerHTML =
|
| 217 |
-
`<p class="error-msg">${error.message || 'Network error. Please try again.'}</p>`;
|
| 218 |
});
|
| 219 |
}
|
| 220 |
|
|
@@ -223,80 +38,6 @@ function switchAuth() {
|
|
| 223 |
window.location.href = newPath;
|
| 224 |
}
|
| 225 |
|
| 226 |
-
function resetPassword() {
|
| 227 |
-
const email = document.getElementById('resetEmail').value.trim();
|
| 228 |
-
|
| 229 |
-
if (!email) {
|
| 230 |
-
document.getElementById('result').innerHTML =
|
| 231 |
-
'<p class="error-msg">β οΈ Please enter your email</p>';
|
| 232 |
-
return;
|
| 233 |
-
}
|
| 234 |
-
|
| 235 |
-
fetch('/forgot-password', {
|
| 236 |
-
method: 'POST',
|
| 237 |
-
headers: {'Content-Type': 'application/json'},
|
| 238 |
-
body: JSON.stringify({email}),
|
| 239 |
-
credentials: 'same-origin'
|
| 240 |
-
})
|
| 241 |
-
.then(response => {
|
| 242 |
-
if (!response.ok) {
|
| 243 |
-
return response.json().then(err => Promise.reject(err));
|
| 244 |
-
}
|
| 245 |
-
return response.json();
|
| 246 |
-
})
|
| 247 |
-
.then(data => {
|
| 248 |
-
if (data.success) {
|
| 249 |
-
document.getElementById('result').innerHTML =
|
| 250 |
-
'<p class="success-msg">β
Password reset link sent! Check your email (or server console in dev mode).</p>';
|
| 251 |
-
} else {
|
| 252 |
-
document.getElementById('result').innerHTML =
|
| 253 |
-
`<p class="error-msg">${data.message || 'Failed to send reset link'}</p>`;
|
| 254 |
-
}
|
| 255 |
-
})
|
| 256 |
-
.catch(error => {
|
| 257 |
-
document.getElementById('result').innerHTML =
|
| 258 |
-
`<p class="error-msg">${error.message || 'Network error. Please try again.'}</p>`;
|
| 259 |
-
});
|
| 260 |
-
}
|
| 261 |
-
|
| 262 |
-
function submitPasswordReset() {
|
| 263 |
-
const token = document.getElementById('resetToken').value;
|
| 264 |
-
const password = document.getElementById('resetPassword').value;
|
| 265 |
-
|
| 266 |
-
if (!password) {
|
| 267 |
-
document.getElementById('result').innerHTML =
|
| 268 |
-
'<p class="error-msg">β οΈ Please enter a new password</p>';
|
| 269 |
-
return;
|
| 270 |
-
}
|
| 271 |
-
|
| 272 |
-
fetch('/reset-password-submit', {
|
| 273 |
-
method: 'POST',
|
| 274 |
-
headers: {'Content-Type': 'application/json'},
|
| 275 |
-
body: JSON.stringify({token, password}),
|
| 276 |
-
credentials: 'same-origin'
|
| 277 |
-
})
|
| 278 |
-
.then(response => {
|
| 279 |
-
if (!response.ok) {
|
| 280 |
-
return response.json().then(err => Promise.reject(err));
|
| 281 |
-
}
|
| 282 |
-
return response.json();
|
| 283 |
-
})
|
| 284 |
-
.then(data => {
|
| 285 |
-
if (data.success) {
|
| 286 |
-
document.getElementById('result').innerHTML =
|
| 287 |
-
'<p class="success-msg">β
Password reset successfully! Redirecting to login...</p>';
|
| 288 |
-
setTimeout(() => window.location.href = '/login', 1500);
|
| 289 |
-
} else {
|
| 290 |
-
document.getElementById('result').innerHTML =
|
| 291 |
-
`<p class="error-msg">${data.message || 'Failed to reset password'}</p>`;
|
| 292 |
-
}
|
| 293 |
-
})
|
| 294 |
-
.catch(error => {
|
| 295 |
-
document.getElementById('result').innerHTML =
|
| 296 |
-
`<p class="error-msg">${error.message || 'Network error. Please try again.'}</p>`;
|
| 297 |
-
});
|
| 298 |
-
}
|
| 299 |
-
|
| 300 |
// ==================== ASSESSMENT ====================
|
| 301 |
|
| 302 |
var currentQuestion = 1;
|
|
@@ -332,7 +73,7 @@ function showQuestion(questionIndex) {
|
|
| 332 |
|
| 333 |
currentQuestion = questionIndex;
|
| 334 |
document.getElementById('questionCounter').textContent = 'Question ' + questionIndex + ' of ' + totalQuestions;
|
| 335 |
-
document.getElementById('progressBar').style.width = (
|
| 336 |
updateNavigationButtons();
|
| 337 |
}
|
| 338 |
|
|
@@ -437,30 +178,6 @@ function resetAssessment() {
|
|
| 437 |
});
|
| 438 |
}
|
| 439 |
|
| 440 |
-
// ==================== SHARE RESULTS ====================
|
| 441 |
-
|
| 442 |
-
function shareResults() {
|
| 443 |
-
const results = getResultsSummary();
|
| 444 |
-
const text = `My Spiritual Path Results:\n\n${results}\n\nTake the assessment: ${window.location.origin}`;
|
| 445 |
-
|
| 446 |
-
if (navigator.share) {
|
| 447 |
-
navigator.share({ title: 'Spiritual Path Results', text: text });
|
| 448 |
-
} else {
|
| 449 |
-
navigator.clipboard.writeText(text);
|
| 450 |
-
alert('Results copied to clipboard!');
|
| 451 |
-
}
|
| 452 |
-
}
|
| 453 |
-
|
| 454 |
-
function getResultsSummary() {
|
| 455 |
-
const cards = document.querySelectorAll('.result-card');
|
| 456 |
-
return Array.from(cards).map((card, i) => {
|
| 457 |
-
const title = card.querySelector('h3').textContent;
|
| 458 |
-
const percentage = card.querySelector('.result-percentage').textContent;
|
| 459 |
-
return `${i+1}. ${title} (${percentage})`;
|
| 460 |
-
}).join('\n');
|
| 461 |
-
}
|
| 462 |
-
|
| 463 |
-
|
| 464 |
// ==================== CHAT FUNCTIONALITY ====================
|
| 465 |
|
| 466 |
var chatHistories = {};
|
|
@@ -597,118 +314,3 @@ function sendMessage(religionName) {
|
|
| 597 |
});
|
| 598 |
}
|
| 599 |
|
| 600 |
-
// ==================== VOICE CHAT ====================
|
| 601 |
-
|
| 602 |
-
var recognition = null;
|
| 603 |
-
var currentReligion = null;
|
| 604 |
-
var isRecording = false;
|
| 605 |
-
|
| 606 |
-
function initializeSpeechRecognition() {
|
| 607 |
-
if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
|
| 608 |
-
recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
|
| 609 |
-
recognition.continuous = true;
|
| 610 |
-
recognition.interimResults = true;
|
| 611 |
-
recognition.lang = 'en-US';
|
| 612 |
-
|
| 613 |
-
recognition.onresult = function(event) {
|
| 614 |
-
var interimTranscript = '';
|
| 615 |
-
var finalTranscript = '';
|
| 616 |
-
|
| 617 |
-
for (var i = event.resultIndex; i < event.results.length; i++) {
|
| 618 |
-
var transcript = event.results[i][0].transcript;
|
| 619 |
-
if (event.results[i].isFinal) {
|
| 620 |
-
finalTranscript += transcript + ' ';
|
| 621 |
-
} else {
|
| 622 |
-
interimTranscript += transcript;
|
| 623 |
-
}
|
| 624 |
-
}
|
| 625 |
-
|
| 626 |
-
// Update input field with live transcription
|
| 627 |
-
if (currentReligion) {
|
| 628 |
-
var inputId = 'input-' + sanitizeReligionName(currentReligion);
|
| 629 |
-
var inputEl = document.getElementById(inputId);
|
| 630 |
-
if (inputEl) {
|
| 631 |
-
inputEl.value = finalTranscript + interimTranscript;
|
| 632 |
-
}
|
| 633 |
-
}
|
| 634 |
-
};
|
| 635 |
-
|
| 636 |
-
recognition.onerror = function(event) {
|
| 637 |
-
console.error('Speech recognition error:', event.error);
|
| 638 |
-
if (event.error === 'no-speech') {
|
| 639 |
-
stopVoiceInput();
|
| 640 |
-
}
|
| 641 |
-
};
|
| 642 |
-
|
| 643 |
-
recognition.onend = function() {
|
| 644 |
-
if (isRecording) {
|
| 645 |
-
// Restart if it stopped unexpectedly
|
| 646 |
-
try {
|
| 647 |
-
recognition.start();
|
| 648 |
-
} catch(e) {
|
| 649 |
-
stopVoiceInput();
|
| 650 |
-
}
|
| 651 |
-
}
|
| 652 |
-
};
|
| 653 |
-
}
|
| 654 |
-
}
|
| 655 |
-
|
| 656 |
-
function startVoiceInput(religionName) {
|
| 657 |
-
if (!recognition) {
|
| 658 |
-
alert('Speech recognition not supported in your browser');
|
| 659 |
-
return;
|
| 660 |
-
}
|
| 661 |
-
|
| 662 |
-
currentReligion = religionName;
|
| 663 |
-
isRecording = true;
|
| 664 |
-
|
| 665 |
-
try {
|
| 666 |
-
recognition.start();
|
| 667 |
-
document.getElementById('voice-' + sanitizeReligionName(religionName)).classList.add('recording');
|
| 668 |
-
} catch(e) {
|
| 669 |
-
console.log('Already started or error:', e);
|
| 670 |
-
}
|
| 671 |
-
}
|
| 672 |
-
|
| 673 |
-
function stopVoiceInput(religionName) {
|
| 674 |
-
if (recognition && isRecording) {
|
| 675 |
-
isRecording = false;
|
| 676 |
-
recognition.stop();
|
| 677 |
-
document.getElementById('voice-' + sanitizeReligionName(religionName)).classList.remove('recording');
|
| 678 |
-
}
|
| 679 |
-
}
|
| 680 |
-
|
| 681 |
-
// Initialize on page load
|
| 682 |
-
if (document.readyState === 'loading') {
|
| 683 |
-
document.addEventListener('DOMContentLoaded', initializeSpeechRecognition);
|
| 684 |
-
} else {
|
| 685 |
-
initializeSpeechRecognition();
|
| 686 |
-
}
|
| 687 |
-
|
| 688 |
-
// Make tooltips appear instantly on hover
|
| 689 |
-
document.addEventListener('DOMContentLoaded', function() {
|
| 690 |
-
const micButtons = document.querySelectorAll('button[title]');
|
| 691 |
-
|
| 692 |
-
micButtons.forEach(button => {
|
| 693 |
-
const tooltipText = button.getAttribute('title');
|
| 694 |
-
button.removeAttribute('title'); // Remove native tooltip
|
| 695 |
-
|
| 696 |
-
// Create custom tooltip element
|
| 697 |
-
const tooltip = document.createElement('div');
|
| 698 |
-
tooltip.className = 'custom-tooltip';
|
| 699 |
-
tooltip.textContent = tooltipText;
|
| 700 |
-
|
| 701 |
-
// Add tooltip to button
|
| 702 |
-
button.style.position = 'relative';
|
| 703 |
-
button.appendChild(tooltip);
|
| 704 |
-
|
| 705 |
-
button.addEventListener('mouseenter', function() {
|
| 706 |
-
tooltip.style.opacity = '1';
|
| 707 |
-
});
|
| 708 |
-
|
| 709 |
-
button.addEventListener('mouseleave', function() {
|
| 710 |
-
tooltip.style.opacity = '0';
|
| 711 |
-
});
|
| 712 |
-
});
|
| 713 |
-
});
|
| 714 |
-
|
|
|
|
| 3 |
return name.replace(/\s+/g, '-');
|
| 4 |
}
|
| 5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
// ==================== AUTHENTICATION ====================
|
| 7 |
|
| 8 |
+
function authenticate() {
|
| 9 |
+
const username = document.getElementById('authUsername').value.trim();
|
|
|
|
| 10 |
const password = document.getElementById('authPassword').value;
|
| 11 |
|
| 12 |
+
if (!username || !password) {
|
| 13 |
document.getElementById('result').innerHTML =
|
| 14 |
'<p class="error-msg">β οΈ Please fill in all fields</p>';
|
| 15 |
return;
|
| 16 |
}
|
| 17 |
|
| 18 |
+
const endpoint = window.location.pathname === '/signup' ? '/signup' : '/login';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
fetch(endpoint, {
|
| 21 |
method: 'POST',
|
| 22 |
headers: {'Content-Type': 'application/json'},
|
| 23 |
+
body: JSON.stringify({username, password})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
})
|
| 25 |
+
.then(response => response.json())
|
| 26 |
.then(data => {
|
| 27 |
if (data.success) {
|
| 28 |
+
window.location.href = '/';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
} else {
|
| 30 |
document.getElementById('result').innerHTML =
|
| 31 |
+
`<p class="error-msg">${data.message}</p>`;
|
| 32 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
});
|
| 34 |
}
|
| 35 |
|
|
|
|
| 38 |
window.location.href = newPath;
|
| 39 |
}
|
| 40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
// ==================== ASSESSMENT ====================
|
| 42 |
|
| 43 |
var currentQuestion = 1;
|
|
|
|
| 73 |
|
| 74 |
currentQuestion = questionIndex;
|
| 75 |
document.getElementById('questionCounter').textContent = 'Question ' + questionIndex + ' of ' + totalQuestions;
|
| 76 |
+
document.getElementById('progressBar').style.width = (questionIndex / totalQuestions) * 100 + '%';
|
| 77 |
updateNavigationButtons();
|
| 78 |
}
|
| 79 |
|
|
|
|
| 178 |
});
|
| 179 |
}
|
| 180 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
// ==================== CHAT FUNCTIONALITY ====================
|
| 182 |
|
| 183 |
var chatHistories = {};
|
|
|
|
| 314 |
});
|
| 315 |
}
|
| 316 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static/style.css
CHANGED
|
@@ -1,6 +1,3 @@
|
|
| 1 |
-
@import url('design-tokens.css');
|
| 2 |
-
|
| 3 |
-
/* ===== RESET & BASE ===== */
|
| 4 |
* {
|
| 5 |
margin: 0;
|
| 6 |
padding: 0;
|
|
@@ -8,121 +5,139 @@
|
|
| 8 |
}
|
| 9 |
|
| 10 |
body {
|
| 11 |
-
font-family:
|
| 12 |
-
background:
|
| 13 |
-
rgb(255, 255, 255) 0%,
|
| 14 |
-
rgb(255, 255, 255) 5%,
|
| 15 |
-
rgb(226, 218, 250) 30%,
|
| 16 |
-
rgb(219, 239, 253) 80%,
|
| 17 |
-
rgb(255, 255, 255) 95%,
|
| 18 |
-
rgb(255, 255, 255) 100%);
|
| 19 |
min-height: 100vh;
|
| 20 |
display: flex;
|
| 21 |
justify-content: center;
|
| 22 |
align-items: center;
|
| 23 |
-
padding:
|
| 24 |
}
|
| 25 |
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
background: var(--bg-white);
|
| 32 |
-
border-radius: var(--radius-xl);
|
| 33 |
-
padding: var(--space-lg);
|
| 34 |
-
box-shadow: var(--shadow-xl);
|
| 35 |
max-width: 700px;
|
| 36 |
width: 100%;
|
| 37 |
-
animation: slideIn
|
| 38 |
max-height: 95vh;
|
| 39 |
overflow-y: auto;
|
| 40 |
}
|
| 41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
@keyframes slideIn {
|
| 43 |
from { opacity: 0; transform: translateY(20px); }
|
| 44 |
to { opacity: 1; transform: translateY(0); }
|
| 45 |
}
|
| 46 |
|
| 47 |
-
/* ===== TYPOGRAPHY ===== */
|
| 48 |
h1 {
|
| 49 |
-
color:
|
| 50 |
-
font-size:
|
| 51 |
-
margin-bottom:
|
| 52 |
text-align: center;
|
| 53 |
-
font-weight:
|
| 54 |
}
|
| 55 |
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
|
|
|
| 60 |
}
|
| 61 |
|
| 62 |
h3 {
|
| 63 |
text-align: center;
|
| 64 |
-
color:
|
| 65 |
-
}
|
| 66 |
-
|
| 67 |
-
/* ===== ICON STYLING ===== */
|
| 68 |
-
.fa-heart {
|
| 69 |
-
color: var(--error); /* Red color for heart icons */
|
| 70 |
}
|
| 71 |
|
| 72 |
p {
|
| 73 |
-
color:
|
| 74 |
text-align: center;
|
| 75 |
-
margin-bottom:
|
| 76 |
-
font-size:
|
| 77 |
}
|
| 78 |
|
| 79 |
.subtitle {
|
| 80 |
-
color:
|
| 81 |
-
font-size:
|
| 82 |
text-align: center;
|
| 83 |
-
margin-bottom:
|
| 84 |
line-height: 1.6;
|
| 85 |
-
max-width: 540px;
|
| 86 |
-
margin-left: auto;
|
| 87 |
-
margin-right: auto;
|
| 88 |
}
|
| 89 |
|
| 90 |
-
/*
|
| 91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
width: 100%;
|
| 93 |
-
padding:
|
| 94 |
-
font-size:
|
| 95 |
border: none;
|
| 96 |
-
background:
|
| 97 |
-
border-radius:
|
| 98 |
-
transition: all
|
| 99 |
outline: none;
|
| 100 |
}
|
| 101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
input:focus {
|
| 103 |
background: #EBEBEB;
|
| 104 |
box-shadow: 0 0 0 2px #E5E5E5;
|
| 105 |
}
|
| 106 |
|
| 107 |
-
/*
|
| 108 |
button, .btn, .nav-btn, .submit-btn {
|
| 109 |
-
padding:
|
| 110 |
-
font-size:
|
| 111 |
-
background:
|
| 112 |
-
color:
|
| 113 |
border: none;
|
| 114 |
-
border-radius:
|
| 115 |
cursor: pointer;
|
| 116 |
-
transition: all
|
| 117 |
-
font-weight:
|
| 118 |
text-decoration: none;
|
| 119 |
display: inline-block;
|
| 120 |
}
|
| 121 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
button:hover, .btn:hover, .nav-btn:hover, .submit-btn:hover {
|
| 123 |
-
background:
|
| 124 |
transform: translateY(-1px);
|
| 125 |
-
box-shadow:
|
| 126 |
}
|
| 127 |
|
| 128 |
button:active, .btn:active {
|
|
@@ -142,141 +157,74 @@ button:disabled {
|
|
| 142 |
transform: none;
|
| 143 |
}
|
| 144 |
|
| 145 |
-
/* Secondary Buttons */
|
| 146 |
-
.logout-btn, .reset-btn
|
| 147 |
-
background:
|
| 148 |
-
padding:
|
| 149 |
-
font-size:
|
| 150 |
-
|
| 151 |
-
margin-top: var(--space-sm);
|
| 152 |
}
|
| 153 |
|
| 154 |
-
.logout-btn:hover, .reset-btn:hover
|
| 155 |
background: #4B5563;
|
| 156 |
-
box-shadow:
|
| 157 |
}
|
| 158 |
|
| 159 |
/* Submit Button */
|
| 160 |
.submit-btn {
|
| 161 |
width: 100%;
|
| 162 |
-
padding:
|
| 163 |
-
font-size:
|
| 164 |
-
margin-top:
|
| 165 |
}
|
| 166 |
|
| 167 |
/* Auth Form */
|
| 168 |
-
/* Auth-specific container - narrower for login/signup/forgot-password */
|
| 169 |
-
.auth-container {
|
| 170 |
-
background: var(--bg-white);
|
| 171 |
-
border-radius: var(--radius-xl);
|
| 172 |
-
padding: var(--space-lg);
|
| 173 |
-
box-shadow: var(--shadow-xl);
|
| 174 |
-
max-width: 400px; /* Narrower for auth forms */
|
| 175 |
-
width: 100%;
|
| 176 |
-
animation: slideIn var(--transition-slow) ease;
|
| 177 |
-
max-height: 95vh;
|
| 178 |
-
overflow-y: auto;
|
| 179 |
-
text-align: center;
|
| 180 |
-
}
|
| 181 |
-
|
| 182 |
.auth-form input {
|
| 183 |
width: 100%;
|
| 184 |
-
margin-bottom:
|
| 185 |
}
|
| 186 |
|
| 187 |
.auth-form button {
|
| 188 |
width: 100%;
|
| 189 |
}
|
| 190 |
|
| 191 |
-
/* Google Sign-In Button */
|
| 192 |
-
.google-signin-btn {
|
| 193 |
-
width: 100%;
|
| 194 |
-
padding: var(--space-sm) var(--space-lg);
|
| 195 |
-
background: white;
|
| 196 |
-
color: #444;
|
| 197 |
-
border: 1px solid #ddd;
|
| 198 |
-
border-radius: var(--radius-md);
|
| 199 |
-
font-size: var(--font-size-base);
|
| 200 |
-
font-weight: 500;
|
| 201 |
-
cursor: pointer;
|
| 202 |
-
display: flex;
|
| 203 |
-
align-items: center;
|
| 204 |
-
justify-content: center;
|
| 205 |
-
gap: 12px;
|
| 206 |
-
transition: all var(--transition-fast);
|
| 207 |
-
margin-bottom: var(--space-md);
|
| 208 |
-
}
|
| 209 |
-
|
| 210 |
-
.google-signin-btn:hover {
|
| 211 |
-
background: #f8f8f8;
|
| 212 |
-
border-color: #ccc;
|
| 213 |
-
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
| 214 |
-
}
|
| 215 |
-
|
| 216 |
-
.google-signin-btn svg {
|
| 217 |
-
flex-shrink: 0;
|
| 218 |
-
}
|
| 219 |
-
|
| 220 |
-
/* Divider for "or" between Google and email/password */
|
| 221 |
-
.divider {
|
| 222 |
-
display: flex;
|
| 223 |
-
align-items: center;
|
| 224 |
-
text-align: center;
|
| 225 |
-
margin: var(--space-md) 0;
|
| 226 |
-
color: var(--text-secondary);
|
| 227 |
-
font-size: var(--font-size-sm);
|
| 228 |
-
}
|
| 229 |
-
|
| 230 |
-
.divider::before,
|
| 231 |
-
.divider::after {
|
| 232 |
-
content: '';
|
| 233 |
-
flex: 1;
|
| 234 |
-
border-bottom: 1px solid #ddd;
|
| 235 |
-
}
|
| 236 |
-
|
| 237 |
-
.divider span {
|
| 238 |
-
padding: 0 var(--space-sm);
|
| 239 |
-
}
|
| 240 |
-
|
| 241 |
-
#result {
|
| 242 |
-
margin-bottom: var(--space-md); /* 16px bottom margin only */
|
| 243 |
-
margin-top: 0;
|
| 244 |
-
padding: 0;
|
| 245 |
-
}
|
| 246 |
-
|
| 247 |
.switch-link {
|
| 248 |
-
color:
|
| 249 |
text-decoration: none;
|
| 250 |
cursor: pointer;
|
| 251 |
-
font-weight:
|
| 252 |
-
|
| 253 |
-
display: block;
|
| 254 |
-
|
| 255 |
-
transition: color var(--transition-fast);
|
| 256 |
-
font-size: var(--font-size-sm);
|
| 257 |
}
|
| 258 |
|
| 259 |
.switch-link:hover {
|
| 260 |
-
color:
|
| 261 |
text-decoration: underline;
|
| 262 |
}
|
| 263 |
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
/* ===== QUESTION BLOCKS ===== */
|
| 267 |
.question-block {
|
| 268 |
-
background:
|
| 269 |
-
padding:
|
| 270 |
-
border-radius:
|
| 271 |
-
margin-bottom:
|
| 272 |
border: none;
|
| 273 |
display: none;
|
| 274 |
min-height: 400px;
|
| 275 |
}
|
| 276 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 277 |
.question-block.active {
|
| 278 |
display: block;
|
| 279 |
-
animation: fadeIn
|
| 280 |
}
|
| 281 |
|
| 282 |
@keyframes fadeIn {
|
|
@@ -285,53 +233,77 @@ button:disabled {
|
|
| 285 |
}
|
| 286 |
|
| 287 |
.question-block h4 {
|
| 288 |
-
color:
|
| 289 |
-
margin-bottom:
|
| 290 |
-
font-weight:
|
| 291 |
-
font-size:
|
| 292 |
line-height: 1.6;
|
| 293 |
}
|
| 294 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
.question-number {
|
| 296 |
display: inline-block;
|
| 297 |
-
background:
|
| 298 |
-
color:
|
| 299 |
width: 32px;
|
| 300 |
height: 32px;
|
| 301 |
-
border-radius:
|
| 302 |
text-align: center;
|
| 303 |
line-height: 32px;
|
| 304 |
-
margin-right:
|
| 305 |
-
font-size:
|
| 306 |
}
|
| 307 |
|
| 308 |
-
/*
|
| 309 |
.option {
|
| 310 |
-
display:
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
background: var(--bg-white);
|
| 315 |
border: none;
|
| 316 |
-
border-radius:
|
| 317 |
cursor: pointer;
|
| 318 |
-
transition: all
|
| 319 |
-
font-size:
|
| 320 |
-
color:
|
| 321 |
-
box-shadow:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 322 |
}
|
| 323 |
|
| 324 |
.option:hover {
|
| 325 |
-
background:
|
| 326 |
transform: translateX(5px);
|
| 327 |
-
box-shadow:
|
| 328 |
}
|
| 329 |
|
| 330 |
.option input[type="radio"] {
|
| 331 |
-
margin-right:
|
| 332 |
cursor: pointer;
|
| 333 |
-
width:
|
| 334 |
-
height:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 335 |
}
|
| 336 |
|
| 337 |
.option input[type="radio"]:disabled {
|
|
@@ -345,222 +317,194 @@ button:disabled {
|
|
| 345 |
}
|
| 346 |
|
| 347 |
.option:has(input[type="radio"]:disabled):hover {
|
| 348 |
-
background:
|
| 349 |
transform: none;
|
| 350 |
}
|
| 351 |
|
| 352 |
-
/*
|
| 353 |
.question-counter {
|
| 354 |
text-align: center;
|
| 355 |
color: #999;
|
| 356 |
-
font-size:
|
| 357 |
-
margin-bottom:
|
| 358 |
-
font-weight:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 359 |
}
|
| 360 |
|
| 361 |
.progress-bar {
|
| 362 |
-
background:
|
| 363 |
-
height:
|
| 364 |
border-radius: 4px;
|
| 365 |
overflow: hidden;
|
| 366 |
-
margin-bottom:
|
| 367 |
}
|
| 368 |
|
| 369 |
.progress-fill {
|
| 370 |
-
background:
|
| 371 |
height: 100%;
|
| 372 |
-
transition: width
|
| 373 |
}
|
| 374 |
|
|
|
|
| 375 |
.nav-buttons {
|
| 376 |
display: flex;
|
| 377 |
-
gap:
|
| 378 |
justify-content: flex-start;
|
| 379 |
-
margin-top:
|
| 380 |
-
}
|
| 381 |
-
|
| 382 |
-
.nav-btn.prev {
|
| 383 |
-
background: transparent;
|
| 384 |
-
color: #999;
|
| 385 |
-
border: none;
|
| 386 |
-
padding: 0;
|
| 387 |
-
font-weight: var(--font-weight-medium);
|
| 388 |
-
font-size: var(--font-size-sm);
|
| 389 |
-
text-decoration: none;
|
| 390 |
-
display: inline-flex;
|
| 391 |
-
align-items: center;
|
| 392 |
-
gap: 4px;
|
| 393 |
-
transition: all var(--transition-base) ease;
|
| 394 |
-
box-shadow: none;
|
| 395 |
-
}
|
| 396 |
-
|
| 397 |
-
.nav-btn.prev:hover {
|
| 398 |
-
background: transparent;
|
| 399 |
-
color: #666;
|
| 400 |
-
transform: translateX(-3px);
|
| 401 |
-
box-shadow: none;
|
| 402 |
}
|
| 403 |
|
| 404 |
.buttons-row {
|
| 405 |
display: flex;
|
| 406 |
-
gap:
|
| 407 |
justify-content: center;
|
| 408 |
-
margin-top:
|
| 409 |
-
}
|
| 410 |
-
|
| 411 |
-
/* ===== RESULTS ===== */
|
| 412 |
-
.results-explanation {
|
| 413 |
-
max-width: 400px; /* Adjust this value as needed */
|
| 414 |
-
margin: 0 auto var(--space-sm);
|
| 415 |
-
text-align: center;
|
| 416 |
-
color: var(--text-secondary);
|
| 417 |
-
font-size: var(--font-size-sm);
|
| 418 |
-
line-height: 1.5;
|
| 419 |
}
|
| 420 |
|
|
|
|
| 421 |
.result-card {
|
| 422 |
-
padding:
|
| 423 |
-
border-radius:
|
| 424 |
-
margin-bottom:
|
| 425 |
border: none;
|
| 426 |
-
box-shadow:
|
| 427 |
}
|
| 428 |
|
| 429 |
.result-card.rank-1 {
|
| 430 |
-
background:
|
| 431 |
}
|
| 432 |
|
| 433 |
.result-card.rank-2 {
|
| 434 |
-
background:
|
| 435 |
}
|
| 436 |
|
| 437 |
.result-card.rank-3 {
|
| 438 |
-
background:
|
| 439 |
}
|
| 440 |
|
| 441 |
.result-header {
|
| 442 |
display: flex;
|
| 443 |
align-items: center;
|
| 444 |
justify-content: space-between;
|
| 445 |
-
margin-bottom:
|
| 446 |
}
|
| 447 |
|
| 448 |
.result-rank {
|
| 449 |
-
color:
|
| 450 |
-
width:
|
| 451 |
-
height:
|
| 452 |
-
border-radius:
|
| 453 |
display: flex;
|
| 454 |
align-items: center;
|
| 455 |
justify-content: center;
|
| 456 |
-
font-size:
|
| 457 |
-
font-weight:
|
| 458 |
-
background:
|
| 459 |
}
|
| 460 |
|
| 461 |
.result-title {
|
| 462 |
flex: 1;
|
| 463 |
-
margin-left:
|
| 464 |
}
|
| 465 |
|
| 466 |
.result-title h3 {
|
| 467 |
-
font-size:
|
| 468 |
margin-bottom: 5px;
|
| 469 |
-
color:
|
| 470 |
-
}
|
| 471 |
-
|
| 472 |
-
.result-details h5 i {
|
| 473 |
-
font-size: var(--font-size-sm);
|
| 474 |
-
margin-right: var(--space-xs);
|
| 475 |
}
|
| 476 |
|
| 477 |
.result-percentage {
|
| 478 |
-
font-size:
|
| 479 |
-
font-weight:
|
| 480 |
-
color:
|
| 481 |
}
|
| 482 |
|
| 483 |
.result-description {
|
| 484 |
color: #666;
|
| 485 |
line-height: 1.6;
|
| 486 |
-
margin-bottom:
|
| 487 |
-
font-size:
|
| 488 |
}
|
| 489 |
|
| 490 |
.result-details {
|
| 491 |
background: rgba(255, 255, 255, 0.6);
|
| 492 |
border: none;
|
| 493 |
-
padding:
|
| 494 |
-
border-radius:
|
| 495 |
-
margin-top:
|
| 496 |
}
|
| 497 |
|
| 498 |
.result-details h5 {
|
| 499 |
-
color:
|
| 500 |
-
font-size:
|
| 501 |
-
margin-bottom:
|
| 502 |
-
font-weight:
|
| 503 |
}
|
| 504 |
|
| 505 |
.result-details p {
|
| 506 |
color: #666;
|
| 507 |
-
font-size:
|
| 508 |
-
margin-bottom:
|
| 509 |
text-align: left;
|
| 510 |
}
|
| 511 |
|
| 512 |
-
/*
|
| 513 |
.icon {
|
| 514 |
-
font-size:
|
| 515 |
-
margin-right:
|
| 516 |
}
|
| 517 |
|
| 518 |
.success-msg {
|
| 519 |
-
color:
|
| 520 |
-
font-weight:
|
| 521 |
}
|
| 522 |
|
| 523 |
.error-msg {
|
| 524 |
color: #666;
|
| 525 |
-
font-weight:
|
| 526 |
text-align: center;
|
| 527 |
-
padding:
|
| 528 |
}
|
| 529 |
|
| 530 |
-
/*
|
| 531 |
.chat-toggle-btn {
|
| 532 |
background: rgba(255, 255, 255, 0.8);
|
| 533 |
-
color:
|
| 534 |
border: none;
|
| 535 |
-
padding:
|
| 536 |
-
border-radius:
|
| 537 |
cursor: pointer;
|
| 538 |
-
font-size:
|
| 539 |
-
font-weight:
|
| 540 |
-
margin-top:
|
| 541 |
width: 100%;
|
| 542 |
-
transition: background
|
| 543 |
-
box-shadow:
|
| 544 |
}
|
| 545 |
|
| 546 |
.chat-toggle-btn:hover {
|
| 547 |
-
background:
|
| 548 |
-
color:
|
| 549 |
}
|
| 550 |
|
| 551 |
.chat-window {
|
| 552 |
display: none;
|
| 553 |
background: rgba(255, 255, 255, 0.9);
|
| 554 |
border: none;
|
| 555 |
-
border-radius:
|
| 556 |
-
margin-top:
|
| 557 |
overflow: hidden;
|
| 558 |
-
box-shadow:
|
| 559 |
}
|
| 560 |
|
| 561 |
.chat-window.open {
|
| 562 |
display: block;
|
| 563 |
-
animation: slideDown
|
| 564 |
}
|
| 565 |
|
| 566 |
@keyframes slideDown {
|
|
@@ -571,37 +515,37 @@ button:disabled {
|
|
| 571 |
.chat-messages {
|
| 572 |
height: 250px;
|
| 573 |
overflow-y: auto;
|
| 574 |
-
padding:
|
| 575 |
-
background:
|
| 576 |
}
|
| 577 |
|
| 578 |
.chat-message {
|
| 579 |
-
margin-bottom:
|
| 580 |
-
padding:
|
| 581 |
-
border-radius:
|
| 582 |
max-width: 85%;
|
| 583 |
line-height: 1.5;
|
| 584 |
-
font-size:
|
| 585 |
}
|
| 586 |
|
| 587 |
.chat-message.user {
|
| 588 |
-
background:
|
| 589 |
-
color:
|
| 590 |
margin-left: auto;
|
| 591 |
text-align: right;
|
| 592 |
}
|
| 593 |
|
| 594 |
.chat-message.bot {
|
| 595 |
-
background:
|
| 596 |
-
color:
|
| 597 |
border: none;
|
| 598 |
text-align: left;
|
| 599 |
-
box-shadow:
|
| 600 |
}
|
| 601 |
|
| 602 |
.chat-message.bot ul {
|
| 603 |
-
margin:
|
| 604 |
-
padding-left:
|
| 605 |
}
|
| 606 |
|
| 607 |
.chat-message.bot li {
|
|
@@ -611,128 +555,74 @@ button:disabled {
|
|
| 611 |
|
| 612 |
.chat-input-area {
|
| 613 |
display: flex;
|
| 614 |
-
|
| 615 |
-
|
| 616 |
-
padding: var(--space-sm);
|
| 617 |
background: transparent;
|
| 618 |
border-top: none;
|
| 619 |
-
position: relative;
|
| 620 |
}
|
| 621 |
|
| 622 |
.chat-input {
|
| 623 |
flex: 1;
|
| 624 |
-
padding:
|
| 625 |
border: none;
|
| 626 |
-
background:
|
| 627 |
-
border-radius:
|
| 628 |
-
font-size:
|
| 629 |
outline: none;
|
| 630 |
-
color:
|
| 631 |
-
box-shadow:
|
| 632 |
}
|
| 633 |
|
| 634 |
.chat-input:focus {
|
| 635 |
-
box-shadow:
|
| 636 |
}
|
| 637 |
|
| 638 |
-
/* Removed the plus icon ::before pseudo-element */
|
| 639 |
-
|
| 640 |
.chat-send-btn {
|
| 641 |
-
padding:
|
| 642 |
-
|
| 643 |
-
|
| 644 |
-
min-width: 36px;
|
| 645 |
-
margin-left: var(--space-xs); /* Add margin instead of gap */
|
| 646 |
-
background: var(--primary-dark);
|
| 647 |
-
color: var(--text-inverse);
|
| 648 |
border: none;
|
| 649 |
-
border-radius:
|
| 650 |
cursor: pointer;
|
| 651 |
-
font-weight:
|
| 652 |
-
font-size:
|
| 653 |
-
transition: background
|
| 654 |
-
display: flex;
|
| 655 |
-
align-items: center;
|
| 656 |
-
justify-content: center;
|
| 657 |
-
flex-shrink: 0;
|
| 658 |
-
}
|
| 659 |
-
|
| 660 |
-
.chat-send-btn::after {
|
| 661 |
-
content: 'β';
|
| 662 |
-
font-size: var(--font-size-base);
|
| 663 |
-
line-height: 1;
|
| 664 |
-
font-weight: var(--font-weight-bold); /* Make arrow thicker */
|
| 665 |
-
-webkit-text-stroke: 0.5px; /* Additional thickness */
|
| 666 |
}
|
| 667 |
|
| 668 |
.chat-send-btn:hover {
|
| 669 |
-
background:
|
| 670 |
-
color:
|
| 671 |
}
|
| 672 |
|
| 673 |
.chat-send-btn:disabled {
|
| 674 |
-
background:
|
| 675 |
color: #999;
|
| 676 |
-
|
| 677 |
-
|
| 678 |
-
.voice-btn {
|
| 679 |
-
padding: 0;
|
| 680 |
-
width: auto;
|
| 681 |
-
height: auto;
|
| 682 |
-
background: transparent; /* Transparent to sit inside input visually */
|
| 683 |
-
color: var(--text-primary); /* Match input text color */
|
| 684 |
-
border: none;
|
| 685 |
-
border-radius: var(--radius-sm);
|
| 686 |
-
cursor: pointer;
|
| 687 |
-
font-size: var(--font-size-lg);
|
| 688 |
-
transition: all var(--transition-fast);
|
| 689 |
-
display: flex;
|
| 690 |
-
align-items: center;
|
| 691 |
-
justify-content: center;
|
| 692 |
-
position: absolute;
|
| 693 |
-
right: calc(16px + var(--space-xs) + var(--space-sm)); /* Position to left of send button */
|
| 694 |
-
}
|
| 695 |
-
|
| 696 |
-
.voice-btn:hover {
|
| 697 |
-
background: transparent;
|
| 698 |
-
color: var(--text-primary);
|
| 699 |
-
opacity: 0.7;
|
| 700 |
-
}
|
| 701 |
-
|
| 702 |
-
.voice-btn.recording {
|
| 703 |
-
color: var(--error);
|
| 704 |
-
animation: pulse 1s infinite;
|
| 705 |
-
}
|
| 706 |
-
|
| 707 |
-
@keyframes pulse {
|
| 708 |
-
0%, 100% { opacity: 1; }
|
| 709 |
-
50% { opacity: 0.7; }
|
| 710 |
}
|
| 711 |
|
| 712 |
.chat-typing {
|
| 713 |
color: #999;
|
| 714 |
font-style: italic;
|
| 715 |
-
font-size:
|
| 716 |
-
padding:
|
| 717 |
}
|
| 718 |
|
| 719 |
-
/*
|
| 720 |
.nav-header {
|
| 721 |
-
padding: 0 0
|
| 722 |
-
margin-bottom:
|
| 723 |
-
border-bottom: 1px solid
|
| 724 |
}
|
| 725 |
|
| 726 |
.back-link {
|
| 727 |
color: #667eea;
|
| 728 |
text-decoration: none;
|
| 729 |
-
font-weight:
|
| 730 |
-
font-size:
|
| 731 |
-
transition: all
|
| 732 |
display: inline-flex;
|
| 733 |
align-items: center;
|
| 734 |
gap: 4px;
|
| 735 |
-
|
| 736 |
}
|
| 737 |
|
| 738 |
.back-link:hover {
|
|
@@ -740,80 +630,12 @@ button:disabled {
|
|
| 740 |
transform: translateX(-3px);
|
| 741 |
}
|
| 742 |
|
| 743 |
-
|
| 744 |
-
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
/* ===== MOBILE RESPONSIVE ===== */
|
| 748 |
-
@media (max-width: 768px) {
|
| 749 |
-
.container {
|
| 750 |
-
padding: var(--space-sm);
|
| 751 |
-
border-radius: var(--radius-lg);
|
| 752 |
-
margin: 5px;
|
| 753 |
-
}
|
| 754 |
-
|
| 755 |
-
h1 {
|
| 756 |
-
font-size: var(--font-size-3xl);
|
| 757 |
-
}
|
| 758 |
-
|
| 759 |
-
p {
|
| 760 |
-
font-size: var(--font-size-lg);
|
| 761 |
-
}
|
| 762 |
-
|
| 763 |
-
.subtitle {
|
| 764 |
-
font-size: var(--font-size-base);
|
| 765 |
-
}
|
| 766 |
-
|
| 767 |
-
input[type="text"], input[type="password"], input[type="email"] {
|
| 768 |
-
padding: var(--space-md) var(--space-lg);
|
| 769 |
-
font-size: var(--font-size-lg);
|
| 770 |
-
}
|
| 771 |
-
|
| 772 |
-
button, .btn, .nav-btn, .submit-btn {
|
| 773 |
-
padding: var(--space-md) var(--space-2xl);
|
| 774 |
-
font-size: var(--font-size-lg);
|
| 775 |
-
}
|
| 776 |
-
|
| 777 |
-
.question-block {
|
| 778 |
-
padding: var(--space-lg);
|
| 779 |
-
min-height: 350px;
|
| 780 |
-
}
|
| 781 |
-
|
| 782 |
-
.question-block h4 {
|
| 783 |
-
font-size: var(--font-size-2xl);
|
| 784 |
-
}
|
| 785 |
-
|
| 786 |
-
.option {
|
| 787 |
-
padding: var(--space-lg) var(--space-xl);
|
| 788 |
-
margin-bottom: var(--space-md);
|
| 789 |
-
font-size: var(--font-size-lg);
|
| 790 |
-
}
|
| 791 |
-
|
| 792 |
-
.option input[type="radio"] {
|
| 793 |
-
width: 22px;
|
| 794 |
-
height: 22px;
|
| 795 |
-
margin-right: var(--space-md);
|
| 796 |
-
}
|
| 797 |
-
|
| 798 |
}
|
| 799 |
|
| 800 |
-
|
| 801 |
-
|
| 802 |
-
.custom-tooltip {
|
| 803 |
-
position: absolute;
|
| 804 |
-
background: var(--primary-dark);
|
| 805 |
-
color: var(--text-inverse);
|
| 806 |
-
padding: var(--space-xs) var(--space-sm);
|
| 807 |
-
border-radius: var(--radius-sm);
|
| 808 |
-
font-family: var(--font-family);
|
| 809 |
-
font-size: 13px;
|
| 810 |
-
font-weight: var(--font-weight-regular);
|
| 811 |
-
white-space: nowrap;
|
| 812 |
-
z-index: 10000;
|
| 813 |
-
pointer-events: none;
|
| 814 |
-
opacity: 0;
|
| 815 |
-
transition: opacity var(--transition-fast) ease-in-out;
|
| 816 |
-
top: -50px;
|
| 817 |
-
left: 50%;
|
| 818 |
-
transform: translateX(-50%);
|
| 819 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
* {
|
| 2 |
margin: 0;
|
| 3 |
padding: 0;
|
|
|
|
| 5 |
}
|
| 6 |
|
| 7 |
body {
|
| 8 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
| 9 |
+
background: #F5F5F5;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
min-height: 100vh;
|
| 11 |
display: flex;
|
| 12 |
justify-content: center;
|
| 13 |
align-items: center;
|
| 14 |
+
padding: 10px;
|
| 15 |
}
|
| 16 |
|
| 17 |
+
.container {
|
| 18 |
+
background: white;
|
| 19 |
+
border-radius: 16px;
|
| 20 |
+
padding: 20px;
|
| 21 |
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
max-width: 700px;
|
| 23 |
width: 100%;
|
| 24 |
+
animation: slideIn 0.4s ease;
|
| 25 |
max-height: 95vh;
|
| 26 |
overflow-y: auto;
|
| 27 |
}
|
| 28 |
|
| 29 |
+
/* Mobile Responsive */
|
| 30 |
+
@media (max-width: 768px) {
|
| 31 |
+
.container {
|
| 32 |
+
padding: 15px;
|
| 33 |
+
border-radius: 12px;
|
| 34 |
+
margin: 5px;
|
| 35 |
+
}
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
@keyframes slideIn {
|
| 39 |
from { opacity: 0; transform: translateY(20px); }
|
| 40 |
to { opacity: 1; transform: translateY(0); }
|
| 41 |
}
|
| 42 |
|
|
|
|
| 43 |
h1 {
|
| 44 |
+
color: #3D3D3D;
|
| 45 |
+
font-size: 28px;
|
| 46 |
+
margin-bottom: 8px;
|
| 47 |
text-align: center;
|
| 48 |
+
font-weight: 800;
|
| 49 |
}
|
| 50 |
|
| 51 |
+
/* Mobile Responsive */
|
| 52 |
+
@media (max-width: 768px) {
|
| 53 |
+
h1 {
|
| 54 |
+
font-size: 24px;
|
| 55 |
+
}
|
| 56 |
}
|
| 57 |
|
| 58 |
h3 {
|
| 59 |
text-align: center;
|
| 60 |
+
color: #3D3D3D;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
}
|
| 62 |
|
| 63 |
p {
|
| 64 |
+
color: #6B7280;
|
| 65 |
text-align: center;
|
| 66 |
+
margin-bottom: 30px;
|
| 67 |
+
font-size: 16px;
|
| 68 |
}
|
| 69 |
|
| 70 |
.subtitle {
|
| 71 |
+
color: #9CA3AF;
|
| 72 |
+
font-size: 15px;
|
| 73 |
text-align: center;
|
| 74 |
+
margin-bottom: 25px;
|
| 75 |
line-height: 1.6;
|
|
|
|
|
|
|
|
|
|
| 76 |
}
|
| 77 |
|
| 78 |
+
/* Mobile Responsive */
|
| 79 |
+
@media (max-width: 768px) {
|
| 80 |
+
p {
|
| 81 |
+
font-size: 18px;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
.subtitle {
|
| 85 |
+
font-size: 16px;
|
| 86 |
+
}
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
/* Form Inputs */
|
| 90 |
+
input[type="text"], input[type="password"] {
|
| 91 |
width: 100%;
|
| 92 |
+
padding: 14px 18px;
|
| 93 |
+
font-size: 16px;
|
| 94 |
border: none;
|
| 95 |
+
background: #F5F5F5;
|
| 96 |
+
border-radius: 10px;
|
| 97 |
+
transition: all 0.2s;
|
| 98 |
outline: none;
|
| 99 |
}
|
| 100 |
|
| 101 |
+
/* Mobile Responsive */
|
| 102 |
+
@media (max-width: 768px) {
|
| 103 |
+
input[type="text"], input[type="password"] {
|
| 104 |
+
padding: 16px 20px;
|
| 105 |
+
font-size: 18px;
|
| 106 |
+
}
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
input:focus {
|
| 110 |
background: #EBEBEB;
|
| 111 |
box-shadow: 0 0 0 2px #E5E5E5;
|
| 112 |
}
|
| 113 |
|
| 114 |
+
/* Buttons - Consolidated styles */
|
| 115 |
button, .btn, .nav-btn, .submit-btn {
|
| 116 |
+
padding: 14px 28px;
|
| 117 |
+
font-size: 16px;
|
| 118 |
+
background: #3D3D3D;
|
| 119 |
+
color: white;
|
| 120 |
border: none;
|
| 121 |
+
border-radius: 10px;
|
| 122 |
cursor: pointer;
|
| 123 |
+
transition: all 0.2s;
|
| 124 |
+
font-weight: 600;
|
| 125 |
text-decoration: none;
|
| 126 |
display: inline-block;
|
| 127 |
}
|
| 128 |
|
| 129 |
+
/* Mobile Responsive */
|
| 130 |
+
@media (max-width: 768px) {
|
| 131 |
+
button, .btn, .nav-btn, .submit-btn {
|
| 132 |
+
padding: 16px 32px;
|
| 133 |
+
font-size: 18px;
|
| 134 |
+
}
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
button:hover, .btn:hover, .nav-btn:hover, .submit-btn:hover {
|
| 138 |
+
background: #1A1A1A;
|
| 139 |
transform: translateY(-1px);
|
| 140 |
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
| 141 |
}
|
| 142 |
|
| 143 |
button:active, .btn:active {
|
|
|
|
| 157 |
transform: none;
|
| 158 |
}
|
| 159 |
|
| 160 |
+
/* Secondary Buttons - Consolidated */
|
| 161 |
+
.logout-btn, .reset-btn {
|
| 162 |
+
background: #6B7280;
|
| 163 |
+
padding: 8px 16px;
|
| 164 |
+
font-size: 13px;
|
| 165 |
+
margin-top: 15px;
|
|
|
|
| 166 |
}
|
| 167 |
|
| 168 |
+
.logout-btn:hover, .reset-btn:hover {
|
| 169 |
background: #4B5563;
|
| 170 |
+
box-shadow: 0 4px 12px rgba(107, 114, 128, 0.3);
|
| 171 |
}
|
| 172 |
|
| 173 |
/* Submit Button */
|
| 174 |
.submit-btn {
|
| 175 |
width: 100%;
|
| 176 |
+
padding: 16px;
|
| 177 |
+
font-size: 16px;
|
| 178 |
+
margin-top: 10px;
|
| 179 |
}
|
| 180 |
|
| 181 |
/* Auth Form */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
.auth-form input {
|
| 183 |
width: 100%;
|
| 184 |
+
margin-bottom: 15px;
|
| 185 |
}
|
| 186 |
|
| 187 |
.auth-form button {
|
| 188 |
width: 100%;
|
| 189 |
}
|
| 190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
.switch-link {
|
| 192 |
+
color: #3D3D3D;
|
| 193 |
text-decoration: none;
|
| 194 |
cursor: pointer;
|
| 195 |
+
font-weight: 600;
|
| 196 |
+
margin-top: 15px;
|
| 197 |
+
display: inline-block;
|
| 198 |
+
transition: color 0.2s;
|
|
|
|
|
|
|
| 199 |
}
|
| 200 |
|
| 201 |
.switch-link:hover {
|
| 202 |
+
color: #1A1A1A;
|
| 203 |
text-decoration: underline;
|
| 204 |
}
|
| 205 |
|
| 206 |
+
/* Question Blocks */
|
|
|
|
|
|
|
| 207 |
.question-block {
|
| 208 |
+
background: #FAFAFA;
|
| 209 |
+
padding: 25px;
|
| 210 |
+
border-radius: 12px;
|
| 211 |
+
margin-bottom: 20px;
|
| 212 |
border: none;
|
| 213 |
display: none;
|
| 214 |
min-height: 400px;
|
| 215 |
}
|
| 216 |
|
| 217 |
+
/* Mobile Responsive */
|
| 218 |
+
@media (max-width: 768px) {
|
| 219 |
+
.question-block {
|
| 220 |
+
padding: 20px;
|
| 221 |
+
min-height: 350px;
|
| 222 |
+
}
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
.question-block.active {
|
| 226 |
display: block;
|
| 227 |
+
animation: fadeIn 0.3s ease;
|
| 228 |
}
|
| 229 |
|
| 230 |
@keyframes fadeIn {
|
|
|
|
| 233 |
}
|
| 234 |
|
| 235 |
.question-block h4 {
|
| 236 |
+
color: #3D3D3D;
|
| 237 |
+
margin-bottom: 25px;
|
| 238 |
+
font-weight: 700;
|
| 239 |
+
font-size: 20px;
|
| 240 |
line-height: 1.6;
|
| 241 |
}
|
| 242 |
|
| 243 |
+
/* Mobile Responsive */
|
| 244 |
+
@media (max-width: 768px) {
|
| 245 |
+
.question-block h4 {
|
| 246 |
+
font-size: 22px;
|
| 247 |
+
}
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
.question-number {
|
| 251 |
display: inline-block;
|
| 252 |
+
background: #3D3D3D;
|
| 253 |
+
color: #fff;
|
| 254 |
width: 32px;
|
| 255 |
height: 32px;
|
| 256 |
+
border-radius: 50%;
|
| 257 |
text-align: center;
|
| 258 |
line-height: 32px;
|
| 259 |
+
margin-right: 12px;
|
| 260 |
+
font-size: 16px;
|
| 261 |
}
|
| 262 |
|
| 263 |
+
/* Options */
|
| 264 |
.option {
|
| 265 |
+
display: block;
|
| 266 |
+
padding: 18px 22px;
|
| 267 |
+
margin-bottom: 14px;
|
| 268 |
+
background: white;
|
|
|
|
| 269 |
border: none;
|
| 270 |
+
border-radius: 10px;
|
| 271 |
cursor: pointer;
|
| 272 |
+
transition: all 0.2s;
|
| 273 |
+
font-size: 16px;
|
| 274 |
+
color: #3D3D3D;
|
| 275 |
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
/* Mobile Responsive */
|
| 279 |
+
@media (max-width: 768px) {
|
| 280 |
+
.option {
|
| 281 |
+
padding: 20px 24px;
|
| 282 |
+
margin-bottom: 16px;
|
| 283 |
+
font-size: 18px;
|
| 284 |
+
}
|
| 285 |
}
|
| 286 |
|
| 287 |
.option:hover {
|
| 288 |
+
background: #F5F5F5;
|
| 289 |
transform: translateX(5px);
|
| 290 |
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
| 291 |
}
|
| 292 |
|
| 293 |
.option input[type="radio"] {
|
| 294 |
+
margin-right: 14px;
|
| 295 |
cursor: pointer;
|
| 296 |
+
width: 20px;
|
| 297 |
+
height: 20px;
|
| 298 |
+
}
|
| 299 |
+
|
| 300 |
+
/* Mobile Responsive */
|
| 301 |
+
@media (max-width: 768px) {
|
| 302 |
+
.option input[type="radio"] {
|
| 303 |
+
width: 22px;
|
| 304 |
+
height: 22px;
|
| 305 |
+
margin-right: 16px;
|
| 306 |
+
}
|
| 307 |
}
|
| 308 |
|
| 309 |
.option input[type="radio"]:disabled {
|
|
|
|
| 317 |
}
|
| 318 |
|
| 319 |
.option:has(input[type="radio"]:disabled):hover {
|
| 320 |
+
background: white;
|
| 321 |
transform: none;
|
| 322 |
}
|
| 323 |
|
| 324 |
+
/* Question Counter & Progress */
|
| 325 |
.question-counter {
|
| 326 |
text-align: center;
|
| 327 |
color: #999;
|
| 328 |
+
font-size: 16px;
|
| 329 |
+
margin-bottom: 15px;
|
| 330 |
+
font-weight: 600;
|
| 331 |
+
}
|
| 332 |
+
|
| 333 |
+
/* Mobile Responsive */
|
| 334 |
+
@media (max-width: 768px) {
|
| 335 |
+
.question-counter {
|
| 336 |
+
font-size: 18px;
|
| 337 |
+
}
|
| 338 |
}
|
| 339 |
|
| 340 |
.progress-bar {
|
| 341 |
+
background: #F5F5F5;
|
| 342 |
+
height: 8px;
|
| 343 |
border-radius: 4px;
|
| 344 |
overflow: hidden;
|
| 345 |
+
margin-bottom: 20px;
|
| 346 |
}
|
| 347 |
|
| 348 |
.progress-fill {
|
| 349 |
+
background: #3D3D3D;
|
| 350 |
height: 100%;
|
| 351 |
+
transition: width 0.3s;
|
| 352 |
}
|
| 353 |
|
| 354 |
+
/* Navigation */
|
| 355 |
.nav-buttons {
|
| 356 |
display: flex;
|
| 357 |
+
gap: 12px;
|
| 358 |
justify-content: flex-start;
|
| 359 |
+
margin-top: 20px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 360 |
}
|
| 361 |
|
| 362 |
.buttons-row {
|
| 363 |
display: flex;
|
| 364 |
+
gap: 10px;
|
| 365 |
justify-content: center;
|
| 366 |
+
margin-top: 20px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 367 |
}
|
| 368 |
|
| 369 |
+
/* Results */
|
| 370 |
.result-card {
|
| 371 |
+
padding: 25px;
|
| 372 |
+
border-radius: 12px;
|
| 373 |
+
margin-bottom: 20px;
|
| 374 |
border: none;
|
| 375 |
+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
|
| 376 |
}
|
| 377 |
|
| 378 |
.result-card.rank-1 {
|
| 379 |
+
background: #FFFACD;
|
| 380 |
}
|
| 381 |
|
| 382 |
.result-card.rank-2 {
|
| 383 |
+
background: #B4C7E7;
|
| 384 |
}
|
| 385 |
|
| 386 |
.result-card.rank-3 {
|
| 387 |
+
background: #90EE90;
|
| 388 |
}
|
| 389 |
|
| 390 |
.result-header {
|
| 391 |
display: flex;
|
| 392 |
align-items: center;
|
| 393 |
justify-content: space-between;
|
| 394 |
+
margin-bottom: 15px;
|
| 395 |
}
|
| 396 |
|
| 397 |
.result-rank {
|
| 398 |
+
color: #fff;
|
| 399 |
+
width: 40px;
|
| 400 |
+
height: 40px;
|
| 401 |
+
border-radius: 50%;
|
| 402 |
display: flex;
|
| 403 |
align-items: center;
|
| 404 |
justify-content: center;
|
| 405 |
+
font-size: 20px;
|
| 406 |
+
font-weight: 800;
|
| 407 |
+
background: #3D3D3D;
|
| 408 |
}
|
| 409 |
|
| 410 |
.result-title {
|
| 411 |
flex: 1;
|
| 412 |
+
margin-left: 15px;
|
| 413 |
}
|
| 414 |
|
| 415 |
.result-title h3 {
|
| 416 |
+
font-size: 22px;
|
| 417 |
margin-bottom: 5px;
|
| 418 |
+
color: #3D3D3D;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 419 |
}
|
| 420 |
|
| 421 |
.result-percentage {
|
| 422 |
+
font-size: 24px;
|
| 423 |
+
font-weight: 800;
|
| 424 |
+
color: #3D3D3D;
|
| 425 |
}
|
| 426 |
|
| 427 |
.result-description {
|
| 428 |
color: #666;
|
| 429 |
line-height: 1.6;
|
| 430 |
+
margin-bottom: 12px;
|
| 431 |
+
font-size: 14px;
|
| 432 |
}
|
| 433 |
|
| 434 |
.result-details {
|
| 435 |
background: rgba(255, 255, 255, 0.6);
|
| 436 |
border: none;
|
| 437 |
+
padding: 15px;
|
| 438 |
+
border-radius: 8px;
|
| 439 |
+
margin-top: 15px;
|
| 440 |
}
|
| 441 |
|
| 442 |
.result-details h5 {
|
| 443 |
+
color: #3D3D3D;
|
| 444 |
+
font-size: 13px;
|
| 445 |
+
margin-bottom: 8px;
|
| 446 |
+
font-weight: 700;
|
| 447 |
}
|
| 448 |
|
| 449 |
.result-details p {
|
| 450 |
color: #666;
|
| 451 |
+
font-size: 13px;
|
| 452 |
+
margin-bottom: 10px;
|
| 453 |
text-align: left;
|
| 454 |
}
|
| 455 |
|
| 456 |
+
/* Icons & Messages */
|
| 457 |
.icon {
|
| 458 |
+
font-size: 24px;
|
| 459 |
+
margin-right: 8px;
|
| 460 |
}
|
| 461 |
|
| 462 |
.success-msg {
|
| 463 |
+
color: #3D3D3D;
|
| 464 |
+
font-weight: 600;
|
| 465 |
}
|
| 466 |
|
| 467 |
.error-msg {
|
| 468 |
color: #666;
|
| 469 |
+
font-weight: 600;
|
| 470 |
text-align: center;
|
| 471 |
+
padding: 10px;
|
| 472 |
}
|
| 473 |
|
| 474 |
+
/* Chat Interface */
|
| 475 |
.chat-toggle-btn {
|
| 476 |
background: rgba(255, 255, 255, 0.8);
|
| 477 |
+
color: #3D3D3D;
|
| 478 |
border: none;
|
| 479 |
+
padding: 10px 20px;
|
| 480 |
+
border-radius: 8px;
|
| 481 |
cursor: pointer;
|
| 482 |
+
font-size: 14px;
|
| 483 |
+
font-weight: 600;
|
| 484 |
+
margin-top: 15px;
|
| 485 |
width: 100%;
|
| 486 |
+
transition: background 0.2s, color 0.2s;
|
| 487 |
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
| 488 |
}
|
| 489 |
|
| 490 |
.chat-toggle-btn:hover {
|
| 491 |
+
background: #3D3D3D;
|
| 492 |
+
color: #fff;
|
| 493 |
}
|
| 494 |
|
| 495 |
.chat-window {
|
| 496 |
display: none;
|
| 497 |
background: rgba(255, 255, 255, 0.9);
|
| 498 |
border: none;
|
| 499 |
+
border-radius: 10px;
|
| 500 |
+
margin-top: 15px;
|
| 501 |
overflow: hidden;
|
| 502 |
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
| 503 |
}
|
| 504 |
|
| 505 |
.chat-window.open {
|
| 506 |
display: block;
|
| 507 |
+
animation: slideDown 0.3s ease;
|
| 508 |
}
|
| 509 |
|
| 510 |
@keyframes slideDown {
|
|
|
|
| 515 |
.chat-messages {
|
| 516 |
height: 250px;
|
| 517 |
overflow-y: auto;
|
| 518 |
+
padding: 15px;
|
| 519 |
+
background: transparent;
|
| 520 |
}
|
| 521 |
|
| 522 |
.chat-message {
|
| 523 |
+
margin-bottom: 12px;
|
| 524 |
+
padding: 10px 14px;
|
| 525 |
+
border-radius: 8px;
|
| 526 |
max-width: 85%;
|
| 527 |
line-height: 1.5;
|
| 528 |
+
font-size: 14px;
|
| 529 |
}
|
| 530 |
|
| 531 |
.chat-message.user {
|
| 532 |
+
background: #3D3D3D;
|
| 533 |
+
color: #fff;
|
| 534 |
margin-left: auto;
|
| 535 |
text-align: right;
|
| 536 |
}
|
| 537 |
|
| 538 |
.chat-message.bot {
|
| 539 |
+
background: white;
|
| 540 |
+
color: #3D3D3D;
|
| 541 |
border: none;
|
| 542 |
text-align: left;
|
| 543 |
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
|
| 544 |
}
|
| 545 |
|
| 546 |
.chat-message.bot ul {
|
| 547 |
+
margin: 8px 0 0 0;
|
| 548 |
+
padding-left: 20px;
|
| 549 |
}
|
| 550 |
|
| 551 |
.chat-message.bot li {
|
|
|
|
| 555 |
|
| 556 |
.chat-input-area {
|
| 557 |
display: flex;
|
| 558 |
+
gap: 8px;
|
| 559 |
+
padding: 12px;
|
|
|
|
| 560 |
background: transparent;
|
| 561 |
border-top: none;
|
|
|
|
| 562 |
}
|
| 563 |
|
| 564 |
.chat-input {
|
| 565 |
flex: 1;
|
| 566 |
+
padding: 10px 14px;
|
| 567 |
border: none;
|
| 568 |
+
background: white;
|
| 569 |
+
border-radius: 8px;
|
| 570 |
+
font-size: 14px;
|
| 571 |
outline: none;
|
| 572 |
+
color: #3D3D3D;
|
| 573 |
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
|
| 574 |
}
|
| 575 |
|
| 576 |
.chat-input:focus {
|
| 577 |
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
| 578 |
}
|
| 579 |
|
|
|
|
|
|
|
| 580 |
.chat-send-btn {
|
| 581 |
+
padding: 10px 20px;
|
| 582 |
+
background: #3D3D3D;
|
| 583 |
+
color: #fff;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 584 |
border: none;
|
| 585 |
+
border-radius: 8px;
|
| 586 |
cursor: pointer;
|
| 587 |
+
font-weight: 600;
|
| 588 |
+
font-size: 14px;
|
| 589 |
+
transition: background 0.2s;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 590 |
}
|
| 591 |
|
| 592 |
.chat-send-btn:hover {
|
| 593 |
+
background: #1A1A1A;
|
| 594 |
+
color: #fff;
|
| 595 |
}
|
| 596 |
|
| 597 |
.chat-send-btn:disabled {
|
| 598 |
+
background: #F5F5F5;
|
| 599 |
color: #999;
|
| 600 |
+
cursor: not-allowed;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 601 |
}
|
| 602 |
|
| 603 |
.chat-typing {
|
| 604 |
color: #999;
|
| 605 |
font-style: italic;
|
| 606 |
+
font-size: 13px;
|
| 607 |
+
padding: 10px 14px;
|
| 608 |
}
|
| 609 |
|
| 610 |
+
/* Navigation Header */
|
| 611 |
.nav-header {
|
| 612 |
+
padding: 0 0 20px 0;
|
| 613 |
+
margin-bottom: 20px;
|
| 614 |
+
border-bottom: 1px solid #e9ecef;
|
| 615 |
}
|
| 616 |
|
| 617 |
.back-link {
|
| 618 |
color: #667eea;
|
| 619 |
text-decoration: none;
|
| 620 |
+
font-weight: 600;
|
| 621 |
+
font-size: 14px;
|
| 622 |
+
transition: all 0.3s ease;
|
| 623 |
display: inline-flex;
|
| 624 |
align-items: center;
|
| 625 |
gap: 4px;
|
|
|
|
| 626 |
}
|
| 627 |
|
| 628 |
.back-link:hover {
|
|
|
|
| 630 |
transform: translateX(-3px);
|
| 631 |
}
|
| 632 |
|
| 633 |
+
/* Results description max-width */
|
| 634 |
+
.subtitle {
|
| 635 |
+
max-width: 500px;
|
| 636 |
+
margin: 0 auto;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 637 |
}
|
| 638 |
|
| 639 |
+
.results-spacing {
|
| 640 |
+
margin-top: 40px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 641 |
}
|
static/video/Animation (Light theme).mp4
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:c53cd9d87f17d8c3e0500572a448609819d7bb1f44d61e19727c65ed15977ac1
|
| 3 |
-
size 6026968
|
|
|
|
|
|
|
|
|
|
|
|
templates/index.html
CHANGED
|
@@ -5,136 +5,36 @@
|
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
<title>{{ title if logged_in else 'Spiritual Path Finder - Login' }}</title>
|
| 7 |
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
| 8 |
-
<!-- Add Font Awesome here -->
|
| 9 |
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
| 10 |
-
|
| 11 |
-
<!-- Firebase SDK -->
|
| 12 |
-
<script src="https://www.gstatic.com/firebasejs/10.7.1/firebase-app-compat.js"></script>
|
| 13 |
-
<script src="https://www.gstatic.com/firebasejs/10.7.1/firebase-auth-compat.js"></script>
|
| 14 |
-
|
| 15 |
-
{% if firebase_config and firebase_config.apiKey %}
|
| 16 |
-
<script>
|
| 17 |
-
// Initialize Firebase
|
| 18 |
-
const firebaseConfig = {
|
| 19 |
-
apiKey: "{{ firebase_config.apiKey }}",
|
| 20 |
-
authDomain: "{{ firebase_config.authDomain }}",
|
| 21 |
-
projectId: "{{ firebase_config.projectId }}",
|
| 22 |
-
storageBucket: "{{ firebase_config.storageBucket }}",
|
| 23 |
-
messagingSenderId: "{{ firebase_config.messagingSenderId }}",
|
| 24 |
-
appId: "{{ firebase_config.appId }}"
|
| 25 |
-
};
|
| 26 |
-
firebase.initializeApp(firebaseConfig);
|
| 27 |
-
window.firebaseAuth = firebase.auth();
|
| 28 |
-
window.firebaseEnabled = true;
|
| 29 |
-
</script>
|
| 30 |
-
{% else %}
|
| 31 |
-
<script>
|
| 32 |
-
window.firebaseEnabled = false;
|
| 33 |
-
</script>
|
| 34 |
-
{% endif %}
|
| 35 |
</head>
|
| 36 |
<body>
|
| 37 |
-
<div class="
|
| 38 |
<div class="nav-header">
|
| 39 |
<a href="/" class="back-link">β Back to Home</a>
|
| 40 |
</div>
|
| 41 |
{% if not logged_in %}
|
| 42 |
<!-- Login/Signup Form -->
|
| 43 |
-
<
|
| 44 |
<p>{{ 'Begin your journey of self-discovery' if is_signup else 'Welcome back, seeker!' }}</p>
|
| 45 |
|
| 46 |
-
{% if verify_success %}
|
| 47 |
-
<div class="success-msg" style="padding: 15px; margin-bottom: 20px; border-radius: 8px;">
|
| 48 |
-
β
Email verified successfully! You can now sign in.
|
| 49 |
-
</div>
|
| 50 |
-
{% endif %}
|
| 51 |
-
|
| 52 |
-
{% if verify_error %}
|
| 53 |
-
<div class="error-msg" style="padding: 15px; margin-bottom: 20px; border-radius: 8px;">
|
| 54 |
-
β οΈ {{ verify_error }}
|
| 55 |
-
</div>
|
| 56 |
-
{% endif %}
|
| 57 |
-
|
| 58 |
-
{% if reset_error %}
|
| 59 |
-
<div class="error-msg" style="padding: 15px; margin-bottom: 20px; border-radius: 8px;">
|
| 60 |
-
β οΈ {{ reset_error }}
|
| 61 |
-
</div>
|
| 62 |
-
{% endif %}
|
| 63 |
-
|
| 64 |
<div class="auth-form">
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
{% if firebase_config and firebase_config.apiKey %}
|
| 68 |
-
<button class="google-signin-btn" onclick="signInWithGoogle()">
|
| 69 |
-
<svg width="18" height="18" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
| 70 |
-
<path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"/>
|
| 71 |
-
<path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"/>
|
| 72 |
-
<path fill="#FBBC05" d="M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z"/>
|
| 73 |
-
<path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"/>
|
| 74 |
-
<path fill="none" d="M0 0h48v48H0z"/>
|
| 75 |
-
</svg>
|
| 76 |
-
Continue with Google
|
| 77 |
-
</button>
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
<!-- Hide email/password sign-in temporarily -------------------------------------->
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
<!-- <div class="divider">
|
| 84 |
-
<span>or</span>
|
| 85 |
-
</div>
|
| 86 |
-
{% endif %}
|
| 87 |
-
|
| 88 |
-
{% if firebase_config and firebase_config.apiKey %}
|
| 89 |
-
<input type="email" id="authEmail" placeholder="Email">
|
| 90 |
-
{% else %}
|
| 91 |
-
<input type="text" id="authUsername" placeholder="User name">
|
| 92 |
-
{% endif %}
|
| 93 |
-
{% if is_signup and firebase_config and firebase_config.apiKey %}
|
| 94 |
-
<input type="text" id="authUsername" placeholder="Display Name (optional)">
|
| 95 |
-
{% elif not firebase_config or not firebase_config.apiKey %}
|
| 96 |
-
{% if is_signup %}
|
| 97 |
-
<input type="email" id="authEmail" placeholder="Email">
|
| 98 |
-
{% endif %}
|
| 99 |
-
{% endif %}
|
| 100 |
-
|
| 101 |
<button onclick="authenticate()">{{ 'Sign Up' if is_signup else 'Sign In' }}</button>
|
| 102 |
<div id="result"></div>
|
| 103 |
-
{% if not is_signup %}
|
| 104 |
-
<p class="switch-link" onclick="window.location.href='/forgot-password'">
|
| 105 |
-
Forgot Password?
|
| 106 |
-
</p>
|
| 107 |
-
{% endif %}
|
| 108 |
<p class="switch-link" onclick="switchAuth()">
|
| 109 |
{{ 'Already have an account? Sign In' if is_signup else 'New here? Sign Up' }}
|
| 110 |
</p>
|
| 111 |
-
</div>
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
{% else %}
|
| 115 |
-
{% if show_reset_form %}
|
| 116 |
-
<input type="password" id="resetPassword" placeholder="New Password">
|
| 117 |
-
<input type="hidden" id="resetToken" value="{{ reset_token }}">
|
| 118 |
-
<button onclick="submitPasswordReset()">Reset Password</button>
|
| 119 |
-
<div id="result"></div>
|
| 120 |
-
{% else %}
|
| 121 |
-
<input type="email" id="resetEmail" placeholder="Email">
|
| 122 |
-
<button onclick="resetPassword()">Send Reset Link</button>
|
| 123 |
-
<div id="result"></div>
|
| 124 |
-
{% endif %}
|
| 125 |
-
<p class="switch-link" onclick="window.location.href='/login'">
|
| 126 |
-
Back to Sign In
|
| 127 |
-
</p>
|
| 128 |
-
{% endif %} -->
|
| 129 |
</div>
|
| 130 |
{% else %}
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
<h2>{{ title }}</h2>
|
| 135 |
-
<p>{{ message }} <i class="fas fa-heart"></i> </p>
|
| 136 |
|
| 137 |
{% if not has_results %}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
|
| 139 |
<div class="question-counter" id="questionCounter">Question 1 of {{ questions|length }}</div>
|
| 140 |
|
|
@@ -185,9 +85,6 @@
|
|
| 185 |
<p class="subtitle">
|
| 186 |
Based on your responses, here are the spiritual paths that align most closely with your values and beliefs:
|
| 187 |
</p>
|
| 188 |
-
<div class="results-explanation">
|
| 189 |
-
* Percentages reflect how strongly your answers align with each path, using weighted scoring where more fundamental beliefs count more.
|
| 190 |
-
</div>
|
| 191 |
|
| 192 |
<div id="resultsContainer" class="results-spacing">
|
| 193 |
{% for result in results %}
|
|
@@ -201,21 +98,21 @@
|
|
| 201 |
</div>
|
| 202 |
<p class="result-description">{{ result.description }}</p>
|
| 203 |
<div class="result-details">
|
| 204 |
-
<h5
|
| 205 |
<p>{{ result.practices }}</p>
|
| 206 |
-
<h5
|
| 207 |
<p>{{ result.core_beliefs }}</p>
|
| 208 |
</div>
|
| 209 |
|
| 210 |
<button class="chat-toggle-btn" onclick="toggleChat('{{ result.name }}')">
|
| 211 |
-
|
| 212 |
</button>
|
| 213 |
|
| 214 |
<div class="chat-window" id="chat-{{ result.name|replace(' ', '-') }}">
|
| 215 |
<div class="chat-messages" id="messages-{{ result.name|replace(' ', '-') }}">
|
| 216 |
<div class="chat-message bot">
|
| 217 |
Hi! Ask me anything about {{ result.name }}.<br>
|
| 218 |
-
<span style="color:#
|
| 219 |
Example: "How do I get started with this path?"
|
| 220 |
</span>
|
| 221 |
</div>
|
|
@@ -224,21 +121,12 @@
|
|
| 224 |
<input type="text"
|
| 225 |
class="chat-input"
|
| 226 |
id="input-{{ result.name|replace(' ', '-') }}"
|
| 227 |
-
placeholder="Ask
|
| 228 |
onkeypress="if(event.key==='Enter') sendMessage('{{ result.name }}')">
|
| 229 |
-
<button class="voice-btn"
|
| 230 |
-
id="voice-{{ result.name|replace(' ', '-') }}"
|
| 231 |
-
onmousedown="startVoiceInput('{{ result.name }}')"
|
| 232 |
-
onmouseup="stopVoiceInput('{{ result.name }}')"
|
| 233 |
-
ontouchstart="startVoiceInput('{{ result.name }}')"
|
| 234 |
-
ontouchend="stopVoiceInput('{{ result.name }}')"
|
| 235 |
-
title="Hold to record with live transcription">
|
| 236 |
-
<i class="fa-solid fa-microphone"></i>
|
| 237 |
-
</button>
|
| 238 |
<button class="chat-send-btn"
|
| 239 |
id="send-{{ result.name|replace(' ', '-') }}"
|
| 240 |
-
onclick="sendMessage('{{ result.name }}')"
|
| 241 |
-
|
| 242 |
</button>
|
| 243 |
</div>
|
| 244 |
</div>
|
|
@@ -247,15 +135,8 @@
|
|
| 247 |
</div>
|
| 248 |
|
| 249 |
<div class="buttons-row">
|
| 250 |
-
<button class="btn reset-btn" onclick="resetAssessment()">
|
| 251 |
-
|
| 252 |
-
</button>
|
| 253 |
-
<button class="btn share-btn" onclick="shareResults()">
|
| 254 |
-
<i class="fa-solid fa-share-nodes"></i> Share Results
|
| 255 |
-
</button>
|
| 256 |
-
<a href="/logout" class="btn logout-btn">
|
| 257 |
-
<i class="fa-solid fa-arrow-right-from-bracket"></i> Sign Out
|
| 258 |
-
</a>
|
| 259 |
</div>
|
| 260 |
{% endif %}
|
| 261 |
{% endif %}
|
|
|
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
<title>{{ title if logged_in else 'Spiritual Path Finder - Login' }}</title>
|
| 7 |
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
</head>
|
| 9 |
<body>
|
| 10 |
+
<div class="container">
|
| 11 |
<div class="nav-header">
|
| 12 |
<a href="/" class="back-link">β Back to Home</a>
|
| 13 |
</div>
|
| 14 |
{% if not logged_in %}
|
| 15 |
<!-- Login/Signup Form -->
|
| 16 |
+
<h1><span class="icon">π</span>Spiritual Path Finder</h1>
|
| 17 |
<p>{{ 'Begin your journey of self-discovery' if is_signup else 'Welcome back, seeker!' }}</p>
|
| 18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
<div class="auth-form">
|
| 20 |
+
<input type="text" id="authUsername" placeholder="Username">
|
| 21 |
+
<input type="password" id="authPassword" placeholder="Password">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
<button onclick="authenticate()">{{ 'Sign Up' if is_signup else 'Sign In' }}</button>
|
| 23 |
<div id="result"></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
<p class="switch-link" onclick="switchAuth()">
|
| 25 |
{{ 'Already have an account? Sign In' if is_signup else 'New here? Sign Up' }}
|
| 26 |
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
</div>
|
| 28 |
{% else %}
|
| 29 |
+
<!-- Assessment Interface -->
|
| 30 |
+
<h1>{{ title }}</h1>
|
| 31 |
+
<p>{{ message }}</p>
|
|
|
|
|
|
|
| 32 |
|
| 33 |
{% if not has_results %}
|
| 34 |
+
<p class="subtitle">
|
| 35 |
+
Discover which spiritual or religious path aligns with your beliefs, values, and lifestyle.
|
| 36 |
+
<br> Answer 8 thoughtful questions about your worldview.
|
| 37 |
+
</p>
|
| 38 |
|
| 39 |
<div class="question-counter" id="questionCounter">Question 1 of {{ questions|length }}</div>
|
| 40 |
|
|
|
|
| 85 |
<p class="subtitle">
|
| 86 |
Based on your responses, here are the spiritual paths that align most closely with your values and beliefs:
|
| 87 |
</p>
|
|
|
|
|
|
|
|
|
|
| 88 |
|
| 89 |
<div id="resultsContainer" class="results-spacing">
|
| 90 |
{% for result in results %}
|
|
|
|
| 98 |
</div>
|
| 99 |
<p class="result-description">{{ result.description }}</p>
|
| 100 |
<div class="result-details">
|
| 101 |
+
<h5>πΏ Common Practices:</h5>
|
| 102 |
<p>{{ result.practices }}</p>
|
| 103 |
+
<h5>π Core Beliefs:</h5>
|
| 104 |
<p>{{ result.core_beliefs }}</p>
|
| 105 |
</div>
|
| 106 |
|
| 107 |
<button class="chat-toggle-btn" onclick="toggleChat('{{ result.name }}')">
|
| 108 |
+
π¬ Ask Questions About {{ result.name }}
|
| 109 |
</button>
|
| 110 |
|
| 111 |
<div class="chat-window" id="chat-{{ result.name|replace(' ', '-') }}">
|
| 112 |
<div class="chat-messages" id="messages-{{ result.name|replace(' ', '-') }}">
|
| 113 |
<div class="chat-message bot">
|
| 114 |
Hi! Ask me anything about {{ result.name }}.<br>
|
| 115 |
+
<span style="color:#7C3AED; font-size:13px;">
|
| 116 |
Example: "How do I get started with this path?"
|
| 117 |
</span>
|
| 118 |
</div>
|
|
|
|
| 121 |
<input type="text"
|
| 122 |
class="chat-input"
|
| 123 |
id="input-{{ result.name|replace(' ', '-') }}"
|
| 124 |
+
placeholder="Ask about {{ result.name }}..."
|
| 125 |
onkeypress="if(event.key==='Enter') sendMessage('{{ result.name }}')">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
<button class="chat-send-btn"
|
| 127 |
id="send-{{ result.name|replace(' ', '-') }}"
|
| 128 |
+
onclick="sendMessage('{{ result.name }}')">
|
| 129 |
+
Send
|
| 130 |
</button>
|
| 131 |
</div>
|
| 132 |
</div>
|
|
|
|
| 135 |
</div>
|
| 136 |
|
| 137 |
<div class="buttons-row">
|
| 138 |
+
<button class="btn reset-btn" onclick="resetAssessment()">π Retake Assessment</button>
|
| 139 |
+
<a href="/logout" class="btn logout-btn">πͺ Sign Out</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
</div>
|
| 141 |
{% endif %}
|
| 142 |
{% endif %}
|
templates/landing.html
CHANGED
|
@@ -6,35 +6,26 @@
|
|
| 6 |
<title>Spiritual Path Assessment</title>
|
| 7 |
<link rel="stylesheet" href="{{ url_for('static', filename='landing.css') }}">
|
| 8 |
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
| 9 |
-
<!-- Add Font Awesome here -->
|
| 10 |
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
| 11 |
</head>
|
| 12 |
<body>
|
| 13 |
<div class="gradient-bg"></div>
|
| 14 |
|
| 15 |
<nav class="navbar">
|
| 16 |
<div class="nav-container">
|
| 17 |
-
<div class="logo"
|
| 18 |
-
|
| 19 |
</div>
|
| 20 |
</nav>
|
| 21 |
|
| 22 |
<main class="main-content">
|
| 23 |
<section class="hero-section">
|
| 24 |
-
<!-- Video Background -->
|
| 25 |
-
<video class="hero-video" autoplay muted loop playsinline preload="auto">
|
| 26 |
-
<source src="{{ url_for('static', filename='video/Animation (Light theme).mp4') }}" type="video/mp4">
|
| 27 |
-
Your browser does not support the video tag.
|
| 28 |
-
</video>
|
| 29 |
-
|
| 30 |
<div class="hero-container">
|
| 31 |
-
<div class="badge"
|
| 32 |
<h1 class="hero-title">
|
| 33 |
-
Find Your Spiritual Journey
|
| 34 |
</h1>
|
| 35 |
<p class="hero-subtitle">
|
| 36 |
-
|
| 37 |
-
Answer 9 thoughtful questions to gain deep insights into your worldview.
|
| 38 |
</p>
|
| 39 |
|
| 40 |
<div class="cta-buttons">
|
|
@@ -43,9 +34,24 @@
|
|
| 43 |
<span class="arrow">β</span>
|
| 44 |
</a>
|
| 45 |
<div class="assessment-meta">
|
| 46 |
-
<span
|
| 47 |
-
<span
|
| 48 |
-
<span
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
</div>
|
| 50 |
</div>
|
| 51 |
</div>
|
|
@@ -55,31 +61,29 @@
|
|
| 55 |
<div class="section-container">
|
| 56 |
<div class="section-header">
|
| 57 |
<h2>What You'll Discover</h2>
|
| 58 |
-
<p
|
| 59 |
-
After completing the assessment, explore your top 3 spiritual paths and ask questions through our interactive chat feature.
|
| 60 |
-
</p>
|
| 61 |
</div>
|
| 62 |
|
| 63 |
<div class="features-grid">
|
| 64 |
<div class="feature-card">
|
| 65 |
<div class="feature-icon-wrapper">
|
| 66 |
-
<
|
| 67 |
</div>
|
| 68 |
<h3>Your Spiritual Dimensions</h3>
|
| 69 |
<p>Understand your current spiritual development across multiple dimensions and uncover hidden aspects of your journey.</p>
|
| 70 |
</div>
|
| 71 |
-
|
| 72 |
<div class="feature-card">
|
| 73 |
<div class="feature-icon-wrapper">
|
| 74 |
-
<
|
| 75 |
</div>
|
| 76 |
<h3>Personalized Recommendations</h3>
|
| 77 |
<p>Get specific guidance tailored to your unique spiritual path, beliefs, and goals for meaningful growth.</p>
|
| 78 |
</div>
|
| 79 |
-
|
| 80 |
<div class="feature-card">
|
| 81 |
<div class="feature-icon-wrapper">
|
| 82 |
-
<
|
| 83 |
</div>
|
| 84 |
<h3>Growth Opportunities</h3>
|
| 85 |
<p>Identify areas for spiritual growth and receive practical steps to deepen your practice and understanding.</p>
|
|
@@ -92,7 +96,7 @@
|
|
| 92 |
<div class="cta-container">
|
| 93 |
<h2>Ready to begin your journey?</h2>
|
| 94 |
<p>Start your spiritual path assessment today</p>
|
| 95 |
-
<a href="/login" class="btn-
|
| 96 |
Get Started Now
|
| 97 |
<span class="arrow">β</span>
|
| 98 |
</a>
|
|
|
|
| 6 |
<title>Spiritual Path Assessment</title>
|
| 7 |
<link rel="stylesheet" href="{{ url_for('static', filename='landing.css') }}">
|
| 8 |
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
|
|
|
|
|
|
| 9 |
</head>
|
| 10 |
<body>
|
| 11 |
<div class="gradient-bg"></div>
|
| 12 |
|
| 13 |
<nav class="navbar">
|
| 14 |
<div class="nav-container">
|
| 15 |
+
<div class="logo">β¨ Spiritual Path</div>
|
| 16 |
+
<a href="/login" class="nav-cta">Start Assessment</a>
|
| 17 |
</div>
|
| 18 |
</nav>
|
| 19 |
|
| 20 |
<main class="main-content">
|
| 21 |
<section class="hero-section">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
<div class="hero-container">
|
| 23 |
+
<div class="badge">π Discover Your Path</div>
|
| 24 |
<h1 class="hero-title">
|
| 25 |
+
Find Your <span class="gradient-text">Spiritual Journey</span>
|
| 26 |
</h1>
|
| 27 |
<p class="hero-subtitle">
|
| 28 |
+
A personalized assessment designed to help you explore and understand your unique spiritual path through thoughtful questions and AI-powered insights.
|
|
|
|
| 29 |
</p>
|
| 30 |
|
| 31 |
<div class="cta-buttons">
|
|
|
|
| 34 |
<span class="arrow">β</span>
|
| 35 |
</a>
|
| 36 |
<div class="assessment-meta">
|
| 37 |
+
<span>β±οΈ 5-10 minutes</span>
|
| 38 |
+
<span>π Completely free</span>
|
| 39 |
+
<span>π§ Personalized insights</span>
|
| 40 |
+
</div>
|
| 41 |
+
</div>
|
| 42 |
+
|
| 43 |
+
<div class="hero-visual" style="display: none;">
|
| 44 |
+
<div class="floating-card card-1">
|
| 45 |
+
<div class="card-icon">π§</div>
|
| 46 |
+
<div class="card-text">Personalized Insights</div>
|
| 47 |
+
</div>
|
| 48 |
+
<div class="floating-card card-2">
|
| 49 |
+
<div class="card-icon">π</div>
|
| 50 |
+
<div class="card-text">Deep Analysis</div>
|
| 51 |
+
</div>
|
| 52 |
+
<div class="floating-card card-3">
|
| 53 |
+
<div class="card-icon">π―</div>
|
| 54 |
+
<div class="card-text">Actionable Guidance</div>
|
| 55 |
</div>
|
| 56 |
</div>
|
| 57 |
</div>
|
|
|
|
| 61 |
<div class="section-container">
|
| 62 |
<div class="section-header">
|
| 63 |
<h2>What You'll Discover</h2>
|
| 64 |
+
<p>Comprehensive insights into your spiritual journey</p>
|
|
|
|
|
|
|
| 65 |
</div>
|
| 66 |
|
| 67 |
<div class="features-grid">
|
| 68 |
<div class="feature-card">
|
| 69 |
<div class="feature-icon-wrapper">
|
| 70 |
+
<div class="feature-icon">π</div>
|
| 71 |
</div>
|
| 72 |
<h3>Your Spiritual Dimensions</h3>
|
| 73 |
<p>Understand your current spiritual development across multiple dimensions and uncover hidden aspects of your journey.</p>
|
| 74 |
</div>
|
| 75 |
+
|
| 76 |
<div class="feature-card">
|
| 77 |
<div class="feature-icon-wrapper">
|
| 78 |
+
<div class="feature-icon">π‘</div>
|
| 79 |
</div>
|
| 80 |
<h3>Personalized Recommendations</h3>
|
| 81 |
<p>Get specific guidance tailored to your unique spiritual path, beliefs, and goals for meaningful growth.</p>
|
| 82 |
</div>
|
| 83 |
+
|
| 84 |
<div class="feature-card">
|
| 85 |
<div class="feature-icon-wrapper">
|
| 86 |
+
<div class="feature-icon">π</div>
|
| 87 |
</div>
|
| 88 |
<h3>Growth Opportunities</h3>
|
| 89 |
<p>Identify areas for spiritual growth and receive practical steps to deepen your practice and understanding.</p>
|
|
|
|
| 96 |
<div class="cta-container">
|
| 97 |
<h2>Ready to begin your journey?</h2>
|
| 98 |
<p>Start your spiritual path assessment today</p>
|
| 99 |
+
<a href="/login" class="btn-secondary">
|
| 100 |
Get Started Now
|
| 101 |
<span class="arrow">β</span>
|
| 102 |
</a>
|
test
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
test
|
tsne_visualization.html
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|