Spaces:
Running
Running
Upload 4 files
Browse files- Apache License.txt +17 -0
- README.md +102 -0
- index.html +1716 -0
- 📘 Educator & Business User Guide.txt +82 -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,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: "🏆 CompetitiveStrategy Pro – Advanced Porter's Five Forces Analysis"
|
| 3 |
+
emoji: "🏆"
|
| 4 |
+
colorFrom: "yellow"
|
| 5 |
+
colorTo: "green"
|
| 6 |
+
sdk: "static"
|
| 7 |
+
sdk_version: "0.1.0"
|
| 8 |
+
app_file: "index.html"
|
| 9 |
+
pinned: false
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
# 🏆 CompetitiveStrategy Pro – Advanced Porter's Five Forces Analysis
|
| 13 |
+
**Developed by Shift Mind AI Labs**
|
| 14 |
+
|
| 15 |
+
CompetitiveStrategy Pro is a next-generation, browser-based tool for performing deep, strategic Porter's Five Forces analysis—tailored to any industry or market scenario. Leveraging AI and a modern UX, it generates structured, multilingual, professionally formatted reports with actionable insights for business leaders, educators, and students. All processing is local and privacy-first.
|
| 16 |
+
|
| 17 |
+
---
|
| 18 |
+
|
| 19 |
+
## 🚀 Features
|
| 20 |
+
|
| 21 |
+
- **Full Five Forces Framework:**
|
| 22 |
+
AI-powered, context-aware analysis of all five competitive forces, with detailed sections and personalized insights.
|
| 23 |
+
- **Custom Industry Input:**
|
| 24 |
+
Paste your real industry scenario for a bespoke report.
|
| 25 |
+
- **Multilingual UI & Output:**
|
| 26 |
+
Instantly translates interface and output into 80+ languages (OpenAI API required, 100% client-side).
|
| 27 |
+
- **Professional, Responsive HTML Output:**
|
| 28 |
+
Clean, visually rich HTML with inline CSS—ready for reports, presentations, or LMS.
|
| 29 |
+
- **Privacy-First Design:**
|
| 30 |
+
No account, no cloud, no data sharing. All keys/data stay on your device.
|
| 31 |
+
- **Cache & Language Management:**
|
| 32 |
+
Instantly switch or clear cached translations for new projects or compliance.
|
| 33 |
+
|
| 34 |
+
---
|
| 35 |
+
|
| 36 |
+
## 🛠 How to Use
|
| 37 |
+
|
| 38 |
+
1. **Open the tool** in your browser (local or Hugging Face Space).
|
| 39 |
+
2. **Select your language** and enter your OpenAI API key (never leaves your device).
|
| 40 |
+
3. **Describe your industry or business scenario** in detail (minimum 50 characters for robust analysis).
|
| 41 |
+
4. **Click “Generate Five Forces Analysis.”**
|
| 42 |
+
5. **Review/copy** the structured, multi-section HTML report for your strategy, client, or class.
|
| 43 |
+
6. **Switch language** or clear translation cache as needed.
|
| 44 |
+
|
| 45 |
+
---
|
| 46 |
+
|
| 47 |
+
## 👩🏫 For Educators: Applications & Benefits
|
| 48 |
+
|
| 49 |
+
- **Business & Economics Classes:**
|
| 50 |
+
Guide students through real-world competitive analysis and market strategy.
|
| 51 |
+
- **PBL & MBA Programs:**
|
| 52 |
+
Use as a digital partner for capstone, consulting, or strategy projects.
|
| 53 |
+
- **Multilingual & Global:**
|
| 54 |
+
Interface and output in 80+ languages—ideal for diverse or international cohorts.
|
| 55 |
+
- **Portfolio Evidence:**
|
| 56 |
+
Export high-quality HTML output for student or faculty portfolios, accreditation, or presentations.
|
| 57 |
+
|
| 58 |
+
---
|
| 59 |
+
|
| 60 |
+
## 👨💼 For Business Leaders/Students
|
| 61 |
+
|
| 62 |
+
- **Strategic Planning:**
|
| 63 |
+
Analyze market entry, pricing, supply chain, and competitive risks for any business.
|
| 64 |
+
- **Pitch & Advisory:**
|
| 65 |
+
Generate board-ready, visually engaging analysis for investors, teams, or clients.
|
| 66 |
+
- **Comparison & Benchmarking:**
|
| 67 |
+
Repeat for different markets or time periods—instantly compare forces and strategies.
|
| 68 |
+
- **No Vendor Lock-in:**
|
| 69 |
+
All data and output are yours; export and use anywhere.
|
| 70 |
+
|
| 71 |
+
---
|
| 72 |
+
|
| 73 |
+
## 🔐 Data Privacy
|
| 74 |
+
|
| 75 |
+
- Your OpenAI API key and industry input **never leave your browser**.
|
| 76 |
+
- Nothing is transmitted to Shift Mind AI Labs, Hugging Face, or any third party.
|
| 77 |
+
|
| 78 |
+
---
|
| 79 |
+
|
| 80 |
+
## 📄 License
|
| 81 |
+
|
| 82 |
+
Licensed under the [Apache License 2.0](./LICENSE).
|
| 83 |
+
|
| 84 |
+
---
|
| 85 |
+
|
| 86 |
+
## 🧠 About Shift Mind AI Labs
|
| 87 |
+
|
| 88 |
+
Shift Mind AI Labs builds open-source, ethical AI tools for global education, strategy, and business analysis.
|
| 89 |
+
|
| 90 |
+
🌐 https://www.shiftmind.io
|
| 91 |
+
✉️ info@shiftmind.io
|
| 92 |
+
|
| 93 |
+
---
|
| 94 |
+
|
| 95 |
+
## 🙌 Contributing
|
| 96 |
+
|
| 97 |
+
Pull requests, feature ideas, and partnerships welcome!
|
| 98 |
+
For pilots, workshops, or consulting: **info@shiftmind.io**
|
| 99 |
+
|
| 100 |
+
---
|
| 101 |
+
|
| 102 |
+
*Strategic clarity, anywhere, in any language—powered by privacy-first AI.*
|
index.html
ADDED
|
@@ -0,0 +1,1716 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en" dir="ltr">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<title>CompetitiveStrategy Pro - Advanced Porter's Five Forces Analysis</title>
|
| 6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
| 7 |
+
<style>
|
| 8 |
+
:root {
|
| 9 |
+
--primary: #dc2626;
|
| 10 |
+
--secondary: #ef4444;
|
| 11 |
+
--accent: #f87171;
|
| 12 |
+
--background: #f8fafc;
|
| 13 |
+
--surface: #ffffff;
|
| 14 |
+
--text: #1e293b;
|
| 15 |
+
--text-secondary: #64748b;
|
| 16 |
+
--border: #e2e8f0;
|
| 17 |
+
--success: #10b981;
|
| 18 |
+
--warning: #f59e0b;
|
| 19 |
+
--error: #ef4444;
|
| 20 |
+
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
| 21 |
+
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
* {
|
| 25 |
+
box-sizing: border-box;
|
| 26 |
+
margin: 0;
|
| 27 |
+
padding: 0;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
body {
|
| 31 |
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
| 32 |
+
background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
|
| 33 |
+
color: var(--text);
|
| 34 |
+
line-height: 1.6;
|
| 35 |
+
min-height: 100vh;
|
| 36 |
+
padding: 15px;
|
| 37 |
+
transition: all 0.3s ease;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
/* RTL Support */
|
| 41 |
+
[dir="rtl"] {
|
| 42 |
+
text-align: right;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
[dir="rtl"] .container {
|
| 46 |
+
direction: rtl;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
[dir="rtl"] .api-key-section {
|
| 50 |
+
margin: 15px 15px 15px auto;
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
[dir="rtl"] .forces-overview {
|
| 54 |
+
direction: rtl;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
[dir="rtl"] .generate-btn {
|
| 58 |
+
direction: rtl;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
/* Language Selection Landing */
|
| 62 |
+
.language-landing {
|
| 63 |
+
display: block;
|
| 64 |
+
max-width: 600px;
|
| 65 |
+
margin: 50px auto;
|
| 66 |
+
background: var(--surface);
|
| 67 |
+
border-radius: 16px;
|
| 68 |
+
box-shadow: var(--shadow-lg);
|
| 69 |
+
padding: 40px;
|
| 70 |
+
text-align: center;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
.language-landing h1 {
|
| 74 |
+
font-size: 2.5rem;
|
| 75 |
+
font-weight: 800;
|
| 76 |
+
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
|
| 77 |
+
-webkit-background-clip: text;
|
| 78 |
+
-webkit-text-fill-color: transparent;
|
| 79 |
+
background-clip: text;
|
| 80 |
+
margin-bottom: 15px;
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
.language-landing p {
|
| 84 |
+
font-size: 1.1rem;
|
| 85 |
+
color: var(--text-secondary);
|
| 86 |
+
margin-bottom: 30px;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
.language-selector {
|
| 90 |
+
margin-bottom: 25px;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
.language-selector label {
|
| 94 |
+
display: block;
|
| 95 |
+
margin-bottom: 10px;
|
| 96 |
+
font-weight: 600;
|
| 97 |
+
color: var(--text);
|
| 98 |
+
font-size: 1.1rem;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
.language-selector select {
|
| 102 |
+
width: 100%;
|
| 103 |
+
padding: 15px 20px;
|
| 104 |
+
border: 2px solid var(--border);
|
| 105 |
+
border-radius: 12px;
|
| 106 |
+
font-size: 1.1rem;
|
| 107 |
+
font-family: inherit;
|
| 108 |
+
background: var(--surface);
|
| 109 |
+
transition: all 0.2s ease;
|
| 110 |
+
margin-bottom: 20px;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
.language-selector select:focus {
|
| 114 |
+
outline: none;
|
| 115 |
+
border-color: var(--primary);
|
| 116 |
+
box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1);
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
.api-key-landing {
|
| 120 |
+
margin-bottom: 25px;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
.api-key-landing label {
|
| 124 |
+
display: block;
|
| 125 |
+
margin-bottom: 10px;
|
| 126 |
+
font-weight: 600;
|
| 127 |
+
color: var(--text);
|
| 128 |
+
font-size: 1.1rem;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
.api-key-landing input {
|
| 132 |
+
width: 100%;
|
| 133 |
+
padding: 15px 20px;
|
| 134 |
+
border: 2px solid var(--border);
|
| 135 |
+
border-radius: 12px;
|
| 136 |
+
font-size: 1.1rem;
|
| 137 |
+
background: var(--surface);
|
| 138 |
+
transition: all 0.2s ease;
|
| 139 |
+
font-family: 'Courier New', monospace;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
.api-key-landing input:focus {
|
| 143 |
+
outline: none;
|
| 144 |
+
border-color: var(--primary);
|
| 145 |
+
box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1);
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
.start-btn {
|
| 149 |
+
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
|
| 150 |
+
color: white;
|
| 151 |
+
padding: 18px 40px;
|
| 152 |
+
border: none;
|
| 153 |
+
border-radius: 12px;
|
| 154 |
+
font-size: 1.2rem;
|
| 155 |
+
font-weight: 700;
|
| 156 |
+
cursor: pointer;
|
| 157 |
+
transition: all 0.3s ease;
|
| 158 |
+
width: 100%;
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
.start-btn:hover {
|
| 162 |
+
transform: translateY(-2px);
|
| 163 |
+
box-shadow: 0 12px 24px -8px rgba(220, 38, 38, 0.4);
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
.start-btn:disabled {
|
| 167 |
+
opacity: 0.7;
|
| 168 |
+
cursor: not-allowed;
|
| 169 |
+
transform: none;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
/* Cache Management Section */
|
| 173 |
+
.cache-management {
|
| 174 |
+
background: rgba(220, 38, 38, 0.05);
|
| 175 |
+
border: 1px solid rgba(220, 38, 38, 0.1);
|
| 176 |
+
border-radius: 12px;
|
| 177 |
+
padding: 20px;
|
| 178 |
+
margin-bottom: 25px;
|
| 179 |
+
text-align: center;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
.cache-management h3 {
|
| 183 |
+
color: var(--primary);
|
| 184 |
+
margin-bottom: 15px;
|
| 185 |
+
font-size: 1.1rem;
|
| 186 |
+
font-weight: 600;
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
.cache-status-display {
|
| 190 |
+
background: rgba(16, 185, 129, 0.1);
|
| 191 |
+
border: 1px solid rgba(16, 185, 129, 0.2);
|
| 192 |
+
color: var(--success);
|
| 193 |
+
padding: 12px 16px;
|
| 194 |
+
border-radius: 8px;
|
| 195 |
+
margin-bottom: 15px;
|
| 196 |
+
font-size: 0.9rem;
|
| 197 |
+
font-weight: 500;
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
.cache-status-display.no-cache {
|
| 201 |
+
background: rgba(100, 116, 139, 0.1);
|
| 202 |
+
border-color: rgba(100, 116, 139, 0.2);
|
| 203 |
+
color: var(--text-secondary);
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
.clear-cache-btn {
|
| 207 |
+
background: linear-gradient(135deg, var(--warning) 0%, #f59e0b 100%);
|
| 208 |
+
color: white;
|
| 209 |
+
padding: 12px 24px;
|
| 210 |
+
border: none;
|
| 211 |
+
border-radius: 8px;
|
| 212 |
+
font-size: 0.9rem;
|
| 213 |
+
font-weight: 600;
|
| 214 |
+
cursor: pointer;
|
| 215 |
+
transition: all 0.3s ease;
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
.clear-cache-btn:hover {
|
| 219 |
+
transform: translateY(-1px);
|
| 220 |
+
box-shadow: 0 6px 12px -4px rgba(245, 158, 11, 0.4);
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
.clear-cache-btn:disabled {
|
| 224 |
+
opacity: 0.5;
|
| 225 |
+
cursor: not-allowed;
|
| 226 |
+
transform: none;
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
/* Cache Status Indicator */
|
| 230 |
+
.cache-status {
|
| 231 |
+
background: rgba(16, 185, 129, 0.1);
|
| 232 |
+
border: 1px solid rgba(16, 185, 129, 0.2);
|
| 233 |
+
color: var(--success);
|
| 234 |
+
padding: 8px 12px;
|
| 235 |
+
border-radius: 6px;
|
| 236 |
+
margin-bottom: 15px;
|
| 237 |
+
font-size: 0.85rem;
|
| 238 |
+
text-align: center;
|
| 239 |
+
font-weight: 500;
|
| 240 |
+
display: none;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
.cache-status.cached {
|
| 244 |
+
display: block;
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
.cache-status.translating {
|
| 248 |
+
background: rgba(220, 38, 38, 0.1);
|
| 249 |
+
border-color: rgba(220, 38, 38, 0.2);
|
| 250 |
+
color: var(--primary);
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
/* Translation Loading Overlay */
|
| 254 |
+
.translation-overlay {
|
| 255 |
+
position: fixed;
|
| 256 |
+
top: 0;
|
| 257 |
+
left: 0;
|
| 258 |
+
width: 100%;
|
| 259 |
+
height: 100%;
|
| 260 |
+
background: rgba(220, 38, 38, 0.9);
|
| 261 |
+
display: none;
|
| 262 |
+
justify-content: center;
|
| 263 |
+
align-items: center;
|
| 264 |
+
z-index: 10000;
|
| 265 |
+
color: white;
|
| 266 |
+
text-align: center;
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
.translation-content {
|
| 270 |
+
background: rgba(255, 255, 255, 0.1);
|
| 271 |
+
padding: 40px;
|
| 272 |
+
border-radius: 16px;
|
| 273 |
+
backdrop-filter: blur(10px);
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
.translation-spinner {
|
| 277 |
+
width: 50px;
|
| 278 |
+
height: 50px;
|
| 279 |
+
border: 4px solid rgba(255, 255, 255, 0.3);
|
| 280 |
+
border-radius: 50%;
|
| 281 |
+
border-top-color: white;
|
| 282 |
+
animation: spin 1s ease-in-out infinite;
|
| 283 |
+
margin: 0 auto 20px;
|
| 284 |
+
}
|
| 285 |
+
|
| 286 |
+
/* Main Application (Hidden Initially) */
|
| 287 |
+
.main-app {
|
| 288 |
+
display: none;
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
.container {
|
| 292 |
+
max-width: 1000px;
|
| 293 |
+
margin: 0 auto;
|
| 294 |
+
background: var(--surface);
|
| 295 |
+
border-radius: 16px;
|
| 296 |
+
box-shadow: var(--shadow-lg);
|
| 297 |
+
overflow: hidden;
|
| 298 |
+
position: relative;
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
/* API Key Section - Static Position Top Left */
|
| 302 |
+
.api-key-section {
|
| 303 |
+
background: rgba(220, 38, 38, 0.05);
|
| 304 |
+
border: 1px solid rgba(220, 38, 38, 0.1);
|
| 305 |
+
border-radius: 8px;
|
| 306 |
+
padding: 12px;
|
| 307 |
+
margin: 15px;
|
| 308 |
+
max-width: 280px;
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
.api-key-section label {
|
| 312 |
+
font-size: 12px;
|
| 313 |
+
font-weight: 600;
|
| 314 |
+
color: var(--primary);
|
| 315 |
+
margin-bottom: 6px;
|
| 316 |
+
display: block;
|
| 317 |
+
}
|
| 318 |
+
|
| 319 |
+
.api-key-section input {
|
| 320 |
+
width: 100%;
|
| 321 |
+
padding: 8px 12px;
|
| 322 |
+
border: 1px solid var(--border);
|
| 323 |
+
border-radius: 6px;
|
| 324 |
+
font-size: 14px;
|
| 325 |
+
background: var(--surface);
|
| 326 |
+
transition: all 0.2s ease;
|
| 327 |
+
font-family: 'Courier New', monospace;
|
| 328 |
+
}
|
| 329 |
+
|
| 330 |
+
.api-key-section input:focus {
|
| 331 |
+
outline: none;
|
| 332 |
+
border-color: var(--primary);
|
| 333 |
+
box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1);
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
/* Language Switcher in Main App */
|
| 337 |
+
.language-switcher {
|
| 338 |
+
position: absolute;
|
| 339 |
+
top: 15px;
|
| 340 |
+
right: 15px;
|
| 341 |
+
display: flex;
|
| 342 |
+
gap: 10px;
|
| 343 |
+
align-items: center;
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
[dir="rtl"] .language-switcher {
|
| 347 |
+
right: auto;
|
| 348 |
+
left: 15px;
|
| 349 |
+
}
|
| 350 |
+
|
| 351 |
+
.language-switch-btn {
|
| 352 |
+
background: rgba(220, 38, 38, 0.05);
|
| 353 |
+
border: 1px solid rgba(220, 38, 38, 0.1);
|
| 354 |
+
border-radius: 8px;
|
| 355 |
+
padding: 8px 12px;
|
| 356 |
+
font-size: 12px;
|
| 357 |
+
cursor: pointer;
|
| 358 |
+
transition: all 0.2s ease;
|
| 359 |
+
color: var(--primary);
|
| 360 |
+
font-weight: 500;
|
| 361 |
+
}
|
| 362 |
+
|
| 363 |
+
.language-switch-btn:hover {
|
| 364 |
+
background: rgba(220, 38, 38, 0.1);
|
| 365 |
+
}
|
| 366 |
+
|
| 367 |
+
.mini-clear-cache {
|
| 368 |
+
background: rgba(245, 158, 11, 0.1);
|
| 369 |
+
border: 1px solid rgba(245, 158, 11, 0.2);
|
| 370 |
+
color: var(--warning);
|
| 371 |
+
padding: 6px 10px;
|
| 372 |
+
border-radius: 6px;
|
| 373 |
+
font-size: 11px;
|
| 374 |
+
cursor: pointer;
|
| 375 |
+
transition: all 0.2s ease;
|
| 376 |
+
font-weight: 500;
|
| 377 |
+
}
|
| 378 |
+
|
| 379 |
+
.mini-clear-cache:hover {
|
| 380 |
+
background: rgba(245, 158, 11, 0.2);
|
| 381 |
+
}
|
| 382 |
+
|
| 383 |
+
/* Main Content */
|
| 384 |
+
.main-content {
|
| 385 |
+
padding: 20px 30px 30px;
|
| 386 |
+
}
|
| 387 |
+
|
| 388 |
+
/* Header */
|
| 389 |
+
.header {
|
| 390 |
+
text-align: center;
|
| 391 |
+
margin-bottom: 25px;
|
| 392 |
+
padding-bottom: 20px;
|
| 393 |
+
border-bottom: 2px solid var(--border);
|
| 394 |
+
}
|
| 395 |
+
|
| 396 |
+
.header h1 {
|
| 397 |
+
font-size: 2.5rem;
|
| 398 |
+
font-weight: 800;
|
| 399 |
+
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
|
| 400 |
+
-webkit-background-clip: text;
|
| 401 |
+
-webkit-text-fill-color: transparent;
|
| 402 |
+
background-clip: text;
|
| 403 |
+
margin-bottom: 8px;
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
.header .subtitle {
|
| 407 |
+
font-size: 1.1rem;
|
| 408 |
+
color: var(--text-secondary);
|
| 409 |
+
font-weight: 500;
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
.header .description {
|
| 413 |
+
font-size: 1rem;
|
| 414 |
+
color: var(--text-secondary);
|
| 415 |
+
margin-top: 12px;
|
| 416 |
+
max-width: 600px;
|
| 417 |
+
margin-left: auto;
|
| 418 |
+
margin-right: auto;
|
| 419 |
+
}
|
| 420 |
+
|
| 421 |
+
/* Porter's Five Forces Overview */
|
| 422 |
+
.forces-overview {
|
| 423 |
+
display: grid;
|
| 424 |
+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
| 425 |
+
gap: 15px;
|
| 426 |
+
margin-bottom: 25px;
|
| 427 |
+
}
|
| 428 |
+
|
| 429 |
+
.force-card {
|
| 430 |
+
background: rgba(220, 38, 38, 0.05);
|
| 431 |
+
border: 1px solid rgba(220, 38, 38, 0.1);
|
| 432 |
+
border-radius: 8px;
|
| 433 |
+
padding: 15px;
|
| 434 |
+
text-align: center;
|
| 435 |
+
position: relative;
|
| 436 |
+
}
|
| 437 |
+
|
| 438 |
+
.force-card.new-entrants {
|
| 439 |
+
background: rgba(239, 68, 68, 0.05);
|
| 440 |
+
border-color: rgba(239, 68, 68, 0.1);
|
| 441 |
+
}
|
| 442 |
+
|
| 443 |
+
.force-card.suppliers {
|
| 444 |
+
background: rgba(245, 158, 11, 0.05);
|
| 445 |
+
border-color: rgba(245, 158, 11, 0.1);
|
| 446 |
+
}
|
| 447 |
+
|
| 448 |
+
.force-card.buyers {
|
| 449 |
+
background: rgba(16, 185, 129, 0.05);
|
| 450 |
+
border-color: rgba(16, 185, 129, 0.1);
|
| 451 |
+
}
|
| 452 |
+
|
| 453 |
+
.force-card.substitutes {
|
| 454 |
+
background: rgba(139, 92, 246, 0.05);
|
| 455 |
+
border-color: rgba(139, 92, 246, 0.1);
|
| 456 |
+
}
|
| 457 |
+
|
| 458 |
+
.force-card.rivalry {
|
| 459 |
+
background: rgba(220, 38, 38, 0.05);
|
| 460 |
+
border-color: rgba(220, 38, 38, 0.1);
|
| 461 |
+
}
|
| 462 |
+
|
| 463 |
+
.force-card h4 {
|
| 464 |
+
color: var(--primary);
|
| 465 |
+
font-size: 0.9rem;
|
| 466 |
+
font-weight: 600;
|
| 467 |
+
margin-bottom: 6px;
|
| 468 |
+
}
|
| 469 |
+
|
| 470 |
+
.force-card.new-entrants h4 { color: #ef4444; }
|
| 471 |
+
.force-card.suppliers h4 { color: #f59e0b; }
|
| 472 |
+
.force-card.buyers h4 { color: #10b981; }
|
| 473 |
+
.force-card.substitutes h4 { color: #8b5cf6; }
|
| 474 |
+
.force-card.rivalry h4 { color: #dc2626; }
|
| 475 |
+
|
| 476 |
+
.force-card p {
|
| 477 |
+
font-size: 0.8rem;
|
| 478 |
+
color: var(--text-secondary);
|
| 479 |
+
}
|
| 480 |
+
|
| 481 |
+
/* Input Section */
|
| 482 |
+
.input-section {
|
| 483 |
+
background: var(--surface);
|
| 484 |
+
border: 1px solid var(--border);
|
| 485 |
+
border-radius: 12px;
|
| 486 |
+
padding: 20px;
|
| 487 |
+
margin-bottom: 25px;
|
| 488 |
+
transition: all 0.3s ease;
|
| 489 |
+
box-shadow: var(--shadow);
|
| 490 |
+
}
|
| 491 |
+
|
| 492 |
+
.input-section:hover {
|
| 493 |
+
border-color: var(--primary);
|
| 494 |
+
box-shadow: 0 8px 25px -8px rgba(220, 38, 38, 0.3);
|
| 495 |
+
}
|
| 496 |
+
|
| 497 |
+
.input-section h3 {
|
| 498 |
+
font-size: 1.1rem;
|
| 499 |
+
font-weight: 700;
|
| 500 |
+
color: var(--primary);
|
| 501 |
+
margin-bottom: 8px;
|
| 502 |
+
display: flex;
|
| 503 |
+
align-items: center;
|
| 504 |
+
gap: 8px;
|
| 505 |
+
}
|
| 506 |
+
|
| 507 |
+
.input-section .description {
|
| 508 |
+
font-size: 0.9rem;
|
| 509 |
+
color: var(--text-secondary);
|
| 510 |
+
margin-bottom: 12px;
|
| 511 |
+
}
|
| 512 |
+
|
| 513 |
+
/* Form Elements */
|
| 514 |
+
label {
|
| 515 |
+
display: block;
|
| 516 |
+
margin-bottom: 6px;
|
| 517 |
+
font-weight: 600;
|
| 518 |
+
color: var(--text);
|
| 519 |
+
font-size: 0.95rem;
|
| 520 |
+
}
|
| 521 |
+
|
| 522 |
+
textarea {
|
| 523 |
+
width: 100%;
|
| 524 |
+
padding: 12px 16px;
|
| 525 |
+
border: 2px solid var(--border);
|
| 526 |
+
border-radius: 8px;
|
| 527 |
+
font-size: 1rem;
|
| 528 |
+
font-family: inherit;
|
| 529 |
+
background: var(--surface);
|
| 530 |
+
transition: all 0.2s ease;
|
| 531 |
+
resize: vertical;
|
| 532 |
+
min-height: 150px;
|
| 533 |
+
}
|
| 534 |
+
|
| 535 |
+
textarea:focus {
|
| 536 |
+
outline: none;
|
| 537 |
+
border-color: var(--primary);
|
| 538 |
+
box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1);
|
| 539 |
+
}
|
| 540 |
+
|
| 541 |
+
/* Character Counter */
|
| 542 |
+
.char-counter {
|
| 543 |
+
font-size: 0.8rem;
|
| 544 |
+
color: var(--text-secondary);
|
| 545 |
+
text-align: right;
|
| 546 |
+
margin-top: 4px;
|
| 547 |
+
}
|
| 548 |
+
|
| 549 |
+
[dir="rtl"] .char-counter {
|
| 550 |
+
text-align: left;
|
| 551 |
+
}
|
| 552 |
+
|
| 553 |
+
/* Generate Button */
|
| 554 |
+
.generate-btn {
|
| 555 |
+
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
|
| 556 |
+
color: white;
|
| 557 |
+
padding: 16px 32px;
|
| 558 |
+
border: none;
|
| 559 |
+
border-radius: 12px;
|
| 560 |
+
font-size: 1.1rem;
|
| 561 |
+
font-weight: 700;
|
| 562 |
+
cursor: pointer;
|
| 563 |
+
transition: all 0.3s ease;
|
| 564 |
+
display: block;
|
| 565 |
+
margin: 25px auto;
|
| 566 |
+
min-width: 280px;
|
| 567 |
+
position: relative;
|
| 568 |
+
overflow: hidden;
|
| 569 |
+
}
|
| 570 |
+
|
| 571 |
+
.generate-btn:hover {
|
| 572 |
+
transform: translateY(-2px);
|
| 573 |
+
box-shadow: 0 12px 24px -8px rgba(220, 38, 38, 0.4);
|
| 574 |
+
}
|
| 575 |
+
|
| 576 |
+
.generate-btn:active {
|
| 577 |
+
transform: translateY(0);
|
| 578 |
+
}
|
| 579 |
+
|
| 580 |
+
.generate-btn:disabled {
|
| 581 |
+
opacity: 0.7;
|
| 582 |
+
cursor: not-allowed;
|
| 583 |
+
transform: none;
|
| 584 |
+
}
|
| 585 |
+
|
| 586 |
+
/* Loading Spinner */
|
| 587 |
+
.spinner {
|
| 588 |
+
display: none;
|
| 589 |
+
width: 20px;
|
| 590 |
+
height: 20px;
|
| 591 |
+
border: 2px solid rgba(255, 255, 255, 0.3);
|
| 592 |
+
border-radius: 50%;
|
| 593 |
+
border-top-color: white;
|
| 594 |
+
animation: spin 1s ease-in-out infinite;
|
| 595 |
+
margin-right: 8px;
|
| 596 |
+
}
|
| 597 |
+
|
| 598 |
+
[dir="rtl"] .spinner {
|
| 599 |
+
margin-right: 0;
|
| 600 |
+
margin-left: 8px;
|
| 601 |
+
}
|
| 602 |
+
|
| 603 |
+
@keyframes spin {
|
| 604 |
+
to { transform: rotate(360deg); }
|
| 605 |
+
}
|
| 606 |
+
|
| 607 |
+
/* Output Section */
|
| 608 |
+
.output-section {
|
| 609 |
+
margin-top: 30px;
|
| 610 |
+
}
|
| 611 |
+
|
| 612 |
+
.output-section h2 {
|
| 613 |
+
font-size: 1.5rem;
|
| 614 |
+
font-weight: 700;
|
| 615 |
+
color: var(--primary);
|
| 616 |
+
margin-bottom: 15px;
|
| 617 |
+
display: flex;
|
| 618 |
+
align-items: center;
|
| 619 |
+
gap: 8px;
|
| 620 |
+
}
|
| 621 |
+
|
| 622 |
+
.output-area {
|
| 623 |
+
background: var(--surface);
|
| 624 |
+
border: 2px solid var(--border);
|
| 625 |
+
border-radius: 12px;
|
| 626 |
+
padding: 20px;
|
| 627 |
+
min-height: 300px;
|
| 628 |
+
transition: all 0.3s ease;
|
| 629 |
+
position: relative;
|
| 630 |
+
overflow-x: auto;
|
| 631 |
+
}
|
| 632 |
+
|
| 633 |
+
.output-area:empty::before {
|
| 634 |
+
content: "Your comprehensive Porter's Five Forces analysis will appear here...";
|
| 635 |
+
color: var(--text-secondary);
|
| 636 |
+
font-style: italic;
|
| 637 |
+
}
|
| 638 |
+
|
| 639 |
+
/* Enhanced output styling */
|
| 640 |
+
.output-area h3 {
|
| 641 |
+
color: var(--primary);
|
| 642 |
+
border-bottom: 2px solid var(--primary);
|
| 643 |
+
padding-bottom: 8px;
|
| 644 |
+
margin: 20px 0 15px 0;
|
| 645 |
+
font-size: 1.2rem;
|
| 646 |
+
}
|
| 647 |
+
|
| 648 |
+
.output-area h4 {
|
| 649 |
+
color: var(--secondary);
|
| 650 |
+
margin: 15px 0 10px 0;
|
| 651 |
+
font-size: 1.1rem;
|
| 652 |
+
}
|
| 653 |
+
|
| 654 |
+
.output-area ul {
|
| 655 |
+
margin: 10px 0 15px 20px;
|
| 656 |
+
line-height: 1.7;
|
| 657 |
+
}
|
| 658 |
+
|
| 659 |
+
.output-area li {
|
| 660 |
+
margin-bottom: 5px;
|
| 661 |
+
}
|
| 662 |
+
|
| 663 |
+
.output-area p {
|
| 664 |
+
margin: 12px 0;
|
| 665 |
+
line-height: 1.7;
|
| 666 |
+
}
|
| 667 |
+
|
| 668 |
+
.output-area strong {
|
| 669 |
+
color: var(--primary);
|
| 670 |
+
}
|
| 671 |
+
|
| 672 |
+
/* Error Messages */
|
| 673 |
+
.error-message {
|
| 674 |
+
background: rgba(239, 68, 68, 0.1);
|
| 675 |
+
border: 1px solid rgba(239, 68, 68, 0.2);
|
| 676 |
+
color: var(--error);
|
| 677 |
+
padding: 12px 16px;
|
| 678 |
+
border-radius: 8px;
|
| 679 |
+
margin: 10px 0;
|
| 680 |
+
font-size: 0.9rem;
|
| 681 |
+
display: none;
|
| 682 |
+
}
|
| 683 |
+
|
| 684 |
+
/* Footer */
|
| 685 |
+
.footer {
|
| 686 |
+
text-align: center;
|
| 687 |
+
padding: 20px;
|
| 688 |
+
background: rgba(220, 38, 38, 0.05);
|
| 689 |
+
border-top: 1px solid var(--border);
|
| 690 |
+
color: var(--text-secondary);
|
| 691 |
+
font-size: 0.9rem;
|
| 692 |
+
}
|
| 693 |
+
|
| 694 |
+
/* Responsive Design */
|
| 695 |
+
@media (max-width: 768px) {
|
| 696 |
+
body {
|
| 697 |
+
padding: 10px;
|
| 698 |
+
}
|
| 699 |
+
|
| 700 |
+
.language-landing {
|
| 701 |
+
margin: 20px auto;
|
| 702 |
+
padding: 30px 20px;
|
| 703 |
+
}
|
| 704 |
+
|
| 705 |
+
.api-key-section {
|
| 706 |
+
margin: 10px;
|
| 707 |
+
max-width: none;
|
| 708 |
+
}
|
| 709 |
+
|
| 710 |
+
.language-switcher {
|
| 711 |
+
position: relative;
|
| 712 |
+
top: auto;
|
| 713 |
+
right: auto;
|
| 714 |
+
margin-bottom: 15px;
|
| 715 |
+
justify-content: center;
|
| 716 |
+
}
|
| 717 |
+
|
| 718 |
+
.main-content {
|
| 719 |
+
padding: 15px 20px 20px;
|
| 720 |
+
}
|
| 721 |
+
|
| 722 |
+
.header h1 {
|
| 723 |
+
font-size: 2rem;
|
| 724 |
+
}
|
| 725 |
+
|
| 726 |
+
.input-section {
|
| 727 |
+
padding: 15px;
|
| 728 |
+
}
|
| 729 |
+
|
| 730 |
+
.forces-overview {
|
| 731 |
+
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
| 732 |
+
}
|
| 733 |
+
|
| 734 |
+
.generate-btn {
|
| 735 |
+
width: 100%;
|
| 736 |
+
margin: 20px 0;
|
| 737 |
+
}
|
| 738 |
+
|
| 739 |
+
.output-area {
|
| 740 |
+
padding: 15px;
|
| 741 |
+
}
|
| 742 |
+
}
|
| 743 |
+
|
| 744 |
+
@media (max-width: 480px) {
|
| 745 |
+
.language-landing h1 {
|
| 746 |
+
font-size: 2rem;
|
| 747 |
+
}
|
| 748 |
+
|
| 749 |
+
.header h1 {
|
| 750 |
+
font-size: 1.8rem;
|
| 751 |
+
}
|
| 752 |
+
|
| 753 |
+
.input-section {
|
| 754 |
+
padding: 12px;
|
| 755 |
+
}
|
| 756 |
+
|
| 757 |
+
.forces-overview {
|
| 758 |
+
grid-template-columns: 1fr 1fr;
|
| 759 |
+
}
|
| 760 |
+
}
|
| 761 |
+
|
| 762 |
+
/* Dark mode support */
|
| 763 |
+
@media (prefers-color-scheme: dark) {
|
| 764 |
+
:root {
|
| 765 |
+
--background: #0f172a;
|
| 766 |
+
--surface: #1e293b;
|
| 767 |
+
--text: #f1f5f9;
|
| 768 |
+
--text-secondary: #94a3b8;
|
| 769 |
+
--border: #334155;
|
| 770 |
+
}
|
| 771 |
+
|
| 772 |
+
body {
|
| 773 |
+
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
|
| 774 |
+
}
|
| 775 |
+
}
|
| 776 |
+
</style>
|
| 777 |
+
</head>
|
| 778 |
+
<body>
|
| 779 |
+
<!-- Translation Loading Overlay -->
|
| 780 |
+
<div class="translation-overlay" id="translationOverlay">
|
| 781 |
+
<div class="translation-content">
|
| 782 |
+
<div class="translation-spinner"></div>
|
| 783 |
+
<h2 id="translationTitle">Translating Interface...</h2>
|
| 784 |
+
<p id="translationMessage">Please wait while we translate the interface to your selected language.</p>
|
| 785 |
+
</div>
|
| 786 |
+
</div>
|
| 787 |
+
|
| 788 |
+
<!-- Language Selection Landing Page -->
|
| 789 |
+
<div class="language-landing" id="languageLanding">
|
| 790 |
+
<h1 data-translate="app_title">CompetitiveStrategy Pro</h1>
|
| 791 |
+
<p data-translate="welcome_message">Welcome! Please select your preferred language and enter your API key to get started.</p>
|
| 792 |
+
|
| 793 |
+
<!-- Cache Status Indicator -->
|
| 794 |
+
<div class="cache-status" id="cacheStatus">
|
| 795 |
+
💾 Translations cached - instant loading!
|
| 796 |
+
</div>
|
| 797 |
+
|
| 798 |
+
<!-- Cache Management Section -->
|
| 799 |
+
<div class="cache-management" id="cacheManagement">
|
| 800 |
+
<h3 data-translate="cache_management_title">🗂️ Translation Cache Management</h3>
|
| 801 |
+
<div class="cache-status-display" id="cacheStatusDisplay">
|
| 802 |
+
<span data-translate="cache_status_checking">Checking cache status...</span>
|
| 803 |
+
</div>
|
| 804 |
+
<button class="clear-cache-btn" id="clearCacheBtn" data-translate="clear_cache_button">
|
| 805 |
+
🗑️ Clear All Cached Translations
|
| 806 |
+
</button>
|
| 807 |
+
</div>
|
| 808 |
+
|
| 809 |
+
<div class="language-selector">
|
| 810 |
+
<label for="languageSelect" data-translate="select_language">🌐 Select Language</label>
|
| 811 |
+
<select id="languageSelect">
|
| 812 |
+
<option value="en">🇺🇸 English</option>
|
| 813 |
+
<option value="es">🇪🇸 Español (Spanish)</option>
|
| 814 |
+
<option value="fr">🇫🇷 Français (French)</option>
|
| 815 |
+
<option value="de">🇩🇪 Deutsch (German)</option>
|
| 816 |
+
<option value="zh">🇨🇳 中文 (Chinese)</option>
|
| 817 |
+
<option value="ja">🇯🇵 日本語 (Japanese)</option>
|
| 818 |
+
<option value="ko">🇰🇷 한국어 (Korean)</option>
|
| 819 |
+
<option value="pt">🇵🇹 Português (Portuguese)</option>
|
| 820 |
+
<option value="it">🇮🇹 Italiano (Italian)</option>
|
| 821 |
+
<option value="ar">🇸🇦 العربية (Arabic)</option>
|
| 822 |
+
<option value="ru">🇷🇺 Русский (Russian)</option>
|
| 823 |
+
<option value="hi">🇮🇳 हिन्दी (Hindi)</option>
|
| 824 |
+
<option value="bn">🇧🇩 বাংলা (Bengali)</option>
|
| 825 |
+
<option value="ur">🇵🇰 اردو (Urdu)</option>
|
| 826 |
+
<option value="tr">🇹🇷 Türkçe (Turkish)</option>
|
| 827 |
+
<option value="pl">🇵🇱 Polski (Polish)</option>
|
| 828 |
+
<option value="nl">🇳🇱 Nederlands (Dutch)</option>
|
| 829 |
+
<option value="sv">🇸🇪 Svenska (Swedish)</option>
|
| 830 |
+
<option value="da">🇩🇰 Dansk (Danish)</option>
|
| 831 |
+
<option value="no">🇳🇴 Norsk (Norwegian)</option>
|
| 832 |
+
<option value="fi">🇫🇮 Suomi (Finnish)</option>
|
| 833 |
+
<option value="is">🇮🇸 Íslenska (Icelandic)</option>
|
| 834 |
+
<option value="cs">🇨🇿 Čeština (Czech)</option>
|
| 835 |
+
<option value="sk">🇸🇰 Slovenčina (Slovak)</option>
|
| 836 |
+
<option value="hu">🇭🇺 Magyar (Hungarian)</option>
|
| 837 |
+
<option value="ro">🇷🇴 Română (Romanian)</option>
|
| 838 |
+
<option value="bg">🇧🇬 Български (Bulgarian)</option>
|
| 839 |
+
<option value="hr">🇭🇷 Hrvatski (Croatian)</option>
|
| 840 |
+
<option value="sr">🇷🇸 Српски (Serbian)</option>
|
| 841 |
+
<option value="sl">🇸🇮 Slovenščina (Slovenian)</option>
|
| 842 |
+
<option value="mk">🇲🇰 Македонски (Macedonian)</option>
|
| 843 |
+
<option value="sq">🇦🇱 Shqip (Albanian)</option>
|
| 844 |
+
<option value="lv">🇱🇻 Latviešu (Latvian)</option>
|
| 845 |
+
<option value="lt">🇱🇹 Lietuvių (Lithuanian)</option>
|
| 846 |
+
<option value="et">🇪🇪 Eesti (Estonian)</option>
|
| 847 |
+
<option value="mt">🇲🇹 Malti (Maltese)</option>
|
| 848 |
+
<option value="ga">🇮🇪 Gaeilge (Irish)</option>
|
| 849 |
+
<option value="cy">🏴 Cymraeg (Welsh)</option>
|
| 850 |
+
<option value="eu">🏴 Euskera (Basque)</option>
|
| 851 |
+
<option value="ca">🏴 Català (Catalan)</option>
|
| 852 |
+
<option value="gl">🏴 Galego (Galician)</option>
|
| 853 |
+
<option value="el">🇬🇷 Ελληνικά (Greek)</option>
|
| 854 |
+
<option value="he">🇮🇱 עברית (Hebrew)</option>
|
| 855 |
+
<option value="fa">🇮🇷 فارسی (Persian)</option>
|
| 856 |
+
<option value="ps">🇦🇫 پښتو (Pashto)</option>
|
| 857 |
+
<option value="ku">🏴 کوردی (Kurdish)</option>
|
| 858 |
+
<option value="az">🇦🇿 Azərbaycan (Azerbaijani)</option>
|
| 859 |
+
<option value="kk">🇰🇿 Қазақша (Kazakh)</option>
|
| 860 |
+
<option value="ky">🇰🇬 Кыргызча (Kyrgyz)</option>
|
| 861 |
+
<option value="uz">🇺🇿 O'zbek (Uzbek)</option>
|
| 862 |
+
<option value="tk">🇹🇲 Türkmen (Turkmen)</option>
|
| 863 |
+
<option value="tg">🇹🇯 Тоҷикӣ (Tajik)</option>
|
| 864 |
+
<option value="mn">🇲🇳 Монгол (Mongolian)</option>
|
| 865 |
+
<option value="ka">🇬🇪 ქართული (Georgian)</option>
|
| 866 |
+
<option value="hy">🇦🇲 Հայերեն (Armenian)</option>
|
| 867 |
+
<option value="th">🇹🇭 ไทย (Thai)</option>
|
| 868 |
+
<option value="vi">🇻🇳 Tiếng Việt (Vietnamese)</option>
|
| 869 |
+
<option value="lo">🇱🇦 ລາວ (Lao)</option>
|
| 870 |
+
<option value="km">🇰🇭 ខ្មែរ (Khmer)</option>
|
| 871 |
+
<option value="my">🇲🇲 မြန်မာ (Myanmar)</option>
|
| 872 |
+
<option value="si">🇱🇰 සිංහල (Sinhala)</option>
|
| 873 |
+
<option value="ta">🇱🇰 தமிழ் (Tamil)</option>
|
| 874 |
+
<option value="te">🇮🇳 తెలుగు (Telugu)</option>
|
| 875 |
+
<option value="kn">🇮🇳 ಕನ್ನಡ (Kannada)</option>
|
| 876 |
+
<option value="ml">🇮🇳 മലയാളം (Malayalam)</option>
|
| 877 |
+
<option value="gu">🇮🇳 ગુજરાતી (Gujarati)</option>
|
| 878 |
+
<option value="pa">🇮🇳 ਪੰਜਾਬੀ (Punjabi)</option>
|
| 879 |
+
<option value="or">🇮🇳 ଓଡ଼ିଆ (Odia)</option>
|
| 880 |
+
<option value="as">🇮🇳 অসমীয়া (Assamese)</option>
|
| 881 |
+
<option value="ne">🇳🇵 नेपाली (Nepali)</option>
|
| 882 |
+
<option value="dz">🇧🇹 རྫོང་ཁ (Dzongkha)</option>
|
| 883 |
+
<option value="bo">🏔️ བོད་ཡིག (Tibetan)</option>
|
| 884 |
+
<option value="id">🇮🇩 Bahasa Indonesia</option>
|
| 885 |
+
<option value="ms">🇲🇾 Bahasa Melayu (Malay)</option>
|
| 886 |
+
<option value="tl">🇵🇭 Filipino (Tagalog)</option>
|
| 887 |
+
<option value="ceb">🇵🇭 Cebuano</option>
|
| 888 |
+
<option value="haw">🏝️ ʻŌlelo Hawaiʻi (Hawaiian)</option>
|
| 889 |
+
<option value="mi">🇳🇿 Te Reo Māori (Maori)</option>
|
| 890 |
+
<option value="sm">🇼🇸 Gagana Samoa (Samoan)</option>
|
| 891 |
+
<option value="to">🇹🇴 Lea Fakatonga (Tongan)</option>
|
| 892 |
+
<option value="fj">🇫🇯 Na Vosa Vakaviti (Fijian)</option>
|
| 893 |
+
<option value="mg">🇲🇬 Malagasy</option>
|
| 894 |
+
<option value="sw">🇰🇪 Kiswahili (Swahili)</option>
|
| 895 |
+
<option value="zu">🇿🇦 isiZulu (Zulu)</option>
|
| 896 |
+
<option value="xh">🇿🇦 isiXhosa (Xhosa)</option>
|
| 897 |
+
<option value="af">🇿🇦 Afrikaans</option>
|
| 898 |
+
<option value="st">🇱🇸 Sesotho (Southern Sotho)</option>
|
| 899 |
+
<option value="tn">🇧🇼 Setswana (Tswana)</option>
|
| 900 |
+
<option value="ss">🇸🇿 siSwati (Swati)</option>
|
| 901 |
+
<option value="ve">🇿🇦 Tshivenḓa (Venda)</option>
|
| 902 |
+
<option value="ts">🇿🇦 Xitsonga (Tsonga)</option>
|
| 903 |
+
<option value="nr">🇿🇦 isiNdebele (Southern Ndebele)</option>
|
| 904 |
+
<option value="am">🇪🇹 አማርኛ (Amharic)</option>
|
| 905 |
+
<option value="ti">🇪🇷 ትግርኛ (Tigrinya)</option>
|
| 906 |
+
<option value="om">🇪🇹 Afaan Oromoo (Oromo)</option>
|
| 907 |
+
<option value="so">🇸🇴 Soomaali (Somali)</option>
|
| 908 |
+
<option value="ha">🇳🇬 Hausa</option>
|
| 909 |
+
<option value="yo">🇳🇬 Yorùbá (Yoruba)</option>
|
| 910 |
+
<option value="ig">🇳🇬 Igbo</option>
|
| 911 |
+
<option value="ff">🇸🇳 Fulfulde (Fulani)</option>
|
| 912 |
+
<option value="wo">🇸🇳 Wolof</option>
|
| 913 |
+
<option value="bm">🇲🇱 Bamanankan (Bambara)</option>
|
| 914 |
+
<option value="rn">🇧🇮 Kirundi (Rundi)</option>
|
| 915 |
+
<option value="rw">🇷🇼 Kinyarwanda (Rwanda)</option>
|
| 916 |
+
<option value="lg">🇺🇬 Luganda</option>
|
| 917 |
+
<option value="ny">🇲🇼 Chichewa (Nyanja)</option>
|
| 918 |
+
<option value="sn">🇿🇼 chiShona (Shona)</option>
|
| 919 |
+
<option value="nd">🇿🇼 isiNdebele (Northern Ndebele)</option>
|
| 920 |
+
</select>
|
| 921 |
+
</div>
|
| 922 |
+
|
| 923 |
+
<div class="api-key-landing">
|
| 924 |
+
<label for="apiKeyLanding" data-translate="api_key_label">🔑 OpenAI API Key</label>
|
| 925 |
+
<input type="password" id="apiKeyLanding" placeholder="Enter your OpenAI API key" data-translate-placeholder="api_key_placeholder">
|
| 926 |
+
</div>
|
| 927 |
+
|
| 928 |
+
<button class="start-btn" id="startBtn" data-translate="start_button">🚀 Start Strategic Analysis</button>
|
| 929 |
+
</div>
|
| 930 |
+
|
| 931 |
+
<!-- Main Application -->
|
| 932 |
+
<div class="main-app" id="mainApp">
|
| 933 |
+
<div class="container">
|
| 934 |
+
<!-- Language Switcher -->
|
| 935 |
+
<div class="language-switcher" id="languageSwitcher">
|
| 936 |
+
<div class="language-switch-btn" onclick="showLanguageLanding()">
|
| 937 |
+
<span data-translate="change_language">🌐 Change Language</span>
|
| 938 |
+
</div>
|
| 939 |
+
<div class="mini-clear-cache" onclick="clearAllTranslationCache()" title="Clear translation cache">
|
| 940 |
+
<span data-translate="clear_cache_mini">🗑️ Clear Cache</span>
|
| 941 |
+
</div>
|
| 942 |
+
</div>
|
| 943 |
+
|
| 944 |
+
<!-- API Key Section - Static Position Top Left -->
|
| 945 |
+
<div class="api-key-section">
|
| 946 |
+
<label for="apiKey" data-translate="api_key_short">🔑 API Key</label>
|
| 947 |
+
<input type="password" id="apiKey" data-translate-placeholder="api_key_placeholder" autocomplete="off">
|
| 948 |
+
</div>
|
| 949 |
+
|
| 950 |
+
<div class="main-content">
|
| 951 |
+
<!-- Header -->
|
| 952 |
+
<div class="header">
|
| 953 |
+
<h1 data-translate="app_title">CompetitiveStrategy Pro</h1>
|
| 954 |
+
<p class="subtitle" data-translate="app_subtitle">Advanced Porter's Five Forces Analysis & Strategic Planning</p>
|
| 955 |
+
<p class="description" data-translate="app_description">Generate comprehensive Porter's Five Forces analyses tailored to your specific industry and competitive landscape</p>
|
| 956 |
+
</div>
|
| 957 |
+
|
| 958 |
+
<!-- Porter's Five Forces Overview -->
|
| 959 |
+
<div class="forces-overview">
|
| 960 |
+
<div class="force-card new-entrants">
|
| 961 |
+
<h4 data-translate="force_new_entrants">🚪 New Entrants</h4>
|
| 962 |
+
<p data-translate="force_new_entrants_desc">Threat of Market Entry</p>
|
| 963 |
+
</div>
|
| 964 |
+
<div class="force-card suppliers">
|
| 965 |
+
<h4 data-translate="force_suppliers">🏭 Suppliers</h4>
|
| 966 |
+
<p data-translate="force_suppliers_desc">Bargaining Power</p>
|
| 967 |
+
</div>
|
| 968 |
+
<div class="force-card buyers">
|
| 969 |
+
<h4 data-translate="force_buyers">👥 Buyers</h4>
|
| 970 |
+
<p data-translate="force_buyers_desc">Customer Influence</p>
|
| 971 |
+
</div>
|
| 972 |
+
<div class="force-card substitutes">
|
| 973 |
+
<h4 data-translate="force_substitutes">🔄 Substitutes</h4>
|
| 974 |
+
<p data-translate="force_substitutes_desc">Alternative Solutions</p>
|
| 975 |
+
</div>
|
| 976 |
+
<div class="force-card rivalry">
|
| 977 |
+
<h4 data-translate="force_rivalry">⚔️ Rivalry</h4>
|
| 978 |
+
<p data-translate="force_rivalry_desc">Competitive Intensity</p>
|
| 979 |
+
</div>
|
| 980 |
+
</div>
|
| 981 |
+
|
| 982 |
+
<!-- Input Section -->
|
| 983 |
+
<div class="input-section">
|
| 984 |
+
<h3 data-translate="input_title">🏢 Industry & Business Context</h3>
|
| 985 |
+
<p class="description" data-translate="input_description">Describe your industry, business, market, or competitive scenario where you need to apply Porter's Five Forces analysis</p>
|
| 986 |
+
<textarea id="textInput" data-translate-placeholder="input_placeholder" required></textarea>
|
| 987 |
+
<div class="char-counter" id="charCounter">0 <span data-translate="characters">characters</span></div>
|
| 988 |
+
</div>
|
| 989 |
+
|
| 990 |
+
<!-- Error Message -->
|
| 991 |
+
<div class="error-message" id="errorMessage"></div>
|
| 992 |
+
|
| 993 |
+
<!-- Generate Button -->
|
| 994 |
+
<button class="generate-btn" id="generatePortersBtn">
|
| 995 |
+
<span class="spinner" id="spinner"></span>
|
| 996 |
+
<span id="buttonText" data-translate="generate_button">⚔️ Generate Five Forces Analysis</span>
|
| 997 |
+
</button>
|
| 998 |
+
|
| 999 |
+
<!-- Output Section -->
|
| 1000 |
+
<div class="output-section">
|
| 1001 |
+
<h2 data-translate="output_title">📊 Your Porter's Five Forces Analysis</h2>
|
| 1002 |
+
<div class="output-area" id="apiOutput"></div>
|
| 1003 |
+
</div>
|
| 1004 |
+
</div>
|
| 1005 |
+
|
| 1006 |
+
<!-- Footer -->
|
| 1007 |
+
<div class="footer">
|
| 1008 |
+
Created by Shift Mind AI Labs
|
| 1009 |
+
</div>
|
| 1010 |
+
</div>
|
| 1011 |
+
</div>
|
| 1012 |
+
|
| 1013 |
+
<script>
|
| 1014 |
+
// RTL languages list
|
| 1015 |
+
const rtlLanguages = ['ar', 'he', 'fa', 'ur', 'ps', 'ku'];
|
| 1016 |
+
|
| 1017 |
+
// Current language and API key
|
| 1018 |
+
let currentLanguage = 'en';
|
| 1019 |
+
let currentApiKey = '';
|
| 1020 |
+
|
| 1021 |
+
// Language names mapping
|
| 1022 |
+
const languageNames = {
|
| 1023 |
+
en: 'English', es: 'Spanish', fr: 'French', de: 'German', zh: 'Chinese',
|
| 1024 |
+
ja: 'Japanese', ko: 'Korean', pt: 'Portuguese', it: 'Italian', ar: 'Arabic',
|
| 1025 |
+
ru: 'Russian', hi: 'Hindi', bn: 'Bengali', ur: 'Urdu', tr: 'Turkish',
|
| 1026 |
+
pl: 'Polish', nl: 'Dutch', sv: 'Swedish', da: 'Danish', no: 'Norwegian',
|
| 1027 |
+
fi: 'Finnish', is: 'Icelandic', cs: 'Czech', sk: 'Slovak', hu: 'Hungarian',
|
| 1028 |
+
ro: 'Romanian', bg: 'Bulgarian', hr: 'Croatian', sr: 'Serbian', sl: 'Slovenian',
|
| 1029 |
+
mk: 'Macedonian', sq: 'Albanian', lv: 'Latvian', lt: 'Lithuanian', et: 'Estonian',
|
| 1030 |
+
mt: 'Maltese', ga: 'Irish', cy: 'Welsh', eu: 'Basque', ca: 'Catalan',
|
| 1031 |
+
gl: 'Galician', el: 'Greek', he: 'Hebrew', fa: 'Persian', ps: 'Pashto',
|
| 1032 |
+
ku: 'Kurdish', az: 'Azerbaijani', kk: 'Kazakh', ky: 'Kyrgyz', uz: 'Uzbek',
|
| 1033 |
+
tk: 'Turkmen', tg: 'Tajik', mn: 'Mongolian', ka: 'Georgian', hy: 'Armenian',
|
| 1034 |
+
th: 'Thai', vi: 'Vietnamese', lo: 'Lao', km: 'Khmer', my: 'Myanmar',
|
| 1035 |
+
si: 'Sinhala', ta: 'Tamil', te: 'Telugu', kn: 'Kannada', ml: 'Malayalam',
|
| 1036 |
+
gu: 'Gujarati', pa: 'Punjabi', or: 'Odia', as: 'Assamese', ne: 'Nepali',
|
| 1037 |
+
dz: 'Dzongkha', bo: 'Tibetan', id: 'Indonesian', ms: 'Malay', tl: 'Filipino',
|
| 1038 |
+
ceb: 'Cebuano', haw: 'Hawaiian', mi: 'Maori', sm: 'Samoan', to: 'Tongan',
|
| 1039 |
+
fj: 'Fijian', mg: 'Malagasy', sw: 'Swahili', zu: 'Zulu', xh: 'Xhosa',
|
| 1040 |
+
af: 'Afrikaans', st: 'Southern Sotho', tn: 'Tswana', ss: 'Swati', ve: 'Venda',
|
| 1041 |
+
ts: 'Tsonga', nr: 'Southern Ndebele', am: 'Amharic', ti: 'Tigrinya', om: 'Oromo',
|
| 1042 |
+
so: 'Somali', ha: 'Hausa', yo: 'Yoruba', ig: 'Igbo', ff: 'Fulani',
|
| 1043 |
+
wo: 'Wolof', bm: 'Bambara', rn: 'Rundi', rw: 'Rwanda', lg: 'Luganda',
|
| 1044 |
+
ny: 'Chichewa', sn: 'Shona', nd: 'Northern Ndebele'
|
| 1045 |
+
};
|
| 1046 |
+
|
| 1047 |
+
// Translation cache management
|
| 1048 |
+
const CACHE_PREFIX = 'competitivestrategy_translations_';
|
| 1049 |
+
const CACHE_VERSION = '1.0';
|
| 1050 |
+
|
| 1051 |
+
// Check if translations are cached for a language
|
| 1052 |
+
function isLanguageCached(language) {
|
| 1053 |
+
const cacheKey = CACHE_PREFIX + language;
|
| 1054 |
+
const cached = localStorage.getItem(cacheKey);
|
| 1055 |
+
return cached !== null;
|
| 1056 |
+
}
|
| 1057 |
+
|
| 1058 |
+
// Save translations to cache
|
| 1059 |
+
function saveTranslationsToCache(language, translations) {
|
| 1060 |
+
const cacheKey = CACHE_PREFIX + language;
|
| 1061 |
+
const cacheData = {
|
| 1062 |
+
version: CACHE_VERSION,
|
| 1063 |
+
timestamp: Date.now(),
|
| 1064 |
+
translations: translations
|
| 1065 |
+
};
|
| 1066 |
+
localStorage.setItem(cacheKey, JSON.stringify(cacheData));
|
| 1067 |
+
console.log(`Translations cached for ${language}`);
|
| 1068 |
+
}
|
| 1069 |
+
|
| 1070 |
+
// Load translations from cache
|
| 1071 |
+
function loadTranslationsFromCache(language) {
|
| 1072 |
+
const cacheKey = CACHE_PREFIX + language;
|
| 1073 |
+
const cached = localStorage.getItem(cacheKey);
|
| 1074 |
+
|
| 1075 |
+
if (cached) {
|
| 1076 |
+
try {
|
| 1077 |
+
const cacheData = JSON.parse(cached);
|
| 1078 |
+
if (cacheData.version === CACHE_VERSION) {
|
| 1079 |
+
console.log(`Translations loaded from cache for ${language}`);
|
| 1080 |
+
return cacheData.translations;
|
| 1081 |
+
}
|
| 1082 |
+
} catch (error) {
|
| 1083 |
+
console.error('Error parsing cached translations:', error);
|
| 1084 |
+
}
|
| 1085 |
+
}
|
| 1086 |
+
return null;
|
| 1087 |
+
}
|
| 1088 |
+
|
| 1089 |
+
// Get all cached languages
|
| 1090 |
+
function getCachedLanguages() {
|
| 1091 |
+
const cachedLanguages = [];
|
| 1092 |
+
for (let i = 0; i < localStorage.length; i++) {
|
| 1093 |
+
const key = localStorage.key(i);
|
| 1094 |
+
if (key && key.startsWith(CACHE_PREFIX)) {
|
| 1095 |
+
const language = key.replace(CACHE_PREFIX, '');
|
| 1096 |
+
cachedLanguages.push(language);
|
| 1097 |
+
}
|
| 1098 |
+
}
|
| 1099 |
+
return cachedLanguages;
|
| 1100 |
+
}
|
| 1101 |
+
|
| 1102 |
+
// Clear all translation cache
|
| 1103 |
+
function clearAllTranslationCache() {
|
| 1104 |
+
const cachedLanguages = getCachedLanguages();
|
| 1105 |
+
|
| 1106 |
+
if (cachedLanguages.length === 0) {
|
| 1107 |
+
alert('No cached translations to clear.');
|
| 1108 |
+
return;
|
| 1109 |
+
}
|
| 1110 |
+
|
| 1111 |
+
const languageList = cachedLanguages.map(lang => languageNames[lang] || lang).join(', ');
|
| 1112 |
+
const confirmMessage = `Are you sure you want to clear all cached translations?\n\nCached languages: ${languageList}\n\nThis will require re-downloading translations when switching languages.`;
|
| 1113 |
+
|
| 1114 |
+
if (confirm(confirmMessage)) {
|
| 1115 |
+
// Clear all translation caches
|
| 1116 |
+
cachedLanguages.forEach(language => {
|
| 1117 |
+
const cacheKey = CACHE_PREFIX + language;
|
| 1118 |
+
localStorage.removeItem(cacheKey);
|
| 1119 |
+
});
|
| 1120 |
+
|
| 1121 |
+
// Update cache status
|
| 1122 |
+
updateCacheStatus(currentLanguage);
|
| 1123 |
+
updateCacheStatusDisplay();
|
| 1124 |
+
|
| 1125 |
+
alert(`Cache cleared successfully!\n\n${cachedLanguages.length} language(s) removed from cache.`);
|
| 1126 |
+
|
| 1127 |
+
// Ask if user wants to reload current language translations
|
| 1128 |
+
if (currentLanguage !== 'en' && cachedLanguages.includes(currentLanguage)) {
|
| 1129 |
+
if (confirm('Would you like to reload the current language translations?')) {
|
| 1130 |
+
applyLanguage(currentLanguage);
|
| 1131 |
+
}
|
| 1132 |
+
}
|
| 1133 |
+
}
|
| 1134 |
+
}
|
| 1135 |
+
|
| 1136 |
+
// Update cache status indicator
|
| 1137 |
+
function updateCacheStatus(language) {
|
| 1138 |
+
const cacheStatus = document.getElementById('cacheStatus');
|
| 1139 |
+
const isCached = isLanguageCached(language);
|
| 1140 |
+
|
| 1141 |
+
if (language === 'en') {
|
| 1142 |
+
cacheStatus.classList.remove('cached', 'translating');
|
| 1143 |
+
return;
|
| 1144 |
+
}
|
| 1145 |
+
|
| 1146 |
+
if (isCached) {
|
| 1147 |
+
cacheStatus.textContent = '💾 Translations cached - instant loading!';
|
| 1148 |
+
cacheStatus.classList.add('cached');
|
| 1149 |
+
cacheStatus.classList.remove('translating');
|
| 1150 |
+
} else {
|
| 1151 |
+
cacheStatus.textContent = '🔄 First time translation - will be cached for future use';
|
| 1152 |
+
cacheStatus.classList.add('translating');
|
| 1153 |
+
cacheStatus.classList.remove('cached');
|
| 1154 |
+
}
|
| 1155 |
+
}
|
| 1156 |
+
|
| 1157 |
+
// Update cache status display in management section
|
| 1158 |
+
function updateCacheStatusDisplay() {
|
| 1159 |
+
const cacheStatusDisplay = document.getElementById('cacheStatusDisplay');
|
| 1160 |
+
const clearCacheBtn = document.getElementById('clearCacheBtn');
|
| 1161 |
+
const cachedLanguages = getCachedLanguages();
|
| 1162 |
+
|
| 1163 |
+
if (cachedLanguages.length === 0) {
|
| 1164 |
+
cacheStatusDisplay.textContent = '📭 No cached translations';
|
| 1165 |
+
cacheStatusDisplay.className = 'cache-status-display no-cache';
|
| 1166 |
+
clearCacheBtn.disabled = true;
|
| 1167 |
+
} else {
|
| 1168 |
+
const languageList = cachedLanguages.map(lang => languageNames[lang] || lang).join(', ');
|
| 1169 |
+
cacheStatusDisplay.textContent = `💾 ${cachedLanguages.length} language(s) cached: ${languageList}`;
|
| 1170 |
+
cacheStatusDisplay.className = 'cache-status-display';
|
| 1171 |
+
clearCacheBtn.disabled = false;
|
| 1172 |
+
}
|
| 1173 |
+
}
|
| 1174 |
+
|
| 1175 |
+
// Initialize the application
|
| 1176 |
+
function initializeApp() {
|
| 1177 |
+
// Load saved language and API key
|
| 1178 |
+
const savedLanguage = localStorage.getItem('competitivestrategy_language') || 'en';
|
| 1179 |
+
const savedApiKey = localStorage.getItem('competitive_strategy_api_key') || '';
|
| 1180 |
+
|
| 1181 |
+
currentLanguage = savedLanguage;
|
| 1182 |
+
currentApiKey = savedApiKey;
|
| 1183 |
+
|
| 1184 |
+
// Set language selector
|
| 1185 |
+
document.getElementById('languageSelect').value = currentLanguage;
|
| 1186 |
+
document.getElementById('apiKeyLanding').value = currentApiKey;
|
| 1187 |
+
|
| 1188 |
+
// Apply direction for current language
|
| 1189 |
+
applyDirection(currentLanguage);
|
| 1190 |
+
|
| 1191 |
+
// Update cache status
|
| 1192 |
+
updateCacheStatus(currentLanguage);
|
| 1193 |
+
updateCacheStatusDisplay();
|
| 1194 |
+
|
| 1195 |
+
// Show appropriate screen
|
| 1196 |
+
if (currentApiKey && currentLanguage) {
|
| 1197 |
+
showMainApp();
|
| 1198 |
+
} else {
|
| 1199 |
+
showLanguageLanding();
|
| 1200 |
+
}
|
| 1201 |
+
}
|
| 1202 |
+
|
| 1203 |
+
// Apply language direction
|
| 1204 |
+
function applyDirection(language) {
|
| 1205 |
+
currentLanguage = language;
|
| 1206 |
+
|
| 1207 |
+
// Set document language and direction
|
| 1208 |
+
document.documentElement.lang = language;
|
| 1209 |
+
document.documentElement.dir = rtlLanguages.includes(language) ? 'rtl' : 'ltr';
|
| 1210 |
+
|
| 1211 |
+
// Save language preference
|
| 1212 |
+
localStorage.setItem('competitivestrategy_language', language);
|
| 1213 |
+
|
| 1214 |
+
// Update cache status
|
| 1215 |
+
updateCacheStatus(language);
|
| 1216 |
+
}
|
| 1217 |
+
|
| 1218 |
+
// API call function for translation
|
| 1219 |
+
async function translateText(text, targetLanguage) {
|
| 1220 |
+
if (!currentApiKey) {
|
| 1221 |
+
throw new Error('API key is required for translation');
|
| 1222 |
+
}
|
| 1223 |
+
|
| 1224 |
+
const languageName = languageNames[targetLanguage] || 'English';
|
| 1225 |
+
|
| 1226 |
+
const prompt = `Translate the following text to ${languageName}. Provide ONLY the exact translation without any explanations, additional information, or formatting:
|
| 1227 |
+
|
| 1228 |
+
"${text}"`;
|
| 1229 |
+
|
| 1230 |
+
const payload = {
|
| 1231 |
+
model: "gpt-4o-mini",
|
| 1232 |
+
messages: [{ role: "user", content: prompt }],
|
| 1233 |
+
max_tokens: 500,
|
| 1234 |
+
temperature: 0.1
|
| 1235 |
+
};
|
| 1236 |
+
|
| 1237 |
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
| 1238 |
+
method: "POST",
|
| 1239 |
+
headers: {
|
| 1240 |
+
"Content-Type": "application/json",
|
| 1241 |
+
"Authorization": `Bearer ${currentApiKey}`
|
| 1242 |
+
},
|
| 1243 |
+
body: JSON.stringify(payload)
|
| 1244 |
+
});
|
| 1245 |
+
|
| 1246 |
+
if (!response.ok) {
|
| 1247 |
+
const errorData = await response.json();
|
| 1248 |
+
throw new Error(errorData.error?.message || "Translation API request failed");
|
| 1249 |
+
}
|
| 1250 |
+
|
| 1251 |
+
const data = await response.json();
|
| 1252 |
+
return data.choices[0].message.content.trim();
|
| 1253 |
+
}
|
| 1254 |
+
|
| 1255 |
+
// Apply cached translations to UI
|
| 1256 |
+
function applyCachedTranslations(translations) {
|
| 1257 |
+
// Apply text translations
|
| 1258 |
+
Object.keys(translations.texts).forEach(originalText => {
|
| 1259 |
+
const translation = translations.texts[originalText];
|
| 1260 |
+
const elements = document.querySelectorAll(`[data-translate]`);
|
| 1261 |
+
|
| 1262 |
+
elements.forEach(element => {
|
| 1263 |
+
const originalElementText = element.getAttribute('data-original-text') || element.textContent;
|
| 1264 |
+
if (originalElementText === originalText) {
|
| 1265 |
+
element.textContent = translation;
|
| 1266 |
+
}
|
| 1267 |
+
});
|
| 1268 |
+
});
|
| 1269 |
+
|
| 1270 |
+
// Apply placeholder translations
|
| 1271 |
+
Object.keys(translations.placeholders).forEach(originalPlaceholder => {
|
| 1272 |
+
const translation = translations.placeholders[originalPlaceholder];
|
| 1273 |
+
const elements = document.querySelectorAll(`[data-translate-placeholder]`);
|
| 1274 |
+
|
| 1275 |
+
elements.forEach(element => {
|
| 1276 |
+
const originalElementPlaceholder = element.getAttribute('data-original-placeholder') || element.placeholder;
|
| 1277 |
+
if (originalElementPlaceholder === originalPlaceholder) {
|
| 1278 |
+
element.placeholder = translation;
|
| 1279 |
+
}
|
| 1280 |
+
});
|
| 1281 |
+
});
|
| 1282 |
+
}
|
| 1283 |
+
|
| 1284 |
+
// Translate all UI elements
|
| 1285 |
+
async function translateInterface(targetLanguage) {
|
| 1286 |
+
if (targetLanguage === 'en') {
|
| 1287 |
+
// No translation needed for English
|
| 1288 |
+
return;
|
| 1289 |
+
}
|
| 1290 |
+
|
| 1291 |
+
// Check if translations are cached
|
| 1292 |
+
const cachedTranslations = loadTranslationsFromCache(targetLanguage);
|
| 1293 |
+
if (cachedTranslations) {
|
| 1294 |
+
// Use cached translations
|
| 1295 |
+
console.log('Using cached translations for', targetLanguage);
|
| 1296 |
+
applyCachedTranslations(cachedTranslations);
|
| 1297 |
+
return;
|
| 1298 |
+
}
|
| 1299 |
+
|
| 1300 |
+
// Need to translate via API
|
| 1301 |
+
showTranslationOverlay();
|
| 1302 |
+
|
| 1303 |
+
try {
|
| 1304 |
+
// Get all elements with data-translate attribute
|
| 1305 |
+
const elements = document.querySelectorAll('[data-translate]');
|
| 1306 |
+
const placeholderElements = document.querySelectorAll('[data-translate-placeholder]');
|
| 1307 |
+
|
| 1308 |
+
// Collect all texts to translate
|
| 1309 |
+
const textsToTranslate = [];
|
| 1310 |
+
const placeholdersToTranslate = [];
|
| 1311 |
+
const elementMap = new Map();
|
| 1312 |
+
|
| 1313 |
+
elements.forEach(element => {
|
| 1314 |
+
const originalText = element.getAttribute('data-original-text') || element.textContent;
|
| 1315 |
+
if (!element.getAttribute('data-original-text')) {
|
| 1316 |
+
element.setAttribute('data-original-text', originalText);
|
| 1317 |
+
}
|
| 1318 |
+
textsToTranslate.push(originalText);
|
| 1319 |
+
elementMap.set(originalText, element);
|
| 1320 |
+
});
|
| 1321 |
+
|
| 1322 |
+
placeholderElements.forEach(element => {
|
| 1323 |
+
const originalPlaceholder = element.getAttribute('data-original-placeholder') || element.placeholder;
|
| 1324 |
+
if (!element.getAttribute('data-original-placeholder')) {
|
| 1325 |
+
element.setAttribute('data-original-placeholder', originalPlaceholder);
|
| 1326 |
+
}
|
| 1327 |
+
placeholdersToTranslate.push(originalPlaceholder);
|
| 1328 |
+
elementMap.set(originalPlaceholder, element);
|
| 1329 |
+
});
|
| 1330 |
+
|
| 1331 |
+
// Prepare cache structure
|
| 1332 |
+
const translationsCache = {
|
| 1333 |
+
texts: {},
|
| 1334 |
+
placeholders: {}
|
| 1335 |
+
};
|
| 1336 |
+
|
| 1337 |
+
// Translate texts in batches
|
| 1338 |
+
const batchSize = 10;
|
| 1339 |
+
const allTexts = [...textsToTranslate, ...placeholdersToTranslate];
|
| 1340 |
+
|
| 1341 |
+
for (let i = 0; i < allTexts.length; i += batchSize) {
|
| 1342 |
+
const batch = allTexts.slice(i, i + batchSize);
|
| 1343 |
+
|
| 1344 |
+
// Update progress
|
| 1345 |
+
updateTranslationProgress(i, allTexts.length);
|
| 1346 |
+
|
| 1347 |
+
// Translate batch
|
| 1348 |
+
const translations = await Promise.all(
|
| 1349 |
+
batch.map(text => translateText(text, targetLanguage))
|
| 1350 |
+
);
|
| 1351 |
+
|
| 1352 |
+
// Apply translations and cache them
|
| 1353 |
+
batch.forEach((originalText, index) => {
|
| 1354 |
+
const element = elementMap.get(originalText);
|
| 1355 |
+
const translation = translations[index];
|
| 1356 |
+
|
| 1357 |
+
if (element.hasAttribute('data-translate')) {
|
| 1358 |
+
element.textContent = translation;
|
| 1359 |
+
translationsCache.texts[originalText] = translation;
|
| 1360 |
+
} else if (element.hasAttribute('data-translate-placeholder')) {
|
| 1361 |
+
element.placeholder = translation;
|
| 1362 |
+
translationsCache.placeholders[originalText] = translation;
|
| 1363 |
+
}
|
| 1364 |
+
});
|
| 1365 |
+
}
|
| 1366 |
+
|
| 1367 |
+
// Save translations to cache
|
| 1368 |
+
saveTranslationsToCache(targetLanguage, translationsCache);
|
| 1369 |
+
|
| 1370 |
+
// Update cache status
|
| 1371 |
+
updateCacheStatus(targetLanguage);
|
| 1372 |
+
updateCacheStatusDisplay();
|
| 1373 |
+
|
| 1374 |
+
} catch (error) {
|
| 1375 |
+
console.error('Translation error:', error);
|
| 1376 |
+
showError('Translation failed: ' + error.message);
|
| 1377 |
+
} finally {
|
| 1378 |
+
hideTranslationOverlay();
|
| 1379 |
+
}
|
| 1380 |
+
}
|
| 1381 |
+
|
| 1382 |
+
// Show translation overlay
|
| 1383 |
+
function showTranslationOverlay() {
|
| 1384 |
+
document.getElementById('translationOverlay').style.display = 'flex';
|
| 1385 |
+
}
|
| 1386 |
+
|
| 1387 |
+
// Hide translation overlay
|
| 1388 |
+
function hideTranslationOverlay() {
|
| 1389 |
+
document.getElementById('translationOverlay').style.display = 'none';
|
| 1390 |
+
}
|
| 1391 |
+
|
| 1392 |
+
// Update translation progress
|
| 1393 |
+
function updateTranslationProgress(current, total) {
|
| 1394 |
+
const percentage = Math.round((current / total) * 100);
|
| 1395 |
+
document.getElementById('translationMessage').textContent =
|
| 1396 |
+
`Translating interface... ${percentage}% complete (will be cached for future use)`;
|
| 1397 |
+
}
|
| 1398 |
+
|
| 1399 |
+
// Apply language with API translation or cache
|
| 1400 |
+
async function applyLanguage(language) {
|
| 1401 |
+
applyDirection(language);
|
| 1402 |
+
|
| 1403 |
+
if (language !== 'en') {
|
| 1404 |
+
await translateInterface(language);
|
| 1405 |
+
}
|
| 1406 |
+
}
|
| 1407 |
+
|
| 1408 |
+
// Show language landing page
|
| 1409 |
+
function showLanguageLanding() {
|
| 1410 |
+
document.getElementById('languageLanding').style.display = 'block';
|
| 1411 |
+
document.getElementById('mainApp').style.display = 'none';
|
| 1412 |
+
}
|
| 1413 |
+
|
| 1414 |
+
// Show main application
|
| 1415 |
+
function showMainApp() {
|
| 1416 |
+
document.getElementById('languageLanding').style.display = 'none';
|
| 1417 |
+
document.getElementById('mainApp').style.display = 'block';
|
| 1418 |
+
|
| 1419 |
+
// Set API key in main app
|
| 1420 |
+
document.getElementById('apiKey').value = currentApiKey;
|
| 1421 |
+
}
|
| 1422 |
+
|
| 1423 |
+
// Start button click handler
|
| 1424 |
+
document.getElementById('startBtn').addEventListener('click', async function() {
|
| 1425 |
+
const selectedLanguage = document.getElementById('languageSelect').value;
|
| 1426 |
+
const apiKey = document.getElementById('apiKeyLanding').value.trim();
|
| 1427 |
+
|
| 1428 |
+
if (!apiKey) {
|
| 1429 |
+
alert('Please enter your OpenAI API key');
|
| 1430 |
+
return;
|
| 1431 |
+
}
|
| 1432 |
+
|
| 1433 |
+
currentLanguage = selectedLanguage;
|
| 1434 |
+
currentApiKey = apiKey;
|
| 1435 |
+
|
| 1436 |
+
// Save API key
|
| 1437 |
+
localStorage.setItem('competitive_strategy_api_key', apiKey);
|
| 1438 |
+
|
| 1439 |
+
// Apply language with translation (cached or API)
|
| 1440 |
+
await applyLanguage(selectedLanguage);
|
| 1441 |
+
|
| 1442 |
+
// Show main app
|
| 1443 |
+
showMainApp();
|
| 1444 |
+
});
|
| 1445 |
+
|
| 1446 |
+
// Language selector change handler
|
| 1447 |
+
document.getElementById('languageSelect').addEventListener('change', async function() {
|
| 1448 |
+
const selectedLanguage = this.value;
|
| 1449 |
+
updateCacheStatus(selectedLanguage);
|
| 1450 |
+
|
| 1451 |
+
if (currentApiKey) {
|
| 1452 |
+
await applyLanguage(selectedLanguage);
|
| 1453 |
+
} else {
|
| 1454 |
+
applyDirection(selectedLanguage);
|
| 1455 |
+
}
|
| 1456 |
+
});
|
| 1457 |
+
|
| 1458 |
+
// Clear cache button handler
|
| 1459 |
+
document.getElementById('clearCacheBtn').addEventListener('click', clearAllTranslationCache);
|
| 1460 |
+
|
| 1461 |
+
// Character counter
|
| 1462 |
+
const textInput = document.getElementById('textInput');
|
| 1463 |
+
const charCounter = document.getElementById('charCounter');
|
| 1464 |
+
|
| 1465 |
+
textInput.addEventListener('input', function() {
|
| 1466 |
+
const count = this.value.length;
|
| 1467 |
+
const charactersText = charCounter.querySelector('[data-translate="characters"]')?.textContent || 'characters';
|
| 1468 |
+
charCounter.innerHTML = `${count} <span data-translate="characters">${charactersText}</span>`;
|
| 1469 |
+
|
| 1470 |
+
if (count > 5000) {
|
| 1471 |
+
charCounter.style.color = 'var(--warning)';
|
| 1472 |
+
} else {
|
| 1473 |
+
charCounter.style.color = 'var(--text-secondary)';
|
| 1474 |
+
}
|
| 1475 |
+
});
|
| 1476 |
+
|
| 1477 |
+
// Error handling
|
| 1478 |
+
function showError(message) {
|
| 1479 |
+
const errorDiv = document.getElementById('errorMessage');
|
| 1480 |
+
errorDiv.textContent = message;
|
| 1481 |
+
errorDiv.style.display = 'block';
|
| 1482 |
+
setTimeout(() => {
|
| 1483 |
+
errorDiv.style.display = 'none';
|
| 1484 |
+
}, 5000);
|
| 1485 |
+
}
|
| 1486 |
+
|
| 1487 |
+
// API call function for Porter's analysis
|
| 1488 |
+
async function callAPI(prompt) {
|
| 1489 |
+
const apiKey = currentApiKey;
|
| 1490 |
+
|
| 1491 |
+
if (!apiKey) {
|
| 1492 |
+
throw new Error('Please enter your OpenAI API key');
|
| 1493 |
+
}
|
| 1494 |
+
|
| 1495 |
+
const payload = {
|
| 1496 |
+
model: "gpt-4o-mini",
|
| 1497 |
+
messages: [{ role: "user", content: prompt }],
|
| 1498 |
+
max_tokens: 3500,
|
| 1499 |
+
temperature: 0.3
|
| 1500 |
+
};
|
| 1501 |
+
|
| 1502 |
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
| 1503 |
+
method: "POST",
|
| 1504 |
+
headers: {
|
| 1505 |
+
"Content-Type": "application/json",
|
| 1506 |
+
"Authorization": `Bearer ${apiKey}`
|
| 1507 |
+
},
|
| 1508 |
+
body: JSON.stringify(payload)
|
| 1509 |
+
});
|
| 1510 |
+
|
| 1511 |
+
if (!response.ok) {
|
| 1512 |
+
const errorData = await response.json();
|
| 1513 |
+
throw new Error(errorData.error?.message || "API request failed");
|
| 1514 |
+
}
|
| 1515 |
+
|
| 1516 |
+
const data = await response.json();
|
| 1517 |
+
return data.choices[0].message.content;
|
| 1518 |
+
}
|
| 1519 |
+
|
| 1520 |
+
// Build Porter's Five Forces prompt
|
| 1521 |
+
function buildPortersPrompt() {
|
| 1522 |
+
const inputText = document.getElementById('textInput').value.trim();
|
| 1523 |
+
const languageName = languageNames[currentLanguage] || 'English';
|
| 1524 |
+
|
| 1525 |
+
return `Based on the following industry and business context:
|
| 1526 |
+
|
| 1527 |
+
---------------------
|
| 1528 |
+
${inputText}
|
| 1529 |
+
---------------------
|
| 1530 |
+
|
| 1531 |
+
Please generate a comprehensive, structured, and professionally formatted explanation of Porter's Five Forces that directly reflects and addresses the specific context provided above. The output should be tailored to the user's industry scenario and formatted as clean HTML with inline CSS for professional presentation. Write ENTIRELY in ${languageName} language.
|
| 1532 |
+
|
| 1533 |
+
**Required Structure:**
|
| 1534 |
+
|
| 1535 |
+
1. **Concept & Strategic Framework**
|
| 1536 |
+
- Provide a thorough description of Porter's Five Forces as a framework for analyzing competitive intensity
|
| 1537 |
+
- Explain its role in strategic planning and business strategy development
|
| 1538 |
+
- Include historical background (Michael Porter, Harvard Business School) and core principles
|
| 1539 |
+
- Connect the explanation to the specific industry context provided in the input
|
| 1540 |
+
- Discuss how the framework helps identify profit potential and competitive positioning
|
| 1541 |
+
|
| 1542 |
+
2. **Industry Context Application**
|
| 1543 |
+
- Explain how Porter's Five Forces applies to the specific industry described in the input
|
| 1544 |
+
- Reference relevant aspects of the business context and competitive challenges
|
| 1545 |
+
- Provide personalized insights based on the industry sector or market mentioned
|
| 1546 |
+
- Discuss the strategic implications for the specific business scenario
|
| 1547 |
+
|
| 1548 |
+
3. **The Five Forces (Detailed Analysis)**
|
| 1549 |
+
Based on the industry context, provide comprehensive coverage of each force:
|
| 1550 |
+
|
| 1551 |
+
**🚪 Threat of New Entrants**
|
| 1552 |
+
- Barriers to entry analysis (capital requirements, economies of scale, brand loyalty)
|
| 1553 |
+
- Government regulations and licensing requirements
|
| 1554 |
+
- Access to distribution channels and supplier relationships
|
| 1555 |
+
- Technology and know-how requirements
|
| 1556 |
+
- Customer switching costs and network effects
|
| 1557 |
+
- Specific examples relevant to the user's industry context
|
| 1558 |
+
- Strategic implications and defensive strategies
|
| 1559 |
+
|
| 1560 |
+
**🏭 Bargaining Power of Suppliers**
|
| 1561 |
+
- Supplier concentration and switching costs
|
| 1562 |
+
- Availability of substitute inputs and forward integration threats
|
| 1563 |
+
- Importance of volume to suppliers and differentiation of inputs
|
| 1564 |
+
- Impact of suppliers on cost structure and quality
|
| 1565 |
+
- Supplier relationships and dependency analysis
|
| 1566 |
+
- Specific supplier dynamics for the user's industry
|
| 1567 |
+
- Strategies for managing supplier power
|
| 1568 |
+
|
| 1569 |
+
**👥 Bargaining Power of Buyers**
|
| 1570 |
+
- Buyer concentration and purchase volumes
|
| 1571 |
+
- Price sensitivity and switching costs
|
| 1572 |
+
- Backward integration threats and substitute availability
|
| 1573 |
+
- Information availability and negotiating leverage
|
| 1574 |
+
- Impact on pricing power and profit margins
|
| 1575 |
+
- Specific buyer characteristics for the user's industry
|
| 1576 |
+
- Customer relationship and retention strategies
|
| 1577 |
+
|
| 1578 |
+
**🔄 Threat of Substitutes**
|
| 1579 |
+
- Identification of substitute products and services
|
| 1580 |
+
- Performance comparison and price-value trade-offs
|
| 1581 |
+
- Switching costs and customer propensity to substitute
|
| 1582 |
+
- Innovation trends and disruptive technologies
|
| 1583 |
+
- Impact on industry growth and profitability
|
| 1584 |
+
- Specific substitute threats for the user's industry
|
| 1585 |
+
- Innovation and differentiation strategies
|
| 1586 |
+
|
| 1587 |
+
**⚔️ Competitive Rivalry**
|
| 1588 |
+
- Number and size of competitors
|
| 1589 |
+
- Industry growth rate and capacity utilization
|
| 1590 |
+
- Product differentiation and switching costs
|
| 1591 |
+
- Exit barriers and strategic stakes
|
| 1592 |
+
- Competitive dynamics and pricing behavior
|
| 1593 |
+
- Specific competitive landscape for the user's industry
|
| 1594 |
+
- Competitive positioning and differentiation strategies
|
| 1595 |
+
|
| 1596 |
+
4. **Strategic Implications & Recommendations**
|
| 1597 |
+
- Overall industry attractiveness assessment
|
| 1598 |
+
- Competitive positioning opportunities
|
| 1599 |
+
- Strategic options for improving competitive advantage
|
| 1600 |
+
- Risk mitigation and defensive strategies
|
| 1601 |
+
- Growth and expansion considerations
|
| 1602 |
+
|
| 1603 |
+
5. **Implementation Framework**
|
| 1604 |
+
- Step-by-step process for conducting Five Forces analysis
|
| 1605 |
+
- Data collection and research methodologies
|
| 1606 |
+
- Stakeholder engagement and analysis validation
|
| 1607 |
+
- Integration with business planning and strategy development
|
| 1608 |
+
- Monitoring and updating the analysis over time
|
| 1609 |
+
|
| 1610 |
+
6. **Advanced Strategic Considerations**
|
| 1611 |
+
- Industry evolution and life cycle implications
|
| 1612 |
+
- Digital transformation and technology disruption
|
| 1613 |
+
- Globalization and market expansion effects
|
| 1614 |
+
- Regulatory changes and policy implications
|
| 1615 |
+
- Sustainability and ESG considerations
|
| 1616 |
+
|
| 1617 |
+
7. **Complementary Strategic Tools**
|
| 1618 |
+
- Integration with SWOT analysis and value chain analysis
|
| 1619 |
+
- Competitive intelligence and market research methods
|
| 1620 |
+
- Strategic group mapping and competitor profiling
|
| 1621 |
+
- Scenario planning and strategic options analysis
|
| 1622 |
+
- Performance measurement and strategic control systems
|
| 1623 |
+
|
| 1624 |
+
**Formatting Requirements:**
|
| 1625 |
+
- Use clean HTML with inline CSS for professional presentation
|
| 1626 |
+
- Include proper headings (h3, h4) with attractive styling
|
| 1627 |
+
- Use bullet points and numbered lists for clarity
|
| 1628 |
+
- Apply consistent color scheme (reds for competitive strategy themes)
|
| 1629 |
+
- Ensure responsive design and readability
|
| 1630 |
+
- Make the content scannable with clear visual hierarchy
|
| 1631 |
+
- Include specific examples relevant to the user's industry context
|
| 1632 |
+
|
| 1633 |
+
**Tone:** Professional, strategic, and directly relevant to the user's specific industry context. Focus on practical, actionable insights that can be immediately applied to their competitive analysis and strategic planning needs.
|
| 1634 |
+
|
| 1635 |
+
Return only the complete HTML content with inline CSS - no additional text or explanations outside the HTML.`;
|
| 1636 |
+
}
|
| 1637 |
+
|
| 1638 |
+
// Validation function
|
| 1639 |
+
function validateInputs() {
|
| 1640 |
+
const inputText = document.getElementById('textInput').value.trim();
|
| 1641 |
+
|
| 1642 |
+
if (!inputText) {
|
| 1643 |
+
document.getElementById('textInput').focus();
|
| 1644 |
+
throw new Error('Please enter your industry context or business scenario');
|
| 1645 |
+
}
|
| 1646 |
+
|
| 1647 |
+
if (inputText.length < 50) {
|
| 1648 |
+
document.getElementById('textInput').focus();
|
| 1649 |
+
throw new Error('Please provide at least 50 characters for meaningful strategic analysis');
|
| 1650 |
+
}
|
| 1651 |
+
}
|
| 1652 |
+
|
| 1653 |
+
// Generate Porter's Five Forces explanation
|
| 1654 |
+
document.getElementById('generatePortersBtn').addEventListener('click', async function() {
|
| 1655 |
+
const button = this;
|
| 1656 |
+
const buttonText = document.getElementById('buttonText');
|
| 1657 |
+
const spinner = document.getElementById('spinner');
|
| 1658 |
+
const outputArea = document.getElementById('apiOutput');
|
| 1659 |
+
|
| 1660 |
+
try {
|
| 1661 |
+
// Validate inputs
|
| 1662 |
+
validateInputs();
|
| 1663 |
+
|
| 1664 |
+
// Update button state
|
| 1665 |
+
button.disabled = true;
|
| 1666 |
+
spinner.style.display = 'inline-block';
|
| 1667 |
+
buttonText.textContent = 'Analyzing Forces...';
|
| 1668 |
+
|
| 1669 |
+
// Clear previous output
|
| 1670 |
+
outputArea.innerHTML = '';
|
| 1671 |
+
|
| 1672 |
+
// Build prompt and call API
|
| 1673 |
+
const prompt = buildPortersPrompt();
|
| 1674 |
+
const result = await callAPI(prompt);
|
| 1675 |
+
|
| 1676 |
+
// Display result
|
| 1677 |
+
outputArea.innerHTML = result;
|
| 1678 |
+
|
| 1679 |
+
} catch (error) {
|
| 1680 |
+
showError(error.message);
|
| 1681 |
+
outputArea.innerHTML = '';
|
| 1682 |
+
} finally {
|
| 1683 |
+
// Reset button state
|
| 1684 |
+
button.disabled = false;
|
| 1685 |
+
spinner.style.display = 'none';
|
| 1686 |
+
buttonText.textContent = '⚔️ Generate Five Forces Analysis';
|
| 1687 |
+
}
|
| 1688 |
+
});
|
| 1689 |
+
|
| 1690 |
+
// Keyboard shortcut for generation
|
| 1691 |
+
document.addEventListener('keydown', function(e) {
|
| 1692 |
+
if (e.ctrlKey && e.key === 'Enter') {
|
| 1693 |
+
e.preventDefault();
|
| 1694 |
+
document.getElementById('generatePortersBtn').click();
|
| 1695 |
+
}
|
| 1696 |
+
});
|
| 1697 |
+
|
| 1698 |
+
// API key sync between landing and main app
|
| 1699 |
+
document.getElementById('apiKeyLanding').addEventListener('input', function() {
|
| 1700 |
+
currentApiKey = this.value;
|
| 1701 |
+
localStorage.setItem('competitive_strategy_api_key', this.value);
|
| 1702 |
+
document.getElementById('apiKey').value = this.value;
|
| 1703 |
+
});
|
| 1704 |
+
|
| 1705 |
+
document.getElementById('apiKey').addEventListener('input', function() {
|
| 1706 |
+
currentApiKey = this.value;
|
| 1707 |
+
localStorage.setItem('competitive_strategy_api_key', this.value);
|
| 1708 |
+
document.getElementById('apiKeyLanding').value = this.value;
|
| 1709 |
+
});
|
| 1710 |
+
|
| 1711 |
+
// Initialize the application when page loads
|
| 1712 |
+
document.addEventListener('DOMContentLoaded', initializeApp);
|
| 1713 |
+
</script>
|
| 1714 |
+
</body>
|
| 1715 |
+
</html>
|
| 1716 |
+
|
📘 Educator & Business User Guide.txt
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
📘 Educator & Business User Guide: CompetitiveStrategy Pro
|
| 2 |
+
1. Purpose & Impact
|
| 3 |
+
CompetitiveStrategy Pro brings actionable, evidence-based strategy analysis to your browser, supporting both professional business use and modern classrooms. Designed for Porter’s Five Forces deep dives, it supports innovation, risk management, and competitive insight—across any sector, in any language.
|
| 4 |
+
|
| 5 |
+
2. Step-by-Step Instructions
|
| 6 |
+
A. Setup
|
| 7 |
+
Open the app (HTML or hosted Space).
|
| 8 |
+
|
| 9 |
+
Choose your preferred language (RTL/LTR fully supported).
|
| 10 |
+
|
| 11 |
+
Enter your OpenAI API key (used only in your browser).
|
| 12 |
+
|
| 13 |
+
B. Input Your Scenario
|
| 14 |
+
Enter your industry/business context:
|
| 15 |
+
|
| 16 |
+
Example: “Global EV automotive market, focusing on mid-price electric SUVs; rapid new entrants in China and US, battery supplier dependency, price-sensitive buyers, major rivals (BYD, Tesla, VW), etc.”
|
| 17 |
+
|
| 18 |
+
Minimum 50 characters for robust results.
|
| 19 |
+
|
| 20 |
+
C. Generate & Use Analysis
|
| 21 |
+
Click “Generate Five Forces Analysis.”
|
| 22 |
+
|
| 23 |
+
The AI will generate a multi-section, visually rich HTML report, including:
|
| 24 |
+
|
| 25 |
+
Framework Overview: Porter’s history, theory, and method.
|
| 26 |
+
|
| 27 |
+
Industry Application: How the forces map to your specific scenario.
|
| 28 |
+
|
| 29 |
+
Five Forces Breakdown: Each force analyzed in depth with industry-specific examples and strategic tips.
|
| 30 |
+
|
| 31 |
+
Strategic Implications: Concrete recommendations and risk/growth tips.
|
| 32 |
+
|
| 33 |
+
Implementation Guide: How to repeat or adapt analysis for new contexts.
|
| 34 |
+
|
| 35 |
+
Advanced Topics: Tech disruption, regulation, sustainability, and more.
|
| 36 |
+
|
| 37 |
+
Complementary Tools: Integration with SWOT, value chain, etc.
|
| 38 |
+
|
| 39 |
+
Copy HTML for use in slides, reports, LMS, or digital portfolios.
|
| 40 |
+
|
| 41 |
+
3. Advanced Classroom & Business Use
|
| 42 |
+
Educators:
|
| 43 |
+
|
| 44 |
+
Assign industry research, strategy projects, or simulation activities.
|
| 45 |
+
|
| 46 |
+
Compare outputs for different scenarios/years to illustrate market shifts.
|
| 47 |
+
|
| 48 |
+
Use the tool for group projects, debate, or assessment.
|
| 49 |
+
|
| 50 |
+
Business Users:
|
| 51 |
+
|
| 52 |
+
Conduct real strategic reviews or due diligence.
|
| 53 |
+
|
| 54 |
+
Benchmark different markets or business units.
|
| 55 |
+
|
| 56 |
+
Use outputs to brief teams or boards—export, print, or share as needed.
|
| 57 |
+
|
| 58 |
+
4. Best Practices
|
| 59 |
+
Be detailed in your scenario for the best insights.
|
| 60 |
+
|
| 61 |
+
Use multilingual UI for international collaboration or teaching.
|
| 62 |
+
|
| 63 |
+
Clear cache between sessions for data security or new project starts.
|
| 64 |
+
|
| 65 |
+
5. Troubleshooting & Support
|
| 66 |
+
If you see errors:
|
| 67 |
+
|
| 68 |
+
Check your API key and quota.
|
| 69 |
+
|
| 70 |
+
Ensure input is specific and 50+ characters.
|
| 71 |
+
|
| 72 |
+
Translation slow?
|
| 73 |
+
|
| 74 |
+
First use in a language will cache, making future loads instant.
|
| 75 |
+
|
| 76 |
+
Need help?
|
| 77 |
+
|
| 78 |
+
Email info@shiftmind.io
|
| 79 |
+
|
| 80 |
+
Visit www.shiftmind.io
|
| 81 |
+
|
| 82 |
+
CompetitiveStrategy Pro empowers both students and professionals to achieve deeper, data-driven strategy analysis—securely, accessibly, and in any language.
|