Upload 4 files
Browse files- Apache License.txt +17 -0
- README.md +92 -0
- index.html +1532 -0
- 📘 Step-by-Step Guide.txt +76 -0
Apache License.txt
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Apache License
|
| 2 |
+
Version 2.0, January 2004
|
| 3 |
+
http://www.apache.org/licenses/
|
| 4 |
+
|
| 5 |
+
Copyright 2025 Shift Mind AI Labs
|
| 6 |
+
|
| 7 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
you may not use this file except in compliance with the License.
|
| 9 |
+
You may obtain a copy of the License at
|
| 10 |
+
|
| 11 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
|
| 13 |
+
Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
See the License for the specific language governing permissions and
|
| 17 |
+
limitations under the License.
|
README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: "🌍 Cultural Intelligence Explorer"
|
| 3 |
+
emoji: "🧭"
|
| 4 |
+
colorFrom: "purple"
|
| 5 |
+
colorTo: "red"
|
| 6 |
+
sdk: "static"
|
| 7 |
+
sdk_version: "0.1.0"
|
| 8 |
+
app_file: "index.html"
|
| 9 |
+
pinned: false
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
# 🌍 Cultural Intelligence Explorer – Global Edition with AI Analysis
|
| 13 |
+
**Developed by Shift Mind AI Labs**
|
| 14 |
+
|
| 15 |
+
The Cultural Intelligence Explorer is an open-source, browser-based learning tool that empowers students, educators, and global citizens to deeply explore world cultures, compare cultural themes, and develop empathy and global citizenship skills. With an integrated AI engine (via your OpenAI API key), users can select any country, focus on cultural themes, receive rich AI-generated insights, reflect on their learning, and receive a personal growth analysis.
|
| 16 |
+
|
| 17 |
+
---
|
| 18 |
+
|
| 19 |
+
## 🚀 Features
|
| 20 |
+
|
| 21 |
+
- **Explore Any Country**: Select from a global list, complete with flags and regions.
|
| 22 |
+
- **Thematic Focus**: Dive into specific cultural themes—family, education, communication, work, food, values, modern challenges, and more.
|
| 23 |
+
- **AI-Generated Insights**: Instantly generate nuanced, non-stereotypical cultural analyses (OpenAI API key required, stored only in your browser).
|
| 24 |
+
- **Guided Reflection**: Respond to evidence-based reflection prompts designed for cultural empathy and self-awareness.
|
| 25 |
+
- **AI Analysis**: Receive a structured AI comparison and growth report between cultural insights and your personal reflections.
|
| 26 |
+
- **Progress Tracking**: Save and revisit your exploration history—each journey is unique!
|
| 27 |
+
- **Privacy-First**: All processing and key storage are client-side; no user data leaves your browser.
|
| 28 |
+
|
| 29 |
+
---
|
| 30 |
+
|
| 31 |
+
## 🛠 How to Use
|
| 32 |
+
|
| 33 |
+
1. **Open the tool** in your browser (no installation or login required).
|
| 34 |
+
2. **Select a country** to explore, and optionally choose a specific theme.
|
| 35 |
+
3. **Provide your OpenAI API key** when prompted (needed for AI features; your key stays private in your browser).
|
| 36 |
+
4. **Generate Cultural Insights**: The AI summarizes key values, history, daily life, challenges, and misconceptions for your chosen country and theme.
|
| 37 |
+
5. **Reflect**: Complete reflection prompts comparing your culture with the one explored—identify similarities, differences, surprises, and new perspectives.
|
| 38 |
+
6. **Receive AI Analysis**: Generate a structured table that analyzes your learning, empathy development, and global citizenship growth.
|
| 39 |
+
7. **Track Your Cultural Journey**: Review or revisit your past explorations in the built-in journey log.
|
| 40 |
+
8. **Restart Anytime**: Explore as many countries or themes as you like.
|
| 41 |
+
|
| 42 |
+
---
|
| 43 |
+
|
| 44 |
+
## 👩🏫 For Educators: How It Supports Teaching
|
| 45 |
+
|
| 46 |
+
- **Global Citizenship & SEL**: Scaffolded to foster cultural intelligence, perspective-taking, and self-reflection.
|
| 47 |
+
- **Any Subject or Level**: Use in social studies, languages, IB Global Contexts, humanities, and more.
|
| 48 |
+
- **Portfolio & Assessment Ready**: Save and review students’ analysis and reflections for evidence of learning.
|
| 49 |
+
- **Safe for School Use**: No accounts, logins, or central data collection.
|
| 50 |
+
|
| 51 |
+
---
|
| 52 |
+
|
| 53 |
+
## 👨🎓 For Students: Benefits & Learning Outcomes
|
| 54 |
+
|
| 55 |
+
- **Personalized Global Learning**: Choose your own country and cultural theme for maximum relevance.
|
| 56 |
+
- **Empathy & Critical Thinking**: Evidence-based prompts support deep, honest self-reflection and challenge assumptions.
|
| 57 |
+
- **Skill Growth**: AI feedback highlights strengths and growth in cultural intelligence.
|
| 58 |
+
- **Reflection Portfolio**: Use AI analyses as evidence in digital portfolios or class projects.
|
| 59 |
+
|
| 60 |
+
---
|
| 61 |
+
|
| 62 |
+
## 🔐 Data Privacy Notice
|
| 63 |
+
|
| 64 |
+
- Your OpenAI API key is only stored locally in your browser.
|
| 65 |
+
- No user data is collected, shared, or sent to Shift Mind AI Labs, Hugging Face, or any third party.
|
| 66 |
+
- All AI requests go directly from your browser to OpenAI via your key.
|
| 67 |
+
|
| 68 |
+
---
|
| 69 |
+
|
| 70 |
+
## 📄 License
|
| 71 |
+
|
| 72 |
+
Licensed under the [Apache License 2.0](./LICENSE).
|
| 73 |
+
|
| 74 |
+
---
|
| 75 |
+
|
| 76 |
+
## 🧠 About Shift Mind AI Labs
|
| 77 |
+
|
| 78 |
+
Shift Mind AI Labs builds open-source, ethical AI tools for global learning and citizenship.
|
| 79 |
+
|
| 80 |
+
🌐 www.shiftmind.io
|
| 81 |
+
✉️ info@shiftmind.io
|
| 82 |
+
|
| 83 |
+
---
|
| 84 |
+
|
| 85 |
+
## 🙌 Contributing
|
| 86 |
+
|
| 87 |
+
Pull requests, bug reports, and feedback welcome!
|
| 88 |
+
For partnerships, integration, or pilots: **info@shiftmind.io**
|
| 89 |
+
|
| 90 |
+
---
|
| 91 |
+
|
| 92 |
+
*Empowering global citizenship—one culture at a time.*
|
index.html
ADDED
|
@@ -0,0 +1,1532 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<title>Cultural Intelligence Explorer - Global Edition with AI Analysis</title>
|
| 6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 7 |
+
<!-- Tailwind CSS -->
|
| 8 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
+
<!-- React & ReactDOM -->
|
| 10 |
+
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
|
| 11 |
+
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
|
| 12 |
+
<!-- @babel/standalone -->
|
| 13 |
+
<script crossorigin src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
| 14 |
+
<!-- Font Awesome for icons -->
|
| 15 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
| 16 |
+
<style>
|
| 17 |
+
html, body {
|
| 18 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 19 |
+
min-height: 100%;
|
| 20 |
+
margin: 0;
|
| 21 |
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
.glass {
|
| 25 |
+
background: rgba(255, 255, 255, 0.9);
|
| 26 |
+
backdrop-filter: blur(15px);
|
| 27 |
+
border-radius: 1.5rem;
|
| 28 |
+
box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37);
|
| 29 |
+
border: 1px solid rgba(255, 255, 255, 0.18);
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
.country-dropdown {
|
| 33 |
+
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
| 34 |
+
border-radius: 1rem;
|
| 35 |
+
padding: 1.5rem;
|
| 36 |
+
color: white;
|
| 37 |
+
margin-bottom: 2rem;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
.dropdown-container {
|
| 41 |
+
position: relative;
|
| 42 |
+
width: 100%;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
.dropdown-input {
|
| 46 |
+
width: 100%;
|
| 47 |
+
padding: 1rem;
|
| 48 |
+
border: 2px solid rgba(255,255,255,0.3);
|
| 49 |
+
border-radius: 0.75rem;
|
| 50 |
+
background: rgba(255,255,255,0.9);
|
| 51 |
+
color: #333;
|
| 52 |
+
font-size: 1rem;
|
| 53 |
+
cursor: pointer;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
.dropdown-input:focus {
|
| 57 |
+
outline: none;
|
| 58 |
+
border-color: #fbbf24;
|
| 59 |
+
box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.3);
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
.dropdown-list {
|
| 63 |
+
position: absolute;
|
| 64 |
+
top: 100%;
|
| 65 |
+
left: 0;
|
| 66 |
+
right: 0;
|
| 67 |
+
background: white;
|
| 68 |
+
border: 1px solid #e5e7eb;
|
| 69 |
+
border-radius: 0.75rem;
|
| 70 |
+
max-height: 300px;
|
| 71 |
+
overflow-y: auto;
|
| 72 |
+
z-index: 1000;
|
| 73 |
+
box-shadow: 0 10px 25px rgba(0,0,0,0.15);
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
.dropdown-item {
|
| 77 |
+
padding: 0.75rem 1rem;
|
| 78 |
+
cursor: pointer;
|
| 79 |
+
border-bottom: 1px solid #f3f4f6;
|
| 80 |
+
display: flex;
|
| 81 |
+
align-items: center;
|
| 82 |
+
gap: 0.75rem;
|
| 83 |
+
transition: background-color 0.2s;
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
.dropdown-item:hover {
|
| 87 |
+
background-color: #f8fafc;
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
.dropdown-item:last-child {
|
| 91 |
+
border-bottom: none;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
.dropdown-item.highlighted {
|
| 95 |
+
background-color: #eff6ff;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
.theme-card {
|
| 99 |
+
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
| 100 |
+
border-radius: 0.75rem;
|
| 101 |
+
padding: 1rem;
|
| 102 |
+
color: white;
|
| 103 |
+
cursor: pointer;
|
| 104 |
+
transition: all 0.3s ease;
|
| 105 |
+
border: 2px solid transparent;
|
| 106 |
+
text-align: center;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
.theme-card:hover {
|
| 110 |
+
transform: scale(1.05);
|
| 111 |
+
border-color: rgba(255,255,255,0.5);
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.theme-card.selected {
|
| 115 |
+
border-color: #fbbf24;
|
| 116 |
+
box-shadow: 0 0 15px rgba(251, 191, 36, 0.4);
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
.insight-section {
|
| 120 |
+
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
| 121 |
+
border-radius: 1rem;
|
| 122 |
+
padding: 1.5rem;
|
| 123 |
+
margin: 1rem 0;
|
| 124 |
+
border-left: 4px solid #667eea;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
.reflection-card {
|
| 128 |
+
background: rgba(255, 255, 255, 0.95);
|
| 129 |
+
border-radius: 1rem;
|
| 130 |
+
padding: 1.5rem;
|
| 131 |
+
margin: 1rem 0;
|
| 132 |
+
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
| 133 |
+
border: 1px solid rgba(102, 126, 234, 0.2);
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
.analysis-table {
|
| 137 |
+
background: rgba(255, 255, 255, 0.98);
|
| 138 |
+
border-radius: 1rem;
|
| 139 |
+
overflow: hidden;
|
| 140 |
+
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
|
| 141 |
+
border: 1px solid rgba(102, 126, 234, 0.2);
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
.analysis-table table {
|
| 145 |
+
width: 100%;
|
| 146 |
+
border-collapse: collapse;
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
.analysis-table th {
|
| 150 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 151 |
+
color: white;
|
| 152 |
+
padding: 1rem;
|
| 153 |
+
text-align: left;
|
| 154 |
+
font-weight: 600;
|
| 155 |
+
border-bottom: 2px solid rgba(255,255,255,0.2);
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
.analysis-table td {
|
| 159 |
+
padding: 1rem;
|
| 160 |
+
border-bottom: 1px solid #e5e7eb;
|
| 161 |
+
vertical-align: top;
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
.analysis-table tr:last-child td {
|
| 165 |
+
border-bottom: none;
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
.analysis-table tr:nth-child(even) {
|
| 169 |
+
background-color: #f8fafc;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
.analysis-table tr:hover {
|
| 173 |
+
background-color: #eff6ff;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
.insight-badge {
|
| 177 |
+
display: inline-block;
|
| 178 |
+
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
| 179 |
+
color: white;
|
| 180 |
+
padding: 0.25rem 0.75rem;
|
| 181 |
+
border-radius: 1rem;
|
| 182 |
+
font-size: 0.75rem;
|
| 183 |
+
font-weight: 600;
|
| 184 |
+
margin: 0.25rem 0.25rem 0.25rem 0;
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
.comparison-badge {
|
| 188 |
+
display: inline-block;
|
| 189 |
+
background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
|
| 190 |
+
color: white;
|
| 191 |
+
padding: 0.25rem 0.75rem;
|
| 192 |
+
border-radius: 1rem;
|
| 193 |
+
font-size: 0.75rem;
|
| 194 |
+
font-weight: 600;
|
| 195 |
+
margin: 0.25rem 0.25rem 0.25rem 0;
|
| 196 |
+
}
|
| 197 |
+
|
| 198 |
+
.progress-bar {
|
| 199 |
+
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
|
| 200 |
+
height: 6px;
|
| 201 |
+
border-radius: 3px;
|
| 202 |
+
transition: width 0.5s ease;
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
.typing-indicator {
|
| 206 |
+
display: inline-flex;
|
| 207 |
+
align-items: center;
|
| 208 |
+
gap: 4px;
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
.typing-dot {
|
| 212 |
+
width: 8px;
|
| 213 |
+
height: 8px;
|
| 214 |
+
border-radius: 50%;
|
| 215 |
+
background: #667eea;
|
| 216 |
+
animation: typing 1.4s infinite ease-in-out;
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
.typing-dot:nth-child(1) { animation-delay: -0.32s; }
|
| 220 |
+
.typing-dot:nth-child(2) { animation-delay: -0.16s; }
|
| 221 |
+
|
| 222 |
+
@keyframes typing {
|
| 223 |
+
0%, 80%, 100% { transform: scale(0); opacity: 0.5; }
|
| 224 |
+
40% { transform: scale(1); opacity: 1; }
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
.fade-in {
|
| 228 |
+
animation: fadeIn 0.6s ease-in;
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
+
@keyframes fadeIn {
|
| 232 |
+
from { opacity: 0; transform: translateY(20px); }
|
| 233 |
+
to { opacity: 1; transform: translateY(0); }
|
| 234 |
+
}
|
| 235 |
+
|
| 236 |
+
.slide-in {
|
| 237 |
+
animation: slideIn 0.5s ease-out;
|
| 238 |
+
}
|
| 239 |
+
|
| 240 |
+
@keyframes slideIn {
|
| 241 |
+
from { opacity: 0; transform: translateX(-30px); }
|
| 242 |
+
to { opacity: 1; transform: translateX(0); }
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
/* Accessibility improvements */
|
| 246 |
+
.sr-only {
|
| 247 |
+
position: absolute;
|
| 248 |
+
width: 1px;
|
| 249 |
+
height: 1px;
|
| 250 |
+
padding: 0;
|
| 251 |
+
margin: -1px;
|
| 252 |
+
overflow: hidden;
|
| 253 |
+
clip: rect(0, 0, 0, 0);
|
| 254 |
+
white-space: nowrap;
|
| 255 |
+
border: 0;
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
button:focus, input:focus, textarea:focus, select:focus {
|
| 259 |
+
outline: 3px solid #fbbf24;
|
| 260 |
+
outline-offset: 2px;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
.theme-card:focus {
|
| 264 |
+
outline: 3px solid #fbbf24;
|
| 265 |
+
outline-offset: 2px;
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
/* Responsive design */
|
| 269 |
+
@media (max-width: 768px) {
|
| 270 |
+
.theme-grid {
|
| 271 |
+
grid-template-columns: repeat(2, 1fr);
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
.analysis-table {
|
| 275 |
+
overflow-x: auto;
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
.analysis-table table {
|
| 279 |
+
min-width: 600px;
|
| 280 |
+
}
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
@media (max-width: 640px) {
|
| 284 |
+
.theme-grid {
|
| 285 |
+
grid-template-columns: 1fr;
|
| 286 |
+
}
|
| 287 |
+
}
|
| 288 |
+
</style>
|
| 289 |
+
</head>
|
| 290 |
+
<body>
|
| 291 |
+
<div id="root"></div>
|
| 292 |
+
<script type="text/babel">
|
| 293 |
+
const { useState, useEffect, useCallback, useRef } = React;
|
| 294 |
+
|
| 295 |
+
// Comprehensive list of world countries with flags and regions
|
| 296 |
+
const WORLD_COUNTRIES = [
|
| 297 |
+
// Africa
|
| 298 |
+
{ id: 'algeria', name: 'Algeria', flag: '🇩🇿', region: 'North Africa' },
|
| 299 |
+
{ id: 'angola', name: 'Angola', flag: '🇦🇴', region: 'Central Africa' },
|
| 300 |
+
{ id: 'benin', name: 'Benin', flag: '🇧🇯', region: 'West Africa' },
|
| 301 |
+
{ id: 'botswana', name: 'Botswana', flag: '🇧🇼', region: 'Southern Africa' },
|
| 302 |
+
{ id: 'burkina-faso', name: 'Burkina Faso', flag: '🇧🇫', region: 'West Africa' },
|
| 303 |
+
{ id: 'burundi', name: 'Burundi', flag: '🇧🇮', region: 'East Africa' },
|
| 304 |
+
{ id: 'cameroon', name: 'Cameroon', flag: '🇨🇲', region: 'Central Africa' },
|
| 305 |
+
{ id: 'cape-verde', name: 'Cape Verde', flag: '🇨🇻', region: 'West Africa' },
|
| 306 |
+
{ id: 'chad', name: 'Chad', flag: '🇹🇩', region: 'Central Africa' },
|
| 307 |
+
{ id: 'comoros', name: 'Comoros', flag: '🇰🇲', region: 'East Africa' },
|
| 308 |
+
{ id: 'congo', name: 'Congo', flag: '🇨🇬', region: 'Central Africa' },
|
| 309 |
+
{ id: 'drc', name: 'Democratic Republic of Congo', flag: '🇨🇩', region: 'Central Africa' },
|
| 310 |
+
{ id: 'djibouti', name: 'Djibouti', flag: '🇩🇯', region: 'East Africa' },
|
| 311 |
+
{ id: 'egypt', name: 'Egypt', flag: '🇪🇬', region: 'North Africa' },
|
| 312 |
+
{ id: 'equatorial-guinea', name: 'Equatorial Guinea', flag: '🇬🇶', region: 'Central Africa' },
|
| 313 |
+
{ id: 'eritrea', name: 'Eritrea', flag: '🇪🇷', region: 'East Africa' },
|
| 314 |
+
{ id: 'eswatini', name: 'Eswatini', flag: '🇸🇿', region: 'Southern Africa' },
|
| 315 |
+
{ id: 'ethiopia', name: 'Ethiopia', flag: '🇪🇹', region: 'East Africa' },
|
| 316 |
+
{ id: 'gabon', name: 'Gabon', flag: '🇬🇦', region: 'Central Africa' },
|
| 317 |
+
{ id: 'gambia', name: 'Gambia', flag: '🇬🇲', region: 'West Africa' },
|
| 318 |
+
{ id: 'ghana', name: 'Ghana', flag: '🇬🇭', region: 'West Africa' },
|
| 319 |
+
{ id: 'guinea', name: 'Guinea', flag: '🇬🇳', region: 'West Africa' },
|
| 320 |
+
{ id: 'guinea-bissau', name: 'Guinea-Bissau', flag: '🇬🇼', region: 'West Africa' },
|
| 321 |
+
{ id: 'ivory-coast', name: 'Ivory Coast', flag: '🇨🇮', region: 'West Africa' },
|
| 322 |
+
{ id: 'kenya', name: 'Kenya', flag: '🇰🇪', region: 'East Africa' },
|
| 323 |
+
{ id: 'lesotho', name: 'Lesotho', flag: '🇱🇸', region: 'Southern Africa' },
|
| 324 |
+
{ id: 'liberia', name: 'Liberia', flag: '🇱🇷', region: 'West Africa' },
|
| 325 |
+
{ id: 'libya', name: 'Libya', flag: '🇱🇾', region: 'North Africa' },
|
| 326 |
+
{ id: 'madagascar', name: 'Madagascar', flag: '🇲🇬', region: 'East Africa' },
|
| 327 |
+
{ id: 'malawi', name: 'Malawi', flag: '🇲🇼', region: 'Southern Africa' },
|
| 328 |
+
{ id: 'mali', name: 'Mali', flag: '🇲🇱', region: 'West Africa' },
|
| 329 |
+
{ id: 'mauritania', name: 'Mauritania', flag: '🇲🇷', region: 'West Africa' },
|
| 330 |
+
{ id: 'mauritius', name: 'Mauritius', flag: '🇲🇺', region: 'East Africa' },
|
| 331 |
+
{ id: 'morocco', name: 'Morocco', flag: '🇲🇦', region: 'North Africa' },
|
| 332 |
+
{ id: 'mozambique', name: 'Mozambique', flag: '🇲🇿', region: 'Southern Africa' },
|
| 333 |
+
{ id: 'namibia', name: 'Namibia', flag: '🇳🇦', region: 'Southern Africa' },
|
| 334 |
+
{ id: 'niger', name: 'Niger', flag: '🇳🇪', region: 'West Africa' },
|
| 335 |
+
{ id: 'nigeria', name: 'Nigeria', flag: '🇳🇬', region: 'West Africa' },
|
| 336 |
+
{ id: 'rwanda', name: 'Rwanda', flag: '🇷🇼', region: 'East Africa' },
|
| 337 |
+
{ id: 'sao-tome', name: 'São Tomé and Príncipe', flag: '🇸🇹', region: 'Central Africa' },
|
| 338 |
+
{ id: 'senegal', name: 'Senegal', flag: '🇸🇳', region: 'West Africa' },
|
| 339 |
+
{ id: 'seychelles', name: 'Seychelles', flag: '🇸🇨', region: 'East Africa' },
|
| 340 |
+
{ id: 'sierra-leone', name: 'Sierra Leone', flag: '🇸🇱', region: 'West Africa' },
|
| 341 |
+
{ id: 'somalia', name: 'Somalia', flag: '🇸🇴', region: 'East Africa' },
|
| 342 |
+
{ id: 'south-africa', name: 'South Africa', flag: '🇿🇦', region: 'Southern Africa' },
|
| 343 |
+
{ id: 'south-sudan', name: 'South Sudan', flag: '🇸🇸', region: 'East Africa' },
|
| 344 |
+
{ id: 'sudan', name: 'Sudan', flag: '🇸🇩', region: 'North Africa' },
|
| 345 |
+
{ id: 'tanzania', name: 'Tanzania', flag: '🇹🇿', region: 'East Africa' },
|
| 346 |
+
{ id: 'togo', name: 'Togo', flag: '🇹🇬', region: 'West Africa' },
|
| 347 |
+
{ id: 'tunisia', name: 'Tunisia', flag: '🇹🇳', region: 'North Africa' },
|
| 348 |
+
{ id: 'uganda', name: 'Uganda', flag: '🇺🇬', region: 'East Africa' },
|
| 349 |
+
{ id: 'zambia', name: 'Zambia', flag: '🇿🇲', region: 'Southern Africa' },
|
| 350 |
+
{ id: 'zimbabwe', name: 'Zimbabwe', flag: '🇿🇼', region: 'Southern Africa' },
|
| 351 |
+
|
| 352 |
+
// Asia
|
| 353 |
+
{ id: 'afghanistan', name: 'Afghanistan', flag: '🇦🇫', region: 'Central Asia' },
|
| 354 |
+
{ id: 'armenia', name: 'Armenia', flag: '🇦🇲', region: 'Western Asia' },
|
| 355 |
+
{ id: 'azerbaijan', name: 'Azerbaijan', flag: '🇦🇿', region: 'Western Asia' },
|
| 356 |
+
{ id: 'bahrain', name: 'Bahrain', flag: '🇧🇭', region: 'Western Asia' },
|
| 357 |
+
{ id: 'bangladesh', name: 'Bangladesh', flag: '🇧🇩', region: 'South Asia' },
|
| 358 |
+
{ id: 'bhutan', name: 'Bhutan', flag: '🇧🇹', region: 'South Asia' },
|
| 359 |
+
{ id: 'brunei', name: 'Brunei', flag: '🇧🇳', region: 'Southeast Asia' },
|
| 360 |
+
{ id: 'cambodia', name: 'Cambodia', flag: '🇰🇭', region: 'Southeast Asia' },
|
| 361 |
+
{ id: 'china', name: 'China', flag: '🇨🇳', region: 'East Asia' },
|
| 362 |
+
{ id: 'cyprus', name: 'Cyprus', flag: '🇨🇾', region: 'Western Asia' },
|
| 363 |
+
{ id: 'georgia', name: 'Georgia', flag: '🇬🇪', region: 'Western Asia' },
|
| 364 |
+
{ id: 'india', name: 'India', flag: '🇮🇳', region: 'South Asia' },
|
| 365 |
+
{ id: 'indonesia', name: 'Indonesia', flag: '🇮🇩', region: 'Southeast Asia' },
|
| 366 |
+
{ id: 'iran', name: 'Iran', flag: '🇮🇷', region: 'Western Asia' },
|
| 367 |
+
{ id: 'iraq', name: 'Iraq', flag: '🇮🇶', region: 'Western Asia' },
|
| 368 |
+
{ id: 'israel', name: 'Israel', flag: '🇮🇱', region: 'Western Asia' },
|
| 369 |
+
{ id: 'japan', name: 'Japan', flag: '🇯🇵', region: 'East Asia' },
|
| 370 |
+
{ id: 'jordan', name: 'Jordan', flag: '🇯🇴', region: 'Western Asia' },
|
| 371 |
+
{ id: 'kazakhstan', name: 'Kazakhstan', flag: '🇰🇿', region: 'Central Asia' },
|
| 372 |
+
{ id: 'kuwait', name: 'Kuwait', flag: '🇰🇼', region: 'Western Asia' },
|
| 373 |
+
{ id: 'kyrgyzstan', name: 'Kyrgyzstan', flag: '🇰🇬', region: 'Central Asia' },
|
| 374 |
+
{ id: 'laos', name: 'Laos', flag: '🇱🇦', region: 'Southeast Asia' },
|
| 375 |
+
{ id: 'lebanon', name: 'Lebanon', flag: '🇱🇧', region: 'Western Asia' },
|
| 376 |
+
{ id: 'malaysia', name: 'Malaysia', flag: '🇲🇾', region: 'Southeast Asia' },
|
| 377 |
+
{ id: 'maldives', name: 'Maldives', flag: '🇲🇻', region: 'South Asia' },
|
| 378 |
+
{ id: 'mongolia', name: 'Mongolia', flag: '🇲🇳', region: 'East Asia' },
|
| 379 |
+
{ id: 'myanmar', name: 'Myanmar', flag: '🇲🇲', region: 'Southeast Asia' },
|
| 380 |
+
{ id: 'nepal', name: 'Nepal', flag: '🇳🇵', region: 'South Asia' },
|
| 381 |
+
{ id: 'north-korea', name: 'North Korea', flag: '🇰🇵', region: 'East Asia' },
|
| 382 |
+
{ id: 'oman', name: 'Oman', flag: '🇴🇲', region: 'Western Asia' },
|
| 383 |
+
{ id: 'pakistan', name: 'Pakistan', flag: '🇵🇰', region: 'South Asia' },
|
| 384 |
+
{ id: 'palestine', name: 'Palestine', flag: '🇵🇸', region: 'Western Asia' },
|
| 385 |
+
{ id: 'philippines', name: 'Philippines', flag: '🇵🇭', region: 'Southeast Asia' },
|
| 386 |
+
{ id: 'qatar', name: 'Qatar', flag: '🇶🇦', region: 'Western Asia' },
|
| 387 |
+
{ id: 'saudi-arabia', name: 'Saudi Arabia', flag: '🇸🇦', region: 'Western Asia' },
|
| 388 |
+
{ id: 'singapore', name: 'Singapore', flag: '🇸🇬', region: 'Southeast Asia' },
|
| 389 |
+
{ id: 'south-korea', name: 'South Korea', flag: '🇰🇷', region: 'East Asia' },
|
| 390 |
+
{ id: 'sri-lanka', name: 'Sri Lanka', flag: '🇱🇰', region: 'South Asia' },
|
| 391 |
+
{ id: 'syria', name: 'Syria', flag: '🇸🇾', region: 'Western Asia' },
|
| 392 |
+
{ id: 'taiwan', name: 'Taiwan', flag: '🇹🇼', region: 'East Asia' },
|
| 393 |
+
{ id: 'tajikistan', name: 'Tajikistan', flag: '🇹🇯', region: 'Central Asia' },
|
| 394 |
+
{ id: 'thailand', name: 'Thailand', flag: '🇹🇭', region: 'Southeast Asia' },
|
| 395 |
+
{ id: 'timor-leste', name: 'Timor-Leste', flag: '🇹🇱', region: 'Southeast Asia' },
|
| 396 |
+
{ id: 'turkey', name: 'Turkey', flag: '🇹🇷', region: 'Western Asia' },
|
| 397 |
+
{ id: 'turkmenistan', name: 'Turkmenistan', flag: '🇹🇲', region: 'Central Asia' },
|
| 398 |
+
{ id: 'uae', name: 'United Arab Emirates', flag: '🇦🇪', region: 'Western Asia' },
|
| 399 |
+
{ id: 'uzbekistan', name: 'Uzbekistan', flag: '🇺🇿', region: 'Central Asia' },
|
| 400 |
+
{ id: 'vietnam', name: 'Vietnam', flag: '🇻🇳', region: 'Southeast Asia' },
|
| 401 |
+
{ id: 'yemen', name: 'Yemen', flag: '🇾🇪', region: 'Western Asia' },
|
| 402 |
+
|
| 403 |
+
// Europe
|
| 404 |
+
{ id: 'albania', name: 'Albania', flag: '🇦🇱', region: 'Southern Europe' },
|
| 405 |
+
{ id: 'andorra', name: 'Andorra', flag: '🇦🇩', region: 'Southern Europe' },
|
| 406 |
+
{ id: 'austria', name: 'Austria', flag: '🇦🇹', region: 'Central Europe' },
|
| 407 |
+
{ id: 'belarus', name: 'Belarus', flag: '🇧🇾', region: 'Eastern Europe' },
|
| 408 |
+
{ id: 'belgium', name: 'Belgium', flag: '🇧🇪', region: 'Western Europe' },
|
| 409 |
+
{ id: 'bosnia', name: 'Bosnia and Herzegovina', flag: '🇧🇦', region: 'Southern Europe' },
|
| 410 |
+
{ id: 'bulgaria', name: 'Bulgaria', flag: '🇧🇬', region: 'Eastern Europe' },
|
| 411 |
+
{ id: 'croatia', name: 'Croatia', flag: '🇭🇷', region: 'Southern Europe' },
|
| 412 |
+
{ id: 'czech-republic', name: 'Czech Republic', flag: '🇨🇿', region: 'Central Europe' },
|
| 413 |
+
{ id: 'denmark', name: 'Denmark', flag: '🇩🇰', region: 'Northern Europe' },
|
| 414 |
+
{ id: 'estonia', name: 'Estonia', flag: '🇪🇪', region: 'Northern Europe' },
|
| 415 |
+
{ id: 'finland', name: 'Finland', flag: '🇫🇮', region: 'Northern Europe' },
|
| 416 |
+
{ id: 'france', name: 'France', flag: '🇫🇷', region: 'Western Europe' },
|
| 417 |
+
{ id: 'germany', name: 'Germany', flag: '🇩🇪', region: 'Central Europe' },
|
| 418 |
+
{ id: 'greece', name: 'Greece', flag: '🇬🇷', region: 'Southern Europe' },
|
| 419 |
+
{ id: 'hungary', name: 'Hungary', flag: '🇭🇺', region: 'Central Europe' },
|
| 420 |
+
{ id: 'iceland', name: 'Iceland', flag: '🇮🇸', region: 'Northern Europe' },
|
| 421 |
+
{ id: 'ireland', name: 'Ireland', flag: '🇮🇪', region: 'Northern Europe' },
|
| 422 |
+
{ id: 'italy', name: 'Italy', flag: '🇮🇹', region: 'Southern Europe' },
|
| 423 |
+
{ id: 'kosovo', name: 'Kosovo', flag: '🇽🇰', region: 'Southern Europe' },
|
| 424 |
+
{ id: 'latvia', name: 'Latvia', flag: '🇱🇻', region: 'Northern Europe' },
|
| 425 |
+
{ id: 'liechtenstein', name: 'Liechtenstein', flag: '🇱🇮', region: 'Central Europe' },
|
| 426 |
+
{ id: 'lithuania', name: 'Lithuania', flag: '🇱🇹', region: 'Northern Europe' },
|
| 427 |
+
{ id: 'luxembourg', name: 'Luxembourg', flag: '🇱🇺', region: 'Western Europe' },
|
| 428 |
+
{ id: 'malta', name: 'Malta', flag: '🇲🇹', region: 'Southern Europe' },
|
| 429 |
+
{ id: 'moldova', name: 'Moldova', flag: '🇲🇩', region: 'Eastern Europe' },
|
| 430 |
+
{ id: 'monaco', name: 'Monaco', flag: '🇲🇨', region: 'Western Europe' },
|
| 431 |
+
{ id: 'montenegro', name: 'Montenegro', flag: '🇲🇪', region: 'Southern Europe' },
|
| 432 |
+
{ id: 'netherlands', name: 'Netherlands', flag: '🇳🇱', region: 'Western Europe' },
|
| 433 |
+
{ id: 'north-macedonia', name: 'North Macedonia', flag: '🇲🇰', region: 'Southern Europe' },
|
| 434 |
+
{ id: 'norway', name: 'Norway', flag: '🇳🇴', region: 'Northern Europe' },
|
| 435 |
+
{ id: 'poland', name: 'Poland', flag: '🇵🇱', region: 'Central Europe' },
|
| 436 |
+
{ id: 'portugal', name: 'Portugal', flag: '🇵🇹', region: 'Southern Europe' },
|
| 437 |
+
{ id: 'romania', name: 'Romania', flag: '🇷🇴', region: 'Eastern Europe' },
|
| 438 |
+
{ id: 'russia', name: 'Russia', flag: '🇷🇺', region: 'Eastern Europe' },
|
| 439 |
+
{ id: 'san-marino', name: 'San Marino', flag: '🇸🇲', region: 'Southern Europe' },
|
| 440 |
+
{ id: 'serbia', name: 'Serbia', flag: '🇷🇸', region: 'Southern Europe' },
|
| 441 |
+
{ id: 'slovakia', name: 'Slovakia', flag: '🇸🇰', region: 'Central Europe' },
|
| 442 |
+
{ id: 'slovenia', name: 'Slovenia', flag: '🇸🇮', region: 'Central Europe' },
|
| 443 |
+
{ id: 'spain', name: 'Spain', flag: '🇪🇸', region: 'Southern Europe' },
|
| 444 |
+
{ id: 'sweden', name: 'Sweden', flag: '🇸🇪', region: 'Northern Europe' },
|
| 445 |
+
{ id: 'switzerland', name: 'Switzerland', flag: '🇨🇭', region: 'Central Europe' },
|
| 446 |
+
{ id: 'ukraine', name: 'Ukraine', flag: '🇺🇦', region: 'Eastern Europe' },
|
| 447 |
+
{ id: 'united-kingdom', name: 'United Kingdom', flag: '🇬🇧', region: 'Northern Europe' },
|
| 448 |
+
{ id: 'vatican', name: 'Vatican City', flag: '🇻🇦', region: 'Southern Europe' },
|
| 449 |
+
|
| 450 |
+
// North America
|
| 451 |
+
{ id: 'antigua', name: 'Antigua and Barbuda', flag: '🇦🇬', region: 'Caribbean' },
|
| 452 |
+
{ id: 'bahamas', name: 'Bahamas', flag: '🇧🇸', region: 'Caribbean' },
|
| 453 |
+
{ id: 'barbados', name: 'Barbados', flag: '🇧🇧', region: 'Caribbean' },
|
| 454 |
+
{ id: 'belize', name: 'Belize', flag: '🇧🇿', region: 'Central America' },
|
| 455 |
+
{ id: 'canada', name: 'Canada', flag: '🇨🇦', region: 'North America' },
|
| 456 |
+
{ id: 'costa-rica', name: 'Costa Rica', flag: '🇨🇷', region: 'Central America' },
|
| 457 |
+
{ id: 'cuba', name: 'Cuba', flag: '🇨🇺', region: 'Caribbean' },
|
| 458 |
+
{ id: 'dominica', name: 'Dominica', flag: '🇩🇲', region: 'Caribbean' },
|
| 459 |
+
{ id: 'dominican-republic', name: 'Dominican Republic', flag: '🇩🇴', region: 'Caribbean' },
|
| 460 |
+
{ id: 'el-salvador', name: 'El Salvador', flag: '🇸🇻', region: 'Central America' },
|
| 461 |
+
{ id: 'grenada', name: 'Grenada', flag: '🇬🇩', region: 'Caribbean' },
|
| 462 |
+
{ id: 'guatemala', name: 'Guatemala', flag: '🇬🇹', region: 'Central America' },
|
| 463 |
+
{ id: 'haiti', name: 'Haiti', flag: '🇭🇹', region: 'Caribbean' },
|
| 464 |
+
{ id: 'honduras', name: 'Honduras', flag: '🇭🇳', region: 'Central America' },
|
| 465 |
+
{ id: 'jamaica', name: 'Jamaica', flag: '🇯🇲', region: 'Caribbean' },
|
| 466 |
+
{ id: 'mexico', name: 'Mexico', flag: '🇲🇽', region: 'North America' },
|
| 467 |
+
{ id: 'nicaragua', name: 'Nicaragua', flag: '🇳🇮', region: 'Central America' },
|
| 468 |
+
{ id: 'panama', name: 'Panama', flag: '🇵🇦', region: 'Central America' },
|
| 469 |
+
{ id: 'saint-kitts', name: 'Saint Kitts and Nevis', flag: '🇰🇳', region: 'Caribbean' },
|
| 470 |
+
{ id: 'saint-lucia', name: 'Saint Lucia', flag: '🇱🇨', region: 'Caribbean' },
|
| 471 |
+
{ id: 'saint-vincent', name: 'Saint Vincent and the Grenadines', flag: '🇻🇨', region: 'Caribbean' },
|
| 472 |
+
{ id: 'trinidad', name: 'Trinidad and Tobago', flag: '🇹🇹', region: 'Caribbean' },
|
| 473 |
+
{ id: 'usa', name: 'United States', flag: '🇺🇸', region: 'North America' },
|
| 474 |
+
|
| 475 |
+
// South America
|
| 476 |
+
{ id: 'argentina', name: 'Argentina', flag: '🇦🇷', region: 'South America' },
|
| 477 |
+
{ id: 'bolivia', name: 'Bolivia', flag: '🇧🇴', region: 'South America' },
|
| 478 |
+
{ id: 'brazil', name: 'Brazil', flag: '🇧🇷', region: 'South America' },
|
| 479 |
+
{ id: 'chile', name: 'Chile', flag: '🇨🇱', region: 'South America' },
|
| 480 |
+
{ id: 'colombia', name: 'Colombia', flag: '🇨🇴', region: 'South America' },
|
| 481 |
+
{ id: 'ecuador', name: 'Ecuador', flag: '🇪🇨', region: 'South America' },
|
| 482 |
+
{ id: 'guyana', name: 'Guyana', flag: '🇬🇾', region: 'South America' },
|
| 483 |
+
{ id: 'paraguay', name: 'Paraguay', flag: '🇵🇾', region: 'South America' },
|
| 484 |
+
{ id: 'peru', name: 'Peru', flag: '🇵🇪', region: 'South America' },
|
| 485 |
+
{ id: 'suriname', name: 'Suriname', flag: '🇸🇷', region: 'South America' },
|
| 486 |
+
{ id: 'uruguay', name: 'Uruguay', flag: '🇺🇾', region: 'South America' },
|
| 487 |
+
{ id: 'venezuela', name: 'Venezuela', flag: '🇻🇪', region: 'South America' },
|
| 488 |
+
|
| 489 |
+
// Oceania
|
| 490 |
+
{ id: 'australia', name: 'Australia', flag: '🇦🇺', region: 'Oceania' },
|
| 491 |
+
{ id: 'fiji', name: 'Fiji', flag: '🇫🇯', region: 'Oceania' },
|
| 492 |
+
{ id: 'kiribati', name: 'Kiribati', flag: '🇰🇮', region: 'Oceania' },
|
| 493 |
+
{ id: 'marshall-islands', name: 'Marshall Islands', flag: '🇲🇭', region: 'Oceania' },
|
| 494 |
+
{ id: 'micronesia', name: 'Micronesia', flag: '🇫🇲', region: 'Oceania' },
|
| 495 |
+
{ id: 'nauru', name: 'Nauru', flag: '🇳🇷', region: 'Oceania' },
|
| 496 |
+
{ id: 'new-zealand', name: 'New Zealand', flag: '🇳🇿', region: 'Oceania' },
|
| 497 |
+
{ id: 'palau', name: 'Palau', flag: '🇵🇼', region: 'Oceania' },
|
| 498 |
+
{ id: 'papua-new-guinea', name: 'Papua New Guinea', flag: '🇵🇬', region: 'Oceania' },
|
| 499 |
+
{ id: 'samoa', name: 'Samoa', flag: '🇼🇸', region: 'Oceania' },
|
| 500 |
+
{ id: 'solomon-islands', name: 'Solomon Islands', flag: '🇸🇧', region: 'Oceania' },
|
| 501 |
+
{ id: 'tonga', name: 'Tonga', flag: '🇹🇴', region: 'Oceania' },
|
| 502 |
+
{ id: 'tuvalu', name: 'Tuvalu', flag: '🇹🇻', region: 'Oceania' },
|
| 503 |
+
{ id: 'vanuatu', name: 'Vanuatu', flag: '🇻🇺', region: 'Oceania' }
|
| 504 |
+
];
|
| 505 |
+
|
| 506 |
+
const THEMES = [
|
| 507 |
+
{
|
| 508 |
+
id: 'family',
|
| 509 |
+
name: 'Family Life',
|
| 510 |
+
icon: '👨👩👧👦',
|
| 511 |
+
description: 'Family structures, relationships, and traditions'
|
| 512 |
+
},
|
| 513 |
+
{
|
| 514 |
+
id: 'education',
|
| 515 |
+
name: 'Education',
|
| 516 |
+
icon: '📚',
|
| 517 |
+
description: 'Learning systems, values, and approaches to knowledge'
|
| 518 |
+
},
|
| 519 |
+
{
|
| 520 |
+
id: 'traditions',
|
| 521 |
+
name: 'Traditions & Festivals',
|
| 522 |
+
icon: '🎭',
|
| 523 |
+
description: 'Cultural celebrations, rituals, and customs'
|
| 524 |
+
},
|
| 525 |
+
{
|
| 526 |
+
id: 'communication',
|
| 527 |
+
name: 'Communication',
|
| 528 |
+
icon: '💬',
|
| 529 |
+
description: 'Language, non-verbal cues, and social interactions'
|
| 530 |
+
},
|
| 531 |
+
{
|
| 532 |
+
id: 'work',
|
| 533 |
+
name: 'Work & Business',
|
| 534 |
+
icon: '💼',
|
| 535 |
+
description: 'Professional culture, work ethics, and business practices'
|
| 536 |
+
},
|
| 537 |
+
{
|
| 538 |
+
id: 'food',
|
| 539 |
+
name: 'Food & Dining',
|
| 540 |
+
icon: '🍽️',
|
| 541 |
+
description: 'Culinary traditions, dining etiquette, and food culture'
|
| 542 |
+
},
|
| 543 |
+
{
|
| 544 |
+
id: 'values',
|
| 545 |
+
name: 'Core Values',
|
| 546 |
+
icon: '⭐',
|
| 547 |
+
description: 'Fundamental beliefs, principles, and worldviews'
|
| 548 |
+
},
|
| 549 |
+
{
|
| 550 |
+
id: 'challenges',
|
| 551 |
+
name: 'Modern Challenges',
|
| 552 |
+
icon: '🌍',
|
| 553 |
+
description: 'Contemporary issues and cultural adaptations'
|
| 554 |
+
}
|
| 555 |
+
];
|
| 556 |
+
|
| 557 |
+
const REFLECTION_PROMPTS = [
|
| 558 |
+
{
|
| 559 |
+
id: 'similarities',
|
| 560 |
+
question: 'What similarities did you discover between this culture and your own?',
|
| 561 |
+
icon: '🤝'
|
| 562 |
+
},
|
| 563 |
+
{
|
| 564 |
+
id: 'differences',
|
| 565 |
+
question: 'What differences surprised you the most?',
|
| 566 |
+
icon: '🔍'
|
| 567 |
+
},
|
| 568 |
+
{
|
| 569 |
+
id: 'assumptions',
|
| 570 |
+
question: 'What assumptions about this culture were challenged?',
|
| 571 |
+
icon: '💭'
|
| 572 |
+
},
|
| 573 |
+
{
|
| 574 |
+
id: 'learning',
|
| 575 |
+
question: 'What valuable lesson or practice could you adopt from this culture?',
|
| 576 |
+
icon: '💡'
|
| 577 |
+
},
|
| 578 |
+
{
|
| 579 |
+
id: 'empathy',
|
| 580 |
+
question: 'How has this exploration changed your perspective on cultural diversity?',
|
| 581 |
+
icon: '❤️'
|
| 582 |
+
}
|
| 583 |
+
];
|
| 584 |
+
|
| 585 |
+
// Country Dropdown Component
|
| 586 |
+
function CountryDropdown({ selectedCountry, onCountrySelect }) {
|
| 587 |
+
const [isOpen, setIsOpen] = useState(false);
|
| 588 |
+
const [searchTerm, setSearchTerm] = useState('');
|
| 589 |
+
const [highlightedIndex, setHighlightedIndex] = useState(-1);
|
| 590 |
+
const dropdownRef = useRef(null);
|
| 591 |
+
const inputRef = useRef(null);
|
| 592 |
+
|
| 593 |
+
const filteredCountries = WORLD_COUNTRIES.filter(country =>
|
| 594 |
+
country.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
| 595 |
+
country.region.toLowerCase().includes(searchTerm.toLowerCase())
|
| 596 |
+
);
|
| 597 |
+
|
| 598 |
+
useEffect(() => {
|
| 599 |
+
function handleClickOutside(event) {
|
| 600 |
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
| 601 |
+
setIsOpen(false);
|
| 602 |
+
setHighlightedIndex(-1);
|
| 603 |
+
}
|
| 604 |
+
}
|
| 605 |
+
|
| 606 |
+
document.addEventListener('mousedown', handleClickOutside);
|
| 607 |
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
| 608 |
+
}, []);
|
| 609 |
+
|
| 610 |
+
const handleInputChange = (e) => {
|
| 611 |
+
setSearchTerm(e.target.value);
|
| 612 |
+
setIsOpen(true);
|
| 613 |
+
setHighlightedIndex(-1);
|
| 614 |
+
};
|
| 615 |
+
|
| 616 |
+
const handleKeyDown = (e) => {
|
| 617 |
+
if (!isOpen) {
|
| 618 |
+
if (e.key === 'Enter' || e.key === 'ArrowDown') {
|
| 619 |
+
setIsOpen(true);
|
| 620 |
+
setHighlightedIndex(0);
|
| 621 |
+
}
|
| 622 |
+
return;
|
| 623 |
+
}
|
| 624 |
+
|
| 625 |
+
switch (e.key) {
|
| 626 |
+
case 'ArrowDown':
|
| 627 |
+
e.preventDefault();
|
| 628 |
+
setHighlightedIndex(prev =>
|
| 629 |
+
prev < filteredCountries.length - 1 ? prev + 1 : 0
|
| 630 |
+
);
|
| 631 |
+
break;
|
| 632 |
+
case 'ArrowUp':
|
| 633 |
+
e.preventDefault();
|
| 634 |
+
setHighlightedIndex(prev =>
|
| 635 |
+
prev > 0 ? prev - 1 : filteredCountries.length - 1
|
| 636 |
+
);
|
| 637 |
+
break;
|
| 638 |
+
case 'Enter':
|
| 639 |
+
e.preventDefault();
|
| 640 |
+
if (highlightedIndex >= 0 && filteredCountries[highlightedIndex]) {
|
| 641 |
+
handleCountrySelect(filteredCountries[highlightedIndex]);
|
| 642 |
+
}
|
| 643 |
+
break;
|
| 644 |
+
case 'Escape':
|
| 645 |
+
setIsOpen(false);
|
| 646 |
+
setHighlightedIndex(-1);
|
| 647 |
+
inputRef.current?.blur();
|
| 648 |
+
break;
|
| 649 |
+
}
|
| 650 |
+
};
|
| 651 |
+
|
| 652 |
+
const handleCountrySelect = (country) => {
|
| 653 |
+
onCountrySelect(country);
|
| 654 |
+
setSearchTerm('');
|
| 655 |
+
setIsOpen(false);
|
| 656 |
+
setHighlightedIndex(-1);
|
| 657 |
+
};
|
| 658 |
+
|
| 659 |
+
const displayValue = selectedCountry
|
| 660 |
+
? `${selectedCountry.flag} ${selectedCountry.name}`
|
| 661 |
+
: searchTerm;
|
| 662 |
+
|
| 663 |
+
return (
|
| 664 |
+
<div className="dropdown-container" ref={dropdownRef}>
|
| 665 |
+
<input
|
| 666 |
+
ref={inputRef}
|
| 667 |
+
type="text"
|
| 668 |
+
className="dropdown-input"
|
| 669 |
+
placeholder={selectedCountry ? `${selectedCountry.flag} ${selectedCountry.name}` : "Search for a country..."}
|
| 670 |
+
value={isOpen ? searchTerm : displayValue}
|
| 671 |
+
onChange={handleInputChange}
|
| 672 |
+
onKeyDown={handleKeyDown}
|
| 673 |
+
onFocus={() => setIsOpen(true)}
|
| 674 |
+
autoComplete="off"
|
| 675 |
+
aria-expanded={isOpen}
|
| 676 |
+
aria-haspopup="listbox"
|
| 677 |
+
role="combobox"
|
| 678 |
+
/>
|
| 679 |
+
|
| 680 |
+
{isOpen && (
|
| 681 |
+
<div className="dropdown-list" role="listbox">
|
| 682 |
+
{filteredCountries.length > 0 ? (
|
| 683 |
+
filteredCountries.map((country, index) => (
|
| 684 |
+
<div
|
| 685 |
+
key={country.id}
|
| 686 |
+
className={`dropdown-item ${index === highlightedIndex ? 'highlighted' : ''}`}
|
| 687 |
+
onClick={() => handleCountrySelect(country)}
|
| 688 |
+
role="option"
|
| 689 |
+
aria-selected={selectedCountry?.id === country.id}
|
| 690 |
+
>
|
| 691 |
+
<span className="text-xl">{country.flag}</span>
|
| 692 |
+
<div>
|
| 693 |
+
<div className="font-semibold text-gray-800">{country.name}</div>
|
| 694 |
+
<div className="text-sm text-gray-500">{country.region}</div>
|
| 695 |
+
</div>
|
| 696 |
+
</div>
|
| 697 |
+
))
|
| 698 |
+
) : (
|
| 699 |
+
<div className="dropdown-item text-gray-500">
|
| 700 |
+
No countries found matching "{searchTerm}"
|
| 701 |
+
</div>
|
| 702 |
+
)}
|
| 703 |
+
</div>
|
| 704 |
+
)}
|
| 705 |
+
</div>
|
| 706 |
+
);
|
| 707 |
+
}
|
| 708 |
+
|
| 709 |
+
function CulturalIntelligenceExplorer() {
|
| 710 |
+
// Core state
|
| 711 |
+
const [phase, setPhase] = useState(1); // 1: Selection, 2: Insights, 3: Reflection, 4: Analysis
|
| 712 |
+
const [selectedCountry, setSelectedCountry] = useState(null);
|
| 713 |
+
const [selectedTheme, setSelectedTheme] = useState(null);
|
| 714 |
+
const [apiKey, setApiKey] = useState('');
|
| 715 |
+
const [showApiKeyModal, setShowApiKeyModal] = useState(false);
|
| 716 |
+
|
| 717 |
+
// AI and insights state
|
| 718 |
+
const [insights, setInsights] = useState(null);
|
| 719 |
+
const [isGeneratingInsights, setIsGeneratingInsights] = useState(false);
|
| 720 |
+
const [aiError, setAiError] = useState('');
|
| 721 |
+
|
| 722 |
+
// Reflection state
|
| 723 |
+
const [reflections, setReflections] = useState({});
|
| 724 |
+
const [explorationHistory, setExplorationHistory] = useState([]);
|
| 725 |
+
|
| 726 |
+
// Analysis state
|
| 727 |
+
const [analysis, setAnalysis] = useState(null);
|
| 728 |
+
const [isGeneratingAnalysis, setIsGeneratingAnalysis] = useState(false);
|
| 729 |
+
|
| 730 |
+
// Load data from localStorage
|
| 731 |
+
useEffect(() => {
|
| 732 |
+
try {
|
| 733 |
+
const savedApiKey = localStorage.getItem('cultural-explorer-api-key');
|
| 734 |
+
const savedHistory = localStorage.getItem('cultural-explorer-history');
|
| 735 |
+
|
| 736 |
+
if (savedApiKey) {
|
| 737 |
+
setApiKey(savedApiKey);
|
| 738 |
+
}
|
| 739 |
+
if (savedHistory) {
|
| 740 |
+
setExplorationHistory(JSON.parse(savedHistory));
|
| 741 |
+
}
|
| 742 |
+
} catch (error) {
|
| 743 |
+
console.error('Error loading saved data:', error);
|
| 744 |
+
}
|
| 745 |
+
}, []);
|
| 746 |
+
|
| 747 |
+
// Save data to localStorage
|
| 748 |
+
useEffect(() => {
|
| 749 |
+
try {
|
| 750 |
+
if (apiKey) {
|
| 751 |
+
localStorage.setItem('cultural-explorer-api-key', apiKey);
|
| 752 |
+
}
|
| 753 |
+
} catch (error) {
|
| 754 |
+
console.error('Error saving API key:', error);
|
| 755 |
+
}
|
| 756 |
+
}, [apiKey]);
|
| 757 |
+
|
| 758 |
+
useEffect(() => {
|
| 759 |
+
try {
|
| 760 |
+
localStorage.setItem('cultural-explorer-history', JSON.stringify(explorationHistory));
|
| 761 |
+
} catch (error) {
|
| 762 |
+
console.error('Error saving history:', error);
|
| 763 |
+
}
|
| 764 |
+
}, [explorationHistory]);
|
| 765 |
+
|
| 766 |
+
const handleCountrySelect = (country) => {
|
| 767 |
+
setSelectedCountry(country);
|
| 768 |
+
};
|
| 769 |
+
|
| 770 |
+
const handleThemeSelect = (theme) => {
|
| 771 |
+
setSelectedTheme(theme);
|
| 772 |
+
};
|
| 773 |
+
|
| 774 |
+
const proceedToInsights = () => {
|
| 775 |
+
if (!selectedCountry) {
|
| 776 |
+
alert('Please select a country to explore');
|
| 777 |
+
return;
|
| 778 |
+
}
|
| 779 |
+
|
| 780 |
+
if (!apiKey) {
|
| 781 |
+
setShowApiKeyModal(true);
|
| 782 |
+
return;
|
| 783 |
+
}
|
| 784 |
+
|
| 785 |
+
setPhase(2);
|
| 786 |
+
generateInsights();
|
| 787 |
+
};
|
| 788 |
+
|
| 789 |
+
const generateInsights = async () => {
|
| 790 |
+
if (!apiKey || !selectedCountry) return;
|
| 791 |
+
|
| 792 |
+
setIsGeneratingInsights(true);
|
| 793 |
+
setAiError('');
|
| 794 |
+
|
| 795 |
+
try {
|
| 796 |
+
const prompt = createInsightPrompt();
|
| 797 |
+
const response = await callOpenAI(prompt);
|
| 798 |
+
setInsights(response);
|
| 799 |
+
} catch (error) {
|
| 800 |
+
console.error('Error generating insights:', error);
|
| 801 |
+
setAiError(`Failed to generate insights: ${error.message}`);
|
| 802 |
+
} finally {
|
| 803 |
+
setIsGeneratingInsights(false);
|
| 804 |
+
}
|
| 805 |
+
};
|
| 806 |
+
|
| 807 |
+
const createInsightPrompt = () => {
|
| 808 |
+
const country = selectedCountry;
|
| 809 |
+
const theme = selectedTheme;
|
| 810 |
+
|
| 811 |
+
return `You are a cultural intelligence educator helping students develop empathy and global citizenship. Provide comprehensive, respectful insights about ${country.name} culture.
|
| 812 |
+
|
| 813 |
+
${theme ? `Focus specifically on: ${theme.name} - ${theme.description}` : 'Provide a general cultural overview.'}
|
| 814 |
+
|
| 815 |
+
Structure your response with the following sections:
|
| 816 |
+
|
| 817 |
+
**CULTURAL OVERVIEW:**
|
| 818 |
+
Provide a respectful, nuanced introduction to ${country.name} culture, avoiding stereotypes.
|
| 819 |
+
|
| 820 |
+
**KEY CULTURAL VALUES:**
|
| 821 |
+
List and explain 4-5 core values that guide this culture.
|
| 822 |
+
|
| 823 |
+
**DAILY LIFE INSIGHTS:**
|
| 824 |
+
Describe how these values manifest in everyday life.
|
| 825 |
+
|
| 826 |
+
${theme ? `**${theme.name.toUpperCase()} FOCUS:**
|
| 827 |
+
Provide detailed insights about ${theme.description} in ${country.name} culture.` : ''}
|
| 828 |
+
|
| 829 |
+
**HISTORICAL CONTEXT:**
|
| 830 |
+
Brief background on how history shaped current cultural practices.
|
| 831 |
+
|
| 832 |
+
**MODERN ADAPTATIONS:**
|
| 833 |
+
How this culture navigates contemporary global challenges while preserving traditions.
|
| 834 |
+
|
| 835 |
+
**COMMON MISCONCEPTIONS:**
|
| 836 |
+
Address 2-3 common stereotypes or misconceptions about this culture.
|
| 837 |
+
|
| 838 |
+
**CULTURAL WISDOM:**
|
| 839 |
+
Share a meaningful lesson or perspective this culture offers to the world.
|
| 840 |
+
|
| 841 |
+
Keep the tone educational, respectful, and engaging. Use specific examples while avoiding overgeneralization. Aim for 800-1000 words total.`;
|
| 842 |
+
};
|
| 843 |
+
|
| 844 |
+
const callOpenAI = async (prompt) => {
|
| 845 |
+
if (!apiKey) {
|
| 846 |
+
throw new Error('API key not provided');
|
| 847 |
+
}
|
| 848 |
+
|
| 849 |
+
const response = await fetch('https://api.openai.com/v1/chat/completions', {
|
| 850 |
+
method: 'POST',
|
| 851 |
+
headers: {
|
| 852 |
+
'Content-Type': 'application/json',
|
| 853 |
+
'Authorization': `Bearer ${apiKey.trim()}`
|
| 854 |
+
},
|
| 855 |
+
body: JSON.stringify({
|
| 856 |
+
model: 'gpt-4o-mini',
|
| 857 |
+
messages: [
|
| 858 |
+
{ role: 'system', content: 'You are a cultural intelligence educator focused on promoting empathy, understanding, and global citizenship.' },
|
| 859 |
+
{ role: 'user', content: prompt }
|
| 860 |
+
],
|
| 861 |
+
max_tokens: 1200,
|
| 862 |
+
temperature: 0.7
|
| 863 |
+
})
|
| 864 |
+
});
|
| 865 |
+
|
| 866 |
+
if (!response.ok) {
|
| 867 |
+
const errorData = await response.json().catch(() => ({}));
|
| 868 |
+
throw new Error(`OpenAI API error: ${response.status} ${response.statusText}${errorData.error ? ` - ${errorData.error.message}` : ''}`);
|
| 869 |
+
}
|
| 870 |
+
|
| 871 |
+
const data = await response.json();
|
| 872 |
+
|
| 873 |
+
if (!data.choices || !data.choices[0] || !data.choices[0].message) {
|
| 874 |
+
throw new Error('Invalid response format from OpenAI API');
|
| 875 |
+
}
|
| 876 |
+
|
| 877 |
+
return data.choices[0].message.content;
|
| 878 |
+
};
|
| 879 |
+
|
| 880 |
+
const proceedToReflection = () => {
|
| 881 |
+
setPhase(3);
|
| 882 |
+
};
|
| 883 |
+
|
| 884 |
+
const handleReflectionChange = (promptId, value) => {
|
| 885 |
+
setReflections(prev => ({
|
| 886 |
+
...prev,
|
| 887 |
+
[promptId]: value
|
| 888 |
+
}));
|
| 889 |
+
};
|
| 890 |
+
|
| 891 |
+
const proceedToAnalysis = () => {
|
| 892 |
+
setPhase(4);
|
| 893 |
+
generateAnalysis();
|
| 894 |
+
};
|
| 895 |
+
|
| 896 |
+
const generateAnalysis = async () => {
|
| 897 |
+
if (!apiKey || !selectedCountry || !insights) return;
|
| 898 |
+
|
| 899 |
+
setIsGeneratingAnalysis(true);
|
| 900 |
+
setAiError('');
|
| 901 |
+
|
| 902 |
+
try {
|
| 903 |
+
const prompt = createAnalysisPrompt();
|
| 904 |
+
const response = await callOpenAI(prompt);
|
| 905 |
+
setAnalysis(response);
|
| 906 |
+
} catch (error) {
|
| 907 |
+
console.error('Error generating analysis:', error);
|
| 908 |
+
setAiError(`Failed to generate analysis: ${error.message}`);
|
| 909 |
+
} finally {
|
| 910 |
+
setIsGeneratingAnalysis(false);
|
| 911 |
+
}
|
| 912 |
+
};
|
| 913 |
+
|
| 914 |
+
const createAnalysisPrompt = () => {
|
| 915 |
+
const country = selectedCountry;
|
| 916 |
+
const theme = selectedTheme;
|
| 917 |
+
const reflectionText = Object.entries(reflections)
|
| 918 |
+
.map(([key, value]) => {
|
| 919 |
+
const prompt = REFLECTION_PROMPTS.find(p => p.id === key);
|
| 920 |
+
return `${prompt?.question}: ${value}`;
|
| 921 |
+
})
|
| 922 |
+
.join('\n\n');
|
| 923 |
+
|
| 924 |
+
return `You are a cultural intelligence educator analyzing a student's cultural exploration journey. Based on the cultural insights and student reflections below, provide a comprehensive analysis in a structured tabular format.
|
| 925 |
+
|
| 926 |
+
**CULTURAL CONTEXT:**
|
| 927 |
+
Country: ${country.name} (${country.region})
|
| 928 |
+
${theme ? `Focus Theme: ${theme.name} - ${theme.description}` : 'General cultural exploration'}
|
| 929 |
+
|
| 930 |
+
**CULTURAL INSIGHTS PROVIDED:**
|
| 931 |
+
${insights}
|
| 932 |
+
|
| 933 |
+
**STUDENT REFLECTIONS:**
|
| 934 |
+
${reflectionText}
|
| 935 |
+
|
| 936 |
+
**ANALYSIS REQUIREMENTS:**
|
| 937 |
+
Create a detailed analysis table with the following structure. Format your response as a structured table with clear rows and columns:
|
| 938 |
+
|
| 939 |
+
| Analysis Category | Cultural Theme Insights | Student Reflection Analysis | Comparison & Growth Indicators |
|
| 940 |
+
|-------------------|------------------------|----------------------------|-------------------------------|
|
| 941 |
+
| Cultural Understanding | [Key cultural insights from the theme] | [Analysis of student's understanding] | [Evidence of learning and growth] |
|
| 942 |
+
| Personal Connection | [How culture relates to universal themes] | [Student's personal connections made] | [Depth of empathy development] |
|
| 943 |
+
| Assumption Challenges | [Cultural misconceptions addressed] | [Student's assumption changes] | [Critical thinking evidence] |
|
| 944 |
+
| Learning Integration | [Key cultural lessons identified] | [Student's learning takeaways] | [Application potential] |
|
| 945 |
+
| Perspective Transformation | [Cultural wisdom shared] | [Student's perspective shifts] | [Global citizenship development] |
|
| 946 |
+
|
| 947 |
+
For each row, provide:
|
| 948 |
+
- 2-3 specific insights from the cultural theme
|
| 949 |
+
- Detailed analysis of the student's reflection quality and depth
|
| 950 |
+
- Evidence of learning, growth, and cultural intelligence development
|
| 951 |
+
- Specific examples and quotes from student responses where relevant
|
| 952 |
+
|
| 953 |
+
Keep the analysis educational, encouraging, and focused on cultural intelligence development. Highlight strengths and areas for continued growth.`;
|
| 954 |
+
};
|
| 955 |
+
|
| 956 |
+
const completeExploration = () => {
|
| 957 |
+
const exploration = {
|
| 958 |
+
id: Date.now(),
|
| 959 |
+
timestamp: new Date().toISOString(),
|
| 960 |
+
country: selectedCountry,
|
| 961 |
+
theme: selectedTheme,
|
| 962 |
+
insights: insights,
|
| 963 |
+
reflections: reflections,
|
| 964 |
+
analysis: analysis
|
| 965 |
+
};
|
| 966 |
+
|
| 967 |
+
setExplorationHistory(prev => [...prev, exploration]);
|
| 968 |
+
|
| 969 |
+
// Reset for new exploration
|
| 970 |
+
setPhase(1);
|
| 971 |
+
setSelectedCountry(null);
|
| 972 |
+
setSelectedTheme(null);
|
| 973 |
+
setInsights(null);
|
| 974 |
+
setReflections({});
|
| 975 |
+
setAnalysis(null);
|
| 976 |
+
setAiError('');
|
| 977 |
+
};
|
| 978 |
+
|
| 979 |
+
const validateApiKey = async (key) => {
|
| 980 |
+
try {
|
| 981 |
+
const response = await fetch('https://api.openai.com/v1/models', {
|
| 982 |
+
headers: {
|
| 983 |
+
'Authorization': `Bearer ${key.trim()}`
|
| 984 |
+
}
|
| 985 |
+
});
|
| 986 |
+
|
| 987 |
+
if (!response.ok) {
|
| 988 |
+
throw new Error('Invalid API key');
|
| 989 |
+
}
|
| 990 |
+
|
| 991 |
+
return true;
|
| 992 |
+
} catch (error) {
|
| 993 |
+
throw new Error('Invalid API key. Please check and try again.');
|
| 994 |
+
}
|
| 995 |
+
};
|
| 996 |
+
|
| 997 |
+
const handleApiKeySubmit = async (key) => {
|
| 998 |
+
try {
|
| 999 |
+
await validateApiKey(key);
|
| 1000 |
+
setApiKey(key);
|
| 1001 |
+
setShowApiKeyModal(false);
|
| 1002 |
+
setPhase(2);
|
| 1003 |
+
generateInsights();
|
| 1004 |
+
} catch (error) {
|
| 1005 |
+
setAiError(error.message);
|
| 1006 |
+
}
|
| 1007 |
+
};
|
| 1008 |
+
|
| 1009 |
+
const formatInsights = (content) => {
|
| 1010 |
+
// Convert markdown-style formatting to HTML
|
| 1011 |
+
let formatted = content
|
| 1012 |
+
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
| 1013 |
+
.replace(/^• (.+)$/gm, '<li>$1</li>')
|
| 1014 |
+
.replace(/^- (.+)$/gm, '<li>$1</li>')
|
| 1015 |
+
.split('\n\n')
|
| 1016 |
+
.map(paragraph => {
|
| 1017 |
+
if (paragraph.includes('<li>')) {
|
| 1018 |
+
return `<ul class="list-disc list-inside space-y-1">${paragraph}</ul>`;
|
| 1019 |
+
}
|
| 1020 |
+
return paragraph.trim() ? `<p class="mb-3">${paragraph.trim()}</p>` : '';
|
| 1021 |
+
})
|
| 1022 |
+
.join('');
|
| 1023 |
+
|
| 1024 |
+
return formatted;
|
| 1025 |
+
};
|
| 1026 |
+
|
| 1027 |
+
const parseAnalysisTable = (content) => {
|
| 1028 |
+
// Parse the AI response into a structured table format
|
| 1029 |
+
const lines = content.split('\n').filter(line => line.trim());
|
| 1030 |
+
const tableData = [];
|
| 1031 |
+
|
| 1032 |
+
let currentRow = null;
|
| 1033 |
+
let inTable = false;
|
| 1034 |
+
|
| 1035 |
+
for (const line of lines) {
|
| 1036 |
+
if (line.includes('|') && line.includes('Analysis Category')) {
|
| 1037 |
+
inTable = true;
|
| 1038 |
+
continue;
|
| 1039 |
+
}
|
| 1040 |
+
|
| 1041 |
+
if (line.includes('|') && line.includes('---')) {
|
| 1042 |
+
continue;
|
| 1043 |
+
}
|
| 1044 |
+
|
| 1045 |
+
if (inTable && line.includes('|')) {
|
| 1046 |
+
const cells = line.split('|').map(cell => cell.trim()).filter(cell => cell);
|
| 1047 |
+
if (cells.length >= 4) {
|
| 1048 |
+
tableData.push({
|
| 1049 |
+
category: cells[0],
|
| 1050 |
+
cultural: cells[1],
|
| 1051 |
+
reflection: cells[2],
|
| 1052 |
+
comparison: cells[3]
|
| 1053 |
+
});
|
| 1054 |
+
}
|
| 1055 |
+
}
|
| 1056 |
+
}
|
| 1057 |
+
|
| 1058 |
+
// If no table found, create a simple structure from the content
|
| 1059 |
+
if (tableData.length === 0) {
|
| 1060 |
+
const sections = content.split('\n\n');
|
| 1061 |
+
sections.forEach((section, index) => {
|
| 1062 |
+
if (section.trim()) {
|
| 1063 |
+
tableData.push({
|
| 1064 |
+
category: `Analysis ${index + 1}`,
|
| 1065 |
+
cultural: section.substring(0, 200) + '...',
|
| 1066 |
+
reflection: 'Detailed analysis provided',
|
| 1067 |
+
comparison: 'Growth indicators identified'
|
| 1068 |
+
});
|
| 1069 |
+
}
|
| 1070 |
+
});
|
| 1071 |
+
}
|
| 1072 |
+
|
| 1073 |
+
return tableData;
|
| 1074 |
+
};
|
| 1075 |
+
|
| 1076 |
+
const getProgressPercentage = () => {
|
| 1077 |
+
return (phase / 4) * 100;
|
| 1078 |
+
};
|
| 1079 |
+
|
| 1080 |
+
// API Key Modal Component
|
| 1081 |
+
const ApiKeyModal = () => {
|
| 1082 |
+
const [keyInput, setKeyInput] = useState('');
|
| 1083 |
+
const [isValidating, setIsValidating] = useState(false);
|
| 1084 |
+
|
| 1085 |
+
const handleSubmit = async (e) => {
|
| 1086 |
+
e.preventDefault();
|
| 1087 |
+
if (!keyInput.trim()) return;
|
| 1088 |
+
|
| 1089 |
+
setIsValidating(true);
|
| 1090 |
+
try {
|
| 1091 |
+
await handleApiKeySubmit(keyInput);
|
| 1092 |
+
} catch (error) {
|
| 1093 |
+
// Error is handled in parent component
|
| 1094 |
+
} finally {
|
| 1095 |
+
setIsValidating(false);
|
| 1096 |
+
}
|
| 1097 |
+
};
|
| 1098 |
+
|
| 1099 |
+
return (
|
| 1100 |
+
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
|
| 1101 |
+
<div className="glass p-6 max-w-md w-full">
|
| 1102 |
+
<h3 className="text-xl font-bold text-gray-800 mb-4">🔑 OpenAI API Key Required</h3>
|
| 1103 |
+
<p className="text-gray-600 mb-4">
|
| 1104 |
+
To generate cultural insights, please provide your OpenAI API key.
|
| 1105 |
+
This will be stored locally and used only for this application.
|
| 1106 |
+
</p>
|
| 1107 |
+
<form onSubmit={handleSubmit}>
|
| 1108 |
+
<input
|
| 1109 |
+
type="password"
|
| 1110 |
+
value={keyInput}
|
| 1111 |
+
onChange={(e) => setKeyInput(e.target.value)}
|
| 1112 |
+
placeholder="sk-..."
|
| 1113 |
+
className="w-full px-3 py-2 border rounded-lg mb-4"
|
| 1114 |
+
autoFocus
|
| 1115 |
+
/>
|
| 1116 |
+
<div className="flex gap-2">
|
| 1117 |
+
<button
|
| 1118 |
+
type="submit"
|
| 1119 |
+
disabled={!keyInput.trim() || isValidating}
|
| 1120 |
+
className="flex-1 bg-blue-600 text-white py-2 rounded-lg hover:bg-blue-700 transition disabled:opacity-50"
|
| 1121 |
+
>
|
| 1122 |
+
{isValidating ? 'Validating...' : 'Continue'}
|
| 1123 |
+
</button>
|
| 1124 |
+
<button
|
| 1125 |
+
type="button"
|
| 1126 |
+
onClick={() => setShowApiKeyModal(false)}
|
| 1127 |
+
className="px-4 py-2 bg-gray-300 text-gray-700 rounded-lg hover:bg-gray-400 transition"
|
| 1128 |
+
>
|
| 1129 |
+
Cancel
|
| 1130 |
+
</button>
|
| 1131 |
+
</div>
|
| 1132 |
+
</form>
|
| 1133 |
+
{aiError && (
|
| 1134 |
+
<div className="mt-3 text-red-600 text-sm">{aiError}</div>
|
| 1135 |
+
)}
|
| 1136 |
+
<p className="text-xs text-gray-500 mt-3">
|
| 1137 |
+
Get your API key at <a href="https://platform.openai.com/api-keys" target="_blank" rel="noopener noreferrer" className="text-blue-600 underline">OpenAI</a>
|
| 1138 |
+
</p>
|
| 1139 |
+
</div>
|
| 1140 |
+
</div>
|
| 1141 |
+
);
|
| 1142 |
+
};
|
| 1143 |
+
|
| 1144 |
+
return (
|
| 1145 |
+
<div className="min-h-screen py-6">
|
| 1146 |
+
<div className="max-w-6xl mx-auto px-4">
|
| 1147 |
+
{/* Header */}
|
| 1148 |
+
<div className="glass p-6 mb-6 text-center">
|
| 1149 |
+
<h1 className="text-4xl font-bold text-gray-800 mb-2">
|
| 1150 |
+
🌍 Cultural Intelligence Explorer
|
| 1151 |
+
</h1>
|
| 1152 |
+
<p className="text-gray-600 mb-4">
|
| 1153 |
+
Develop empathy and global citizenship through cultural exploration
|
| 1154 |
+
</p>
|
| 1155 |
+
<p className="text-sm text-blue-600 font-semibold">
|
| 1156 |
+
Global Edition with AI Analysis - Explore any country in the world!
|
| 1157 |
+
</p>
|
| 1158 |
+
|
| 1159 |
+
{/* Progress Bar */}
|
| 1160 |
+
<div className="max-w-md mx-auto mt-4">
|
| 1161 |
+
<div className="flex justify-between text-xs text-gray-500 mb-2">
|
| 1162 |
+
<span className={phase >= 1 ? 'text-blue-600 font-semibold' : ''}>Selection</span>
|
| 1163 |
+
<span className={phase >= 2 ? 'text-blue-600 font-semibold' : ''}>Insights</span>
|
| 1164 |
+
<span className={phase >= 3 ? 'text-blue-600 font-semibold' : ''}>Reflection</span>
|
| 1165 |
+
<span className={phase >= 4 ? 'text-blue-600 font-semibold' : ''}>Analysis</span>
|
| 1166 |
+
</div>
|
| 1167 |
+
<div className="w-full bg-gray-200 rounded-full h-2">
|
| 1168 |
+
<div
|
| 1169 |
+
className="progress-bar rounded-full h-2"
|
| 1170 |
+
style={{ width: `${getProgressPercentage()}%` }}
|
| 1171 |
+
></div>
|
| 1172 |
+
</div>
|
| 1173 |
+
</div>
|
| 1174 |
+
</div>
|
| 1175 |
+
|
| 1176 |
+
{/* Phase 1: Cultural Selection */}
|
| 1177 |
+
{phase === 1 && (
|
| 1178 |
+
<div className="fade-in">
|
| 1179 |
+
<div className="glass p-6 mb-6">
|
| 1180 |
+
<h2 className="text-2xl font-bold text-gray-800 mb-4">
|
| 1181 |
+
🎯 Phase 1: Choose Your Cultural Journey
|
| 1182 |
+
</h2>
|
| 1183 |
+
<p className="text-gray-600 mb-6">
|
| 1184 |
+
Select any country in the world to explore and optionally choose a specific theme to focus on.
|
| 1185 |
+
</p>
|
| 1186 |
+
|
| 1187 |
+
{/* Country Selection */}
|
| 1188 |
+
<div className="mb-8">
|
| 1189 |
+
<div className="country-dropdown">
|
| 1190 |
+
<h3 className="text-xl font-semibold mb-4">🌎 Select a Country</h3>
|
| 1191 |
+
<p className="text-sm opacity-90 mb-4">
|
| 1192 |
+
Search from {WORLD_COUNTRIES.length} countries worldwide
|
| 1193 |
+
</p>
|
| 1194 |
+
<CountryDropdown
|
| 1195 |
+
selectedCountry={selectedCountry}
|
| 1196 |
+
onCountrySelect={handleCountrySelect}
|
| 1197 |
+
/>
|
| 1198 |
+
</div>
|
| 1199 |
+
</div>
|
| 1200 |
+
|
| 1201 |
+
{/* Theme Selection */}
|
| 1202 |
+
<div className="mb-8">
|
| 1203 |
+
<h3 className="text-xl font-semibold text-gray-700 mb-4">
|
| 1204 |
+
Choose a Focus Theme (Optional)
|
| 1205 |
+
</h3>
|
| 1206 |
+
<div className="grid grid-cols-2 md:grid-cols-4 gap-3 theme-grid">
|
| 1207 |
+
{THEMES.map(theme => (
|
| 1208 |
+
<div
|
| 1209 |
+
key={theme.id}
|
| 1210 |
+
className={`theme-card ${selectedTheme?.id === theme.id ? 'selected' : ''}`}
|
| 1211 |
+
onClick={() => handleThemeSelect(selectedTheme?.id === theme.id ? null : theme)}
|
| 1212 |
+
tabIndex={0}
|
| 1213 |
+
role="button"
|
| 1214 |
+
aria-pressed={selectedTheme?.id === theme.id}
|
| 1215 |
+
onKeyPress={(e) => e.key === 'Enter' && handleThemeSelect(selectedTheme?.id === theme.id ? null : theme)}
|
| 1216 |
+
>
|
| 1217 |
+
<div className="text-2xl mb-2">{theme.icon}</div>
|
| 1218 |
+
<h4 className="font-semibold text-sm">{theme.name}</h4>
|
| 1219 |
+
<p className="text-xs opacity-80 mt-1">{theme.description}</p>
|
| 1220 |
+
</div>
|
| 1221 |
+
))}
|
| 1222 |
+
</div>
|
| 1223 |
+
</div>
|
| 1224 |
+
|
| 1225 |
+
{/* Selection Summary */}
|
| 1226 |
+
{selectedCountry && (
|
| 1227 |
+
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">
|
| 1228 |
+
<h4 className="font-semibold text-blue-800 mb-2">Your Selection:</h4>
|
| 1229 |
+
<p className="text-blue-700">
|
| 1230 |
+
<strong>{selectedCountry.flag} {selectedCountry.name}</strong> ({selectedCountry.region})
|
| 1231 |
+
{selectedTheme && (
|
| 1232 |
+
<span> - Focus: {selectedTheme.icon} {selectedTheme.name}</span>
|
| 1233 |
+
)}
|
| 1234 |
+
</p>
|
| 1235 |
+
</div>
|
| 1236 |
+
)}
|
| 1237 |
+
|
| 1238 |
+
{/* Continue Button */}
|
| 1239 |
+
<div className="text-center">
|
| 1240 |
+
<button
|
| 1241 |
+
onClick={proceedToInsights}
|
| 1242 |
+
disabled={!selectedCountry}
|
| 1243 |
+
className="bg-gradient-to-r from-blue-600 to-purple-600 text-white px-8 py-3 rounded-lg font-semibold hover:from-blue-700 hover:to-purple-700 transition disabled:opacity-50 disabled:cursor-not-allowed"
|
| 1244 |
+
>
|
| 1245 |
+
Explore Culture 🚀
|
| 1246 |
+
</button>
|
| 1247 |
+
</div>
|
| 1248 |
+
</div>
|
| 1249 |
+
</div>
|
| 1250 |
+
)}
|
| 1251 |
+
|
| 1252 |
+
{/* Phase 2: AI Cultural Insights */}
|
| 1253 |
+
{phase === 2 && (
|
| 1254 |
+
<div className="fade-in">
|
| 1255 |
+
<div className="glass p-6 mb-6">
|
| 1256 |
+
<div className="flex items-center justify-between mb-6">
|
| 1257 |
+
<div>
|
| 1258 |
+
<h2 className="text-2xl font-bold text-gray-800">
|
| 1259 |
+
🧠 Phase 2: Cultural Insights
|
| 1260 |
+
</h2>
|
| 1261 |
+
<p className="text-gray-600">
|
| 1262 |
+
Exploring {selectedCountry?.flag} {selectedCountry?.name} ({selectedCountry?.region})
|
| 1263 |
+
{selectedTheme && ` - ${selectedTheme.icon} ${selectedTheme.name}`}
|
| 1264 |
+
</p>
|
| 1265 |
+
</div>
|
| 1266 |
+
<button
|
| 1267 |
+
onClick={() => setPhase(1)}
|
| 1268 |
+
className="text-blue-600 hover:text-blue-800 transition"
|
| 1269 |
+
>
|
| 1270 |
+
← Back to Selection
|
| 1271 |
+
</button>
|
| 1272 |
+
</div>
|
| 1273 |
+
|
| 1274 |
+
{isGeneratingInsights && (
|
| 1275 |
+
<div className="text-center py-12">
|
| 1276 |
+
<div className="typing-indicator mb-4">
|
| 1277 |
+
<span className="text-lg text-gray-600 mr-3">Generating cultural insights</span>
|
| 1278 |
+
<div className="typing-dot"></div>
|
| 1279 |
+
<div className="typing-dot"></div>
|
| 1280 |
+
<div className="typing-dot"></div>
|
| 1281 |
+
</div>
|
| 1282 |
+
<p className="text-gray-500">This may take a moment...</p>
|
| 1283 |
+
</div>
|
| 1284 |
+
)}
|
| 1285 |
+
|
| 1286 |
+
{aiError && (
|
| 1287 |
+
<div className="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">
|
| 1288 |
+
<h4 className="font-semibold text-red-800 mb-2">Error:</h4>
|
| 1289 |
+
<p className="text-red-700">{aiError}</p>
|
| 1290 |
+
<button
|
| 1291 |
+
onClick={generateInsights}
|
| 1292 |
+
className="mt-3 bg-red-600 text-white px-4 py-2 rounded hover:bg-red-700 transition"
|
| 1293 |
+
>
|
| 1294 |
+
Try Again
|
| 1295 |
+
</button>
|
| 1296 |
+
</div>
|
| 1297 |
+
)}
|
| 1298 |
+
|
| 1299 |
+
{insights && (
|
| 1300 |
+
<div className="slide-in">
|
| 1301 |
+
<div className="insight-section">
|
| 1302 |
+
<div
|
| 1303 |
+
className="prose prose-lg max-w-none"
|
| 1304 |
+
dangerouslySetInnerHTML={{ __html: formatInsights(insights) }}
|
| 1305 |
+
/>
|
| 1306 |
+
</div>
|
| 1307 |
+
|
| 1308 |
+
<div className="text-center mt-8">
|
| 1309 |
+
<button
|
| 1310 |
+
onClick={proceedToReflection}
|
| 1311 |
+
className="bg-gradient-to-r from-green-600 to-blue-600 text-white px-8 py-3 rounded-lg font-semibold hover:from-green-700 hover:to-blue-700 transition"
|
| 1312 |
+
>
|
| 1313 |
+
Reflect on Learning 💭
|
| 1314 |
+
</button>
|
| 1315 |
+
</div>
|
| 1316 |
+
</div>
|
| 1317 |
+
)}
|
| 1318 |
+
</div>
|
| 1319 |
+
</div>
|
| 1320 |
+
)}
|
| 1321 |
+
|
| 1322 |
+
{/* Phase 3: Reflection & Comparison */}
|
| 1323 |
+
{phase === 3 && (
|
| 1324 |
+
<div className="fade-in">
|
| 1325 |
+
<div className="glass p-6 mb-6">
|
| 1326 |
+
<div className="flex items-center justify-between mb-6">
|
| 1327 |
+
<div>
|
| 1328 |
+
<h2 className="text-2xl font-bold text-gray-800">
|
| 1329 |
+
💭 Phase 3: Reflection & Growth
|
| 1330 |
+
</h2>
|
| 1331 |
+
<p className="text-gray-600">
|
| 1332 |
+
Reflect on your cultural exploration and personal insights
|
| 1333 |
+
</p>
|
| 1334 |
+
</div>
|
| 1335 |
+
<button
|
| 1336 |
+
onClick={() => setPhase(2)}
|
| 1337 |
+
className="text-blue-600 hover:text-blue-800 transition"
|
| 1338 |
+
>
|
| 1339 |
+
← Back to Insights
|
| 1340 |
+
</button>
|
| 1341 |
+
</div>
|
| 1342 |
+
|
| 1343 |
+
<div className="space-y-6">
|
| 1344 |
+
{REFLECTION_PROMPTS.map(prompt => (
|
| 1345 |
+
<div key={prompt.id} className="reflection-card">
|
| 1346 |
+
<div className="flex items-start gap-3 mb-3">
|
| 1347 |
+
<span className="text-2xl">{prompt.icon}</span>
|
| 1348 |
+
<h3 className="font-semibold text-gray-800 flex-1">
|
| 1349 |
+
{prompt.question}
|
| 1350 |
+
</h3>
|
| 1351 |
+
</div>
|
| 1352 |
+
<textarea
|
| 1353 |
+
value={reflections[prompt.id] || ''}
|
| 1354 |
+
onChange={(e) => handleReflectionChange(prompt.id, e.target.value)}
|
| 1355 |
+
placeholder="Share your thoughts and insights..."
|
| 1356 |
+
className="w-full px-4 py-3 border border-gray-300 rounded-lg resize-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
| 1357 |
+
rows={4}
|
| 1358 |
+
/>
|
| 1359 |
+
</div>
|
| 1360 |
+
))}
|
| 1361 |
+
</div>
|
| 1362 |
+
|
| 1363 |
+
<div className="text-center mt-8">
|
| 1364 |
+
<button
|
| 1365 |
+
onClick={proceedToAnalysis}
|
| 1366 |
+
className="bg-gradient-to-r from-purple-600 to-pink-600 text-white px-8 py-3 rounded-lg font-semibold hover:from-purple-700 hover:to-pink-700 transition"
|
| 1367 |
+
>
|
| 1368 |
+
Generate AI Analysis 📊
|
| 1369 |
+
</button>
|
| 1370 |
+
</div>
|
| 1371 |
+
</div>
|
| 1372 |
+
</div>
|
| 1373 |
+
)}
|
| 1374 |
+
|
| 1375 |
+
{/* Phase 4: AI Analysis & Comparison */}
|
| 1376 |
+
{phase === 4 && (
|
| 1377 |
+
<div className="fade-in">
|
| 1378 |
+
<div className="glass p-6 mb-6">
|
| 1379 |
+
<div className="flex items-center justify-between mb-6">
|
| 1380 |
+
<div>
|
| 1381 |
+
<h2 className="text-2xl font-bold text-gray-800">
|
| 1382 |
+
📊 Phase 4: AI Analysis & Insights
|
| 1383 |
+
</h2>
|
| 1384 |
+
<p className="text-gray-600">
|
| 1385 |
+
AI-powered comparison between cultural themes and your reflections
|
| 1386 |
+
</p>
|
| 1387 |
+
</div>
|
| 1388 |
+
<button
|
| 1389 |
+
onClick={() => setPhase(3)}
|
| 1390 |
+
className="text-blue-600 hover:text-blue-800 transition"
|
| 1391 |
+
>
|
| 1392 |
+
← Back to Reflection
|
| 1393 |
+
</button>
|
| 1394 |
+
</div>
|
| 1395 |
+
|
| 1396 |
+
{isGeneratingAnalysis && (
|
| 1397 |
+
<div className="text-center py-12">
|
| 1398 |
+
<div className="typing-indicator mb-4">
|
| 1399 |
+
<span className="text-lg text-gray-600 mr-3">Analyzing your cultural journey</span>
|
| 1400 |
+
<div className="typing-dot"></div>
|
| 1401 |
+
<div className="typing-dot"></div>
|
| 1402 |
+
<div className="typing-dot"></div>
|
| 1403 |
+
</div>
|
| 1404 |
+
<p className="text-gray-500">Creating personalized insights...</p>
|
| 1405 |
+
</div>
|
| 1406 |
+
)}
|
| 1407 |
+
|
| 1408 |
+
{aiError && (
|
| 1409 |
+
<div className="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">
|
| 1410 |
+
<h4 className="font-semibold text-red-800 mb-2">Error:</h4>
|
| 1411 |
+
<p className="text-red-700">{aiError}</p>
|
| 1412 |
+
<button
|
| 1413 |
+
onClick={generateAnalysis}
|
| 1414 |
+
className="mt-3 bg-red-600 text-white px-4 py-2 rounded hover:bg-red-700 transition"
|
| 1415 |
+
>
|
| 1416 |
+
Try Again
|
| 1417 |
+
</button>
|
| 1418 |
+
</div>
|
| 1419 |
+
)}
|
| 1420 |
+
|
| 1421 |
+
{analysis && (
|
| 1422 |
+
<div className="slide-in">
|
| 1423 |
+
<div className="mb-6">
|
| 1424 |
+
<h3 className="text-xl font-semibold text-gray-800 mb-4">
|
| 1425 |
+
🎯 Cultural Intelligence Analysis
|
| 1426 |
+
</h3>
|
| 1427 |
+
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">
|
| 1428 |
+
<p className="text-blue-700">
|
| 1429 |
+
<strong>Analysis for:</strong> {selectedCountry?.flag} {selectedCountry?.name}
|
| 1430 |
+
{selectedTheme && ` - ${selectedTheme.icon} ${selectedTheme.name}`}
|
| 1431 |
+
</p>
|
| 1432 |
+
</div>
|
| 1433 |
+
</div>
|
| 1434 |
+
|
| 1435 |
+
<div className="analysis-table mb-8">
|
| 1436 |
+
<table>
|
| 1437 |
+
<thead>
|
| 1438 |
+
<tr>
|
| 1439 |
+
<th className="w-1/4">Analysis Category</th>
|
| 1440 |
+
<th className="w-1/4">Cultural Theme Insights</th>
|
| 1441 |
+
<th className="w-1/4">Your Reflection Analysis</th>
|
| 1442 |
+
<th className="w-1/4">Growth Indicators</th>
|
| 1443 |
+
</tr>
|
| 1444 |
+
</thead>
|
| 1445 |
+
<tbody>
|
| 1446 |
+
{parseAnalysisTable(analysis).map((row, index) => (
|
| 1447 |
+
<tr key={index}>
|
| 1448 |
+
<td className="font-semibold text-gray-800">
|
| 1449 |
+
{row.category}
|
| 1450 |
+
<div className="mt-2">
|
| 1451 |
+
<span className="insight-badge">Cultural Insight</span>
|
| 1452 |
+
</div>
|
| 1453 |
+
</td>
|
| 1454 |
+
<td className="text-gray-700">
|
| 1455 |
+
{row.cultural}
|
| 1456 |
+
</td>
|
| 1457 |
+
<td className="text-gray-700">
|
| 1458 |
+
{row.reflection}
|
| 1459 |
+
<div className="mt-2">
|
| 1460 |
+
<span className="comparison-badge">Personal Growth</span>
|
| 1461 |
+
</div>
|
| 1462 |
+
</td>
|
| 1463 |
+
<td className="text-gray-700">
|
| 1464 |
+
{row.comparison}
|
| 1465 |
+
</td>
|
| 1466 |
+
</tr>
|
| 1467 |
+
))}
|
| 1468 |
+
</tbody>
|
| 1469 |
+
</table>
|
| 1470 |
+
</div>
|
| 1471 |
+
|
| 1472 |
+
<div className="text-center mt-8">
|
| 1473 |
+
<button
|
| 1474 |
+
onClick={completeExploration}
|
| 1475 |
+
className="bg-gradient-to-r from-green-600 to-teal-600 text-white px-8 py-3 rounded-lg font-semibold hover:from-green-700 hover:to-teal-700 transition"
|
| 1476 |
+
>
|
| 1477 |
+
Complete Exploration ✨
|
| 1478 |
+
</button>
|
| 1479 |
+
</div>
|
| 1480 |
+
</div>
|
| 1481 |
+
)}
|
| 1482 |
+
</div>
|
| 1483 |
+
</div>
|
| 1484 |
+
)}
|
| 1485 |
+
|
| 1486 |
+
{/* Exploration History */}
|
| 1487 |
+
{explorationHistory.length > 0 && (
|
| 1488 |
+
<div className="glass p-6">
|
| 1489 |
+
<h3 className="text-xl font-bold text-gray-800 mb-4">
|
| 1490 |
+
📚 Your Cultural Journey
|
| 1491 |
+
</h3>
|
| 1492 |
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
| 1493 |
+
{explorationHistory.slice(-6).map(exploration => (
|
| 1494 |
+
<div key={exploration.id} className="bg-white rounded-lg p-4 border border-gray-200">
|
| 1495 |
+
<div className="flex items-center gap-2 mb-2">
|
| 1496 |
+
<span className="text-xl">{exploration.country.flag}</span>
|
| 1497 |
+
<h4 className="font-semibold text-gray-800">{exploration.country.name}</h4>
|
| 1498 |
+
</div>
|
| 1499 |
+
<p className="text-xs text-gray-500 mb-1">{exploration.country.region}</p>
|
| 1500 |
+
{exploration.theme && (
|
| 1501 |
+
<p className="text-sm text-gray-600 mb-2">
|
| 1502 |
+
{exploration.theme.icon} {exploration.theme.name}
|
| 1503 |
+
</p>
|
| 1504 |
+
)}
|
| 1505 |
+
<div className="flex gap-1 mb-2">
|
| 1506 |
+
<span className="insight-badge text-xs">Insights</span>
|
| 1507 |
+
<span className="comparison-badge text-xs">Analysis</span>
|
| 1508 |
+
</div>
|
| 1509 |
+
<p className="text-xs text-gray-500">
|
| 1510 |
+
{new Date(exploration.timestamp).toLocaleDateString()}
|
| 1511 |
+
</p>
|
| 1512 |
+
</div>
|
| 1513 |
+
))}
|
| 1514 |
+
</div>
|
| 1515 |
+
<p className="text-center text-gray-500 mt-4">
|
| 1516 |
+
{explorationHistory.length} culture{explorationHistory.length !== 1 ? 's' : ''} explored with AI analysis
|
| 1517 |
+
</p>
|
| 1518 |
+
</div>
|
| 1519 |
+
)}
|
| 1520 |
+
</div>
|
| 1521 |
+
|
| 1522 |
+
{/* API Key Modal */}
|
| 1523 |
+
{showApiKeyModal && <ApiKeyModal />}
|
| 1524 |
+
</div>
|
| 1525 |
+
);
|
| 1526 |
+
}
|
| 1527 |
+
|
| 1528 |
+
ReactDOM.createRoot(document.getElementById("root")).render(<CulturalIntelligenceExplorer />);
|
| 1529 |
+
</script>
|
| 1530 |
+
</body>
|
| 1531 |
+
</html>
|
| 1532 |
+
|
📘 Step-by-Step Guide.txt
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
📘 Step-by-Step Guide: Cultural Intelligence Explorer
|
| 2 |
+
1. Introduction
|
| 3 |
+
The Cultural Intelligence Explorer empowers students and educators to explore, compare, and analyze cultures worldwide through AI-powered insights and guided reflection—helping everyone build empathy, self-awareness, and true global citizenship.
|
| 4 |
+
|
| 5 |
+
2. How to Use the Tool
|
| 6 |
+
A. Getting Started
|
| 7 |
+
Access the App:
|
| 8 |
+
Open “Cultural Intelligence Explorer.html” in your browser—no login, install, or sign-up required.
|
| 9 |
+
|
| 10 |
+
Select a Country and Theme:
|
| 11 |
+
|
| 12 |
+
Use the searchable dropdown to pick any country (with flag and region).
|
| 13 |
+
|
| 14 |
+
Optionally, choose a focus theme: family, education, food, values, communication, business, traditions, or challenges.
|
| 15 |
+
|
| 16 |
+
Provide Your OpenAI API Key:
|
| 17 |
+
|
| 18 |
+
When prompted, enter your OpenAI API key (see instructions in-app if you need one).
|
| 19 |
+
|
| 20 |
+
Your key is only stored in your browser for this tool.
|
| 21 |
+
|
| 22 |
+
B. Exploring and Reflecting
|
| 23 |
+
Generate AI Cultural Insights:
|
| 24 |
+
|
| 25 |
+
Click “Explore Culture.”
|
| 26 |
+
|
| 27 |
+
The tool provides a detailed, structured analysis of your chosen country/theme, including cultural overview, values, daily life, history, challenges, misconceptions, and cultural wisdom.
|
| 28 |
+
|
| 29 |
+
Reflect on Learning:
|
| 30 |
+
|
| 31 |
+
Respond to guided prompts: similarities, differences, surprises, challenged assumptions, valuable lessons, empathy development, and more.
|
| 32 |
+
|
| 33 |
+
Get AI-Powered Growth Analysis:
|
| 34 |
+
|
| 35 |
+
Click to generate a personalized analysis table.
|
| 36 |
+
|
| 37 |
+
See a structured comparison between cultural insights and your reflection—highlighting growth in understanding, empathy, and global citizenship.
|
| 38 |
+
|
| 39 |
+
Track and Review Your Journey:
|
| 40 |
+
|
| 41 |
+
All completed explorations are saved in your browser’s “journey” log—review at any time.
|
| 42 |
+
|
| 43 |
+
3. How It Supports Educators
|
| 44 |
+
Global Citizenship:
|
| 45 |
+
Build cultural intelligence, perspective-taking, and self-reflection as part of any subject.
|
| 46 |
+
|
| 47 |
+
Differentiation:
|
| 48 |
+
Students choose countries/themes for personally meaningful learning.
|
| 49 |
+
|
| 50 |
+
Formative/Summative Assessment:
|
| 51 |
+
Use reflection and AI analysis outputs as portfolio evidence or learning artifacts.
|
| 52 |
+
|
| 53 |
+
Safe for Schools:
|
| 54 |
+
Privacy-first, no logins, no central data collection.
|
| 55 |
+
|
| 56 |
+
4. How It Benefits Students
|
| 57 |
+
Personalized Global Learning:
|
| 58 |
+
Explore the world—your way. Every session is unique.
|
| 59 |
+
|
| 60 |
+
Empathy & Critical Thinking:
|
| 61 |
+
Evidence-based prompts drive deep reflection and growth.
|
| 62 |
+
|
| 63 |
+
Growth Feedback:
|
| 64 |
+
AI analysis shows your cultural intelligence progress.
|
| 65 |
+
|
| 66 |
+
Portfolio-Ready:
|
| 67 |
+
Use your journey log and AI feedback in digital portfolios or class projects.
|
| 68 |
+
|
| 69 |
+
5. Best Practices
|
| 70 |
+
Encourage students to explore multiple countries/themes.
|
| 71 |
+
|
| 72 |
+
Use reflections and AI tables for classroom or group discussions.
|
| 73 |
+
|
| 74 |
+
Have students compare journeys to highlight diversity and shared humanity.
|
| 75 |
+
|
| 76 |
+
Remind everyone to keep API keys private.
|