Darshan03 commited on
Commit
e6e5558
·
verified ·
1 Parent(s): dae9c8c

Upload 9 files

Browse files
Files changed (9) hide show
  1. .dockerignore +51 -0
  2. .env +9 -0
  3. .gitignore +298 -0
  4. Dockerfile +35 -35
  5. README.md +160 -20
  6. docker-compose.yml +28 -0
  7. requirements.txt +0 -0
  8. streamlit_app.py +782 -0
  9. watch_and_restart.py +40 -0
.dockerignore ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Git
2
+ .git
3
+ .gitignore
4
+
5
+ # Python
6
+ __pycache__/
7
+ *.py[cod]
8
+ *$py.class
9
+ *.so
10
+ .Python
11
+ env/
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # Virtual Environment
28
+ venv/
29
+ ENV/
30
+
31
+ # IDE
32
+ .idea/
33
+ .vscode/
34
+ *.swp
35
+ *.swo
36
+
37
+ # Environment variables
38
+ .env
39
+ .env.*
40
+
41
+ # Docker
42
+ Dockerfile
43
+ docker-compose.yml
44
+ .dockerignore
45
+
46
+ # Logs
47
+ *.log
48
+
49
+ # Local development
50
+ .DS_Store
51
+ Thumbs.db
.env ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ GOOGLE_MAPS_API_KEY = "AIzaSyDQFL41TpGPqHe1RuUQrzgAKgZv1QKiidg"
2
+ GROQ_API_KEY="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"
3
+ GOOGLE_API_KEY = "AIzaSyCyDgvCFhIEJLDobxS2D4Rv79j7RBSIfn0"
4
+ SNOWFLAKE_USER="ASHITOSH1409"
5
+ SNOWFLAKE_PASSWORD="AshitoshKatale@2003"
6
+ SNOWFLAKE_ACCOUNT="BOTIBKV-JZ14792"
7
+ SNOWFLAKE_WAREHOUSE="COMPUTE_WH"
8
+ SNOWFLAKE_DATABASE="MAIN"
9
+ SNOWFLAKE_SCHEMA="PUBLIC"
.gitignore ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # poetry
98
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102
+ #poetry.lock
103
+
104
+ # pdm
105
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106
+ #pdm.lock
107
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108
+ # in version control.
109
+ # https://pdm.fming.dev/#use-with-ide
110
+ .pdm.toml
111
+
112
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
113
+ __pypackages__/
114
+
115
+ # Celery stuff
116
+ celerybeat-schedule
117
+ celerybeat.pid
118
+
119
+ # SageMath parsed files
120
+ *.sage.py
121
+
122
+ # Environments
123
+ .env
124
+ .venv
125
+ env/
126
+ venv/
127
+ ENV/
128
+ env.bak/
129
+ venv.bak/
130
+
131
+ # Spyder project settings
132
+ .spyderproject
133
+ .spyproject
134
+
135
+ # Rope project settings
136
+ .ropeproject
137
+
138
+ # mkdocs documentation
139
+ /site
140
+
141
+ # mypy
142
+ .mypy_cache/
143
+ .dmypy.json
144
+ dmypy.json
145
+
146
+ # Pyre type checker
147
+ .pyre/
148
+
149
+ # pytype static type analyzer
150
+ .pytype/
151
+
152
+ # Cython debug symbols
153
+ cython_debug/
154
+
155
+ # PyCharm
156
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
157
+ # be added to the global gitignore or merged into this project gitignore. For a PyCharm
158
+ # project, it is recommended to ignore the entire idea folder.
159
+ .idea/
160
+
161
+ # Streamlit specific files
162
+ .streamlit/
163
+ *.toml
164
+
165
+ # Streamlit secrets (IMPORTANT: Never commit secrets)
166
+ .streamlit/secrets.toml
167
+ secrets.toml
168
+
169
+ # Streamlit cache
170
+ .streamlit/cache/
171
+
172
+ # VS Code
173
+ .vscode/
174
+ *.code-workspace
175
+
176
+ # Sublime Text
177
+ *.sublime-project
178
+ *.sublime-workspace
179
+
180
+ # Vim
181
+ *.swp
182
+ *.swo
183
+ *~
184
+
185
+ # Emacs
186
+ *~
187
+ \#*\#
188
+ /.emacs.desktop
189
+ /.emacs.desktop.lock
190
+ *.elc
191
+ auto-save-list
192
+ tramp
193
+ .\#*
194
+
195
+ # macOS
196
+ .DS_Store
197
+ .AppleDouble
198
+ .LSOverride
199
+ Icon
200
+ ._*
201
+ .DocumentRevisions-V100
202
+ .fseventsd
203
+ .Spotlight-V100
204
+ .TemporaryItems
205
+ .Trashes
206
+ .VolumeIcon.icns
207
+ .com.apple.timemachine.donotpresent
208
+ .AppleDB
209
+ .AppleDesktop
210
+ Network Trash Folder
211
+ Temporary Items
212
+ .apdisk
213
+
214
+ # Windows
215
+ Thumbs.db
216
+ Thumbs.db:encryptable
217
+ ehthumbs.db
218
+ ehthumbs_vista.db
219
+ *.stackdump
220
+ [Dd]esktop.ini
221
+ $RECYCLE.BIN/
222
+ *.cab
223
+ *.msi
224
+ *.msix
225
+ *.msm
226
+ *.msp
227
+ *.lnk
228
+
229
+ # Linux
230
+ *~
231
+ .fuse_hidden*
232
+ .directory
233
+ .Trash-*
234
+ .nfs*
235
+
236
+ # Logs
237
+ logs/
238
+ *.log
239
+ npm-debug.log*
240
+ yarn-debug.log*
241
+ yarn-error.log*
242
+
243
+ # Runtime data
244
+ pids
245
+ *.pid
246
+ *.seed
247
+ *.pid.lock
248
+
249
+ # Temporary files
250
+ tmp/
251
+ temp/
252
+ .tmp/
253
+ .temp/
254
+
255
+ # Application specific
256
+ # Uncomment the lines below if you want to ignore certain data files
257
+
258
+
259
+
260
+ # Configuration files (uncomment if you want to ignore config files)
261
+ # config.json
262
+ # settings.json
263
+
264
+ # Backup files
265
+ *.bak
266
+ *.backup
267
+ *.old
268
+
269
+ # Database files (if you add database support later)
270
+ *.db
271
+ *.sqlite
272
+ *.sqlite3
273
+
274
+ # Image cache (if your app generates/caches images)
275
+ image_cache/
276
+ .image_cache/
277
+
278
+ # Custom directories for your app
279
+ uploads/
280
+ downloads/
281
+ cache/
282
+ .cache/
283
+
284
+ # Environment-specific files
285
+ .env.local
286
+ .env.production
287
+ .env.staging
288
+ .env.development
289
+
290
+ # Package files
291
+ *.tgz
292
+ *.tar.gz
293
+ *.zip
294
+ *.rar
295
+
296
+ # Documentation builds
297
+ docs/build/
298
+ site/
Dockerfile CHANGED
@@ -1,36 +1,36 @@
1
- # Use Python 3.9 slim image as base
2
- FROM python:3.9-slim
3
-
4
- # Set working directory
5
- WORKDIR /app
6
-
7
- # Set environment variables
8
- ENV PYTHONDONTWRITEBYTECODE=1 \
9
- PYTHONUNBUFFERED=1 \
10
- PYTHONPATH=/app
11
-
12
- # Install system dependencies
13
- RUN apt-get update && apt-get install -y \
14
- build-essential \
15
- curl \
16
- software-properties-common \
17
- git \
18
- && rm -rf /var/lib/apt/lists/*
19
-
20
- # Copy requirements file
21
- COPY requirements.txt .
22
-
23
- # Install Python dependencies
24
- RUN pip install --no-cache-dir -r requirements.txt
25
-
26
- # Copy project files
27
- COPY . .
28
-
29
- # Expose port
30
- EXPOSE 8501
31
-
32
- # Set healthcheck
33
- HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
34
-
35
- # Command to run the application
36
  ENTRYPOINT ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]
 
1
+ # Use Python 3.9 slim image as base
2
+ FROM python:3.9-slim
3
+
4
+ # Set working directory
5
+ WORKDIR /app
6
+
7
+ # Set environment variables
8
+ ENV PYTHONDONTWRITEBYTECODE=1 \
9
+ PYTHONUNBUFFERED=1 \
10
+ PYTHONPATH=/app
11
+
12
+ # Install system dependencies
13
+ RUN apt-get update && apt-get install -y \
14
+ build-essential \
15
+ curl \
16
+ software-properties-common \
17
+ git \
18
+ && rm -rf /var/lib/apt/lists/*
19
+
20
+ # Copy requirements file
21
+ COPY requirements.txt .
22
+
23
+ # Install Python dependencies
24
+ RUN pip install --no-cache-dir -r requirements.txt
25
+
26
+ # Copy project files
27
+ COPY . .
28
+
29
+ # Expose port
30
+ EXPOSE 8501
31
+
32
+ # Set healthcheck
33
+ HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
34
+
35
+ # Command to run the application
36
  ENTRYPOINT ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]
README.md CHANGED
@@ -1,20 +1,160 @@
1
- ---
2
- title: Snowflake HeroChallenge
3
- emoji: 🚀
4
- colorFrom: red
5
- colorTo: red
6
- sdk: docker
7
- app_port: 8501
8
- tags:
9
- - streamlit
10
- pinned: false
11
- short_description: Streamlit template space
12
- license: apache-2.0
13
- ---
14
-
15
- # Welcome to Streamlit!
16
-
17
- Edit `/src/streamlit_app.py` to customize this app to your heart's desire. :heart:
18
-
19
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
20
- forums](https://discuss.streamlit.io).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🎨 Art & Cultural Heritage Explorer
2
+
3
+ Discover cultural heritage through AI-powered storytelling and interactive features. We aim to make history engaging and accessible for everyone.
4
+
5
+ > Made with ❤️ by Team Gandivam
6
+
7
+ ## 🌟 Overview
8
+
9
+ The Art & Cultural Heritage Explorer is an innovative web application that brings cultural heritage to life through AI-powered storytelling and interactive features. Our platform makes exploring art, architecture, and cultural heritage engaging and accessible for everyone.
10
+
11
+ ## 🚧 Key Challenges Addressed
12
+
13
+ 1. **Making Cultural Heritage Interesting for Everyone**
14
+ - Engaging younger audiences with cultural heritage
15
+ - Creating interactive and modern experiences
16
+
17
+ 2. **Telling Real and Interactive Stories with AI**
18
+ - Delivering authentic, respectful, and engaging narratives
19
+ - Adapting AI responses to diverse users while maintaining accuracy
20
+
21
+ 3. **Creating Fun and Easy Ways to Explore**
22
+ - Implementing smart design for maps and galleries
23
+ - Making cultural exploration enjoyable and intuitive
24
+
25
+ 4. **Keeping the Website Simple and Easy to Use**
26
+ - Organizing information clearly
27
+ - Ensuring mobile-friendly experience
28
+
29
+ ## 💡 Solution Overview
30
+
31
+ - Interactive web app built with Streamlit + Snowflake
32
+ - AI-powered storytelling to animate cultural items
33
+ - Interactive maps to explore architectural heritage
34
+ - Image gallery to browse cultural content
35
+ - AI chatbot to answer questions about art, places, architecture
36
+ - Google Maps integration for street view & locations
37
+ - Secure deployment on Streamlit Cloud
38
+
39
+ ## 🛠️ Tech Stack
40
+
41
+ ### Frontend
42
+ - Streamlit
43
+ - Custom CSS/HTML
44
+ - Google Fonts
45
+ - Responsive design
46
+
47
+ ### Backend
48
+ - Python 3.x
49
+ - Streamlit web framework
50
+ - Pandas, NumPy
51
+
52
+ ### APIs
53
+ - Google Maps API
54
+ - Groq API (for AI)
55
+
56
+ ### AI/ML
57
+ - Groq for story generation
58
+ - Custom AI chatbot (NLP)
59
+
60
+ ### Deployment
61
+ - Streamlit Cloud
62
+ - Secure API key handling
63
+
64
+ ### Data Management
65
+ - Snowflake (warehouse)
66
+ - JSON/CSV for data
67
+ - JPEG/PNG for images
68
+ - ChromaDB for vector storage
69
+
70
+ ## 🏗️ Architecture
71
+
72
+ ### High-Level Architecture
73
+ The application follows a modern architecture with clear separation of concerns:
74
+ - User Interface Layer (Streamlit)
75
+ - Application Logic Layer (Python)
76
+ - Data Layer (Snowflake)
77
+ - AI Services Layer (Groq)
78
+
79
+ ### Main Application Flow
80
+ 1. User interacts with app
81
+ 2. Backend processes requests
82
+ 3. AI generates stories/responses
83
+ 4. UI displays content
84
+
85
+ ## 🎯 User Experience Features
86
+
87
+ ### Responsive Grid Layout
88
+ - Adaptive to screen sizes
89
+ - Smooth transitions
90
+ - Touch-friendly
91
+
92
+ ### Interactive Gallery
93
+ - High-res image zoom/pan
94
+ - Carousel navigation
95
+ - Quick view
96
+
97
+ ### Navigation
98
+ - Intuitive categories
99
+ - Clear menu
100
+ - Search and breadcrumb support
101
+
102
+ ### Loading States & Animations
103
+ - Smooth load transitions
104
+ - Story generation and map loading animations
105
+
106
+ ## 🔮 Future Enhancements
107
+
108
+ 1. **AI-Based Recommendations**
109
+ - Recommends nearby arts & locations using user's live location
110
+
111
+ 2. **3D Modeling with AI**
112
+ - AI-generated 3D models of art/architecture
113
+ - Enhanced AR experience
114
+
115
+ 3. **AI Vision Guide**
116
+ - Natural language explanation of visuals (art & architecture)
117
+
118
+ 4. **Onboarding Local Guides & Artists**
119
+ - Encourages responsible tourism
120
+ - Supports local communities
121
+
122
+ ## 👥 Team Gandivam
123
+
124
+ - Darshan Roy
125
+ - Jyoti Sharma
126
+ - Sarthak Gaikwad
127
+ - Prathamesh Bhaskar
128
+ - Ashitosh Katale
129
+
130
+ ## 🚀 Getting Started
131
+
132
+ 1. Clone the repository
133
+ ```bash
134
+ git clone [repository-url]
135
+ ```
136
+
137
+ 2. Install dependencies
138
+ ```bash
139
+ pip install -r requirements.txt
140
+ ```
141
+
142
+ 3. Set up environment variables
143
+ ```bash
144
+ cp .env.example .env
145
+ # Edit .env with your credentials
146
+ ```
147
+
148
+ 4. Run the application
149
+ ```bash
150
+ streamlit run app.py
151
+ ```
152
+
153
+ ## 📝 License
154
+
155
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
156
+
157
+ ## 🙏 Acknowledgments
158
+
159
+ - Made with [Gamma](https://gamma.app/?utm_source=made-with-gamma)
160
+ - Special thanks to all contributors and supporters
docker-compose.yml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: '3.8'
2
+
3
+ services:
4
+ app:
5
+ build: .
6
+ container_name: art_culture_app
7
+ ports:
8
+ - "8501:8501"
9
+ volumes:
10
+ - .:/app
11
+ env_file:
12
+ - .env
13
+ environment:
14
+ - SNOWFLAKE_USER=${SNOWFLAKE_USER}
15
+ - SNOWFLAKE_PASSWORD=${SNOWFLAKE_PASSWORD}
16
+ - SNOWFLAKE_ACCOUNT=${SNOWFLAKE_ACCOUNT}
17
+ - SNOWFLAKE_WAREHOUSE=${SNOWFLAKE_WAREHOUSE}
18
+ - SNOWFLAKE_DATABASE=${SNOWFLAKE_DATABASE}
19
+ - SNOWFLAKE_SCHEMA=${SNOWFLAKE_SCHEMA}
20
+ - GOOGLE_MAPS_API_KEY=${GOOGLE_MAPS_API_KEY}
21
+ - GROQ_API_KEY=${GROQ_API_KEY}
22
+ restart: unless-stopped
23
+ healthcheck:
24
+ test: ["CMD", "curl", "--fail", "http://localhost:8501/_stcore/health"]
25
+ interval: 30s
26
+ timeout: 10s
27
+ retries: 3
28
+ start_period: 40s
requirements.txt CHANGED
Binary files a/requirements.txt and b/requirements.txt differ
 
streamlit_app.py ADDED
@@ -0,0 +1,782 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from config.settings import PAGE_CONFIG
3
+ from loaders.data_loader import load_all_data_streamlit
4
+ from utils.session import initialize_session_state
5
+ from utils.router import router
6
+ from pages import home, category_detail, item_detail
7
+
8
+
9
+ def apply_custom_css():
10
+ """Apply custom light-blue theme CSS for improved UI with Poppins fonts."""
11
+ st.markdown(
12
+ """
13
+ <style>
14
+ /* Import Google Fonts and Adobe Fonts (Typekit) */
15
+ @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;600;700&family=Inter:wght@300;400;500;600&display=swap');
16
+ </style>
17
+
18
+ <!-- Adobe Fonts (Typekit) for Poppins -->
19
+ <link rel="stylesheet" href="https://use.typekit.net/jre8nsm.css">
20
+
21
+ <style>
22
+ /* Hide Streamlit branding */
23
+ #MainMenu {visibility: hidden;}
24
+ footer {visibility: hidden;}
25
+ header {visibility: hidden;}
26
+
27
+ /* Hide sidebar collapse/expand button */
28
+ .css-1vbkxwb {display: none;}
29
+ button[data-testid="collapsedControl"] {display: none;}
30
+ .css-1rs6os {display: none;}
31
+ .css-1cypcdb {display: none;}
32
+ .streamlit-expanderHeader {display: none;}
33
+ div[data-testid="stSidebarCollapsedControl"] {display: none;}
34
+ .css-1outpf7 {display: none;}
35
+
36
+ /* Hide Streamlit elements */
37
+ #MainMenu {display: none;}
38
+ footer {display: none;}
39
+ header {display: none;}
40
+
41
+ /* Hide Sidebar Completely */
42
+ .css-1d391kg {display: none;}
43
+ .css-1aumxhk {display: none;}
44
+ section[data-testid="stSidebar"] {display: none;}
45
+ .css-17eq0hr {display: none;}
46
+ .css-1cypcdb {display: none;}
47
+ .css-1544g2n {display: none;}
48
+ div[data-testid="stSidebarNav"] {display: none;}
49
+ .css-1lcbmhc {display: none;}
50
+ .css-1outpf7 {display: none;}
51
+
52
+ /* Remove top spacing and adjust main content to full width */
53
+ .stApp {
54
+ margin-top: -205px !important;
55
+ padding-top: 0 !important;
56
+ scroll-behavior: smooth !important;
57
+ }
58
+
59
+ .main .block-container {
60
+ padding-top: 0 !important;
61
+ padding-left: 1rem !important;
62
+ padding-right: 1rem !important;
63
+ max-width: none !important;
64
+ width: 100% !important;
65
+ margin-top: 0 !important;
66
+ }
67
+
68
+ /* Ensure content uses full width and removes top spacing */
69
+ .stApp > div:first-child {
70
+ margin-left: 0 !important;
71
+ margin-top: 0 !important;
72
+ padding-top: 0 !important;
73
+ }
74
+
75
+ /* Remove any default top margins/padding */
76
+ div[data-testid="stAppViewContainer"] {
77
+ padding-top: 0 !important;
78
+ margin-top: 0 !important;
79
+ }
80
+
81
+ div[data-testid="stMain"] {
82
+ padding-top: 0 !important;
83
+ margin-top: 0 !important;
84
+ }
85
+
86
+ /* Force scroll position */
87
+ html {
88
+ scroll-behavior: auto !important;
89
+ }
90
+
91
+ body {
92
+ overflow-x: hidden;
93
+ font-family: "poppins", sans-serif;
94
+ font-weight: 400;
95
+ font-style: normal;
96
+ }
97
+
98
+ /* Global Styles - Light Blue Theme */
99
+ .main {
100
+ padding: 0rem 1rem;
101
+ background-color: #F0F8FF;
102
+ margin-top: 0 !important;
103
+ font-family: "poppins", sans-serif;
104
+ }
105
+
106
+ /* Custom Color Palette - Light Blue Theme */
107
+ :root {
108
+ --primary-blue: #1E88E5;
109
+ --secondary-blue: #42A5F5;
110
+ --deep-blue: #1565C0;
111
+ --light-bg: #F0F8FF;
112
+ --card-bg: #FFFFFF;
113
+ --surface-bg: #E3F2FD;
114
+ --accent-blue: #2196F3;
115
+ --text-dark: #1A237E;
116
+ --text-primary: #0D47A1;
117
+ --text-secondary: #1976D2;
118
+ --text-muted: #5C6BC0;
119
+ --border-color: #BBDEFB;
120
+ --success-green: #4CAF50;
121
+ --gradient-start: #E3F2FD;
122
+ --gradient-end: #BBDEFB;
123
+ --highlight-color: #FF9800;
124
+ --shadow-light: rgba(30, 136, 229, 0.1);
125
+ --shadow-medium: rgba(30, 136, 229, 0.2);
126
+ --shadow-strong: rgba(30, 136, 229, 0.3);
127
+
128
+ /* Font Family Variables */
129
+ --font-primary: "poppins", sans-serif;
130
+ --font-display: 'Playfair Display', serif;
131
+ --font-body: "poppins", sans-serif;
132
+ --font-ui: "poppins", sans-serif;
133
+ }
134
+
135
+ /* Typography with Poppins Integration */
136
+ .main-title {
137
+ font-family: var(--font-display);
138
+ font-size: 3.5rem;
139
+ font-weight: 700;
140
+ color: var(--text-dark);
141
+ text-align: center;
142
+ margin-bottom: 0.5rem;
143
+ text-shadow: 2px 2px 4px rgba(30, 136, 229, 0.1);
144
+ background: linear-gradient(135deg, var(--primary-blue), var(--secondary-blue));
145
+ -webkit-background-clip: text;
146
+ -webkit-text-fill-color: transparent;
147
+ background-clip: text;
148
+ }
149
+
150
+ .section-title {
151
+ font-family: var(--font-display);
152
+ font-size: 2.5rem;
153
+ font-weight: 600;
154
+ color: var(--text-dark);
155
+ text-align: center;
156
+ margin: 2rem 0 3rem 0;
157
+ position: relative;
158
+ }
159
+
160
+ .section-title::after {
161
+ content: '';
162
+ position: absolute;
163
+ bottom: -10px;
164
+ left: 50%;
165
+ transform: translateX(-50%);
166
+ width: 80px;
167
+ height: 3px;
168
+ background: linear-gradient(90deg, var(--primary-blue), var(--secondary-blue));
169
+ border-radius: 2px;
170
+ }
171
+
172
+ /* Poppins Typography Classes */
173
+ .poppins-regular {
174
+ font-family: "poppins", sans-serif;
175
+ font-weight: 400;
176
+ font-style: normal;
177
+ }
178
+
179
+ .poppins-italic {
180
+ font-family: "poppins", sans-serif;
181
+ font-weight: 400;
182
+ font-style: italic;
183
+ }
184
+
185
+ .poppins-bold {
186
+ font-family: "poppins", sans-serif;
187
+ font-weight: 700;
188
+ font-style: normal;
189
+ }
190
+
191
+ .poppins-bold-italic {
192
+ font-family: "poppins", sans-serif;
193
+ font-weight: 700;
194
+ font-style: italic;
195
+ }
196
+
197
+ /* Category Cards */
198
+ .category-card {
199
+ background: var(--card-bg);
200
+ border-radius: 20px;
201
+ box-shadow: 0 8px 32px var(--shadow-light);
202
+ overflow: hidden;
203
+ transition: all 0.3s ease;
204
+ border: 1px solid var(--border-color);
205
+ margin-bottom: 2rem;
206
+ margin-top: 3rem;
207
+ position: relative;
208
+ }
209
+
210
+ .category-card:hover {
211
+ transform: translateY(-8px);
212
+ box-shadow: 0 16px 48px var(--shadow-medium);
213
+ border-color: var(--primary-blue);
214
+ }
215
+
216
+ .category-card::before {
217
+ content: '';
218
+ position: absolute;
219
+ top: 0;
220
+ left: 0;
221
+ right: 0;
222
+ height: 4px;
223
+ background: linear-gradient(90deg, var(--primary-blue), var(--secondary-blue));
224
+ }
225
+
226
+ .card-image-container {
227
+ position: relative;
228
+ overflow: hidden;
229
+ height: 200px;
230
+ }
231
+
232
+ .card-image-container img {
233
+ width: 100%;
234
+ height: 100%;
235
+ object-fit: cover;
236
+ transition: transform 0.3s ease;
237
+ }
238
+
239
+ .category-card:hover .card-image-container img {
240
+ transform: scale(1.05);
241
+ }
242
+
243
+ .card-content {
244
+ padding: 1.5rem;
245
+ background: var(--card-bg);
246
+ color: var(--text-dark);
247
+ border-top: 1px solid var(--border-color);
248
+ }
249
+
250
+ .card-title {
251
+ font-family: var(--font-display);
252
+ font-size: 1.4rem;
253
+ font-weight: 600;
254
+ color: var(--text-dark);
255
+ margin-bottom: 0.8rem;
256
+ text-align: center;
257
+ }
258
+
259
+ .card-description {
260
+ font-family: var(--font-primary);
261
+ font-size: 0.95rem;
262
+ color: var(--text-secondary);
263
+ line-height: 1.6;
264
+ text-align: center;
265
+ margin-bottom: 1.5rem;
266
+ font-weight: 400;
267
+ }
268
+
269
+ /* Item Cards */
270
+ .item-card {
271
+ background: var(--card-bg);
272
+ border-radius: 15px;
273
+ box-shadow: 0 6px 24px var(--shadow-light);
274
+ overflow: hidden;
275
+ transition: all 0.3s ease;
276
+ margin-bottom: 1.5rem;
277
+ border: 1px solid var(--border-color);
278
+ }
279
+
280
+ .item-card:hover {
281
+ transform: translateY(-4px);
282
+ box-shadow: 0 12px 32px var(--shadow-medium);
283
+ border-color: var(--primary-blue);
284
+ }
285
+
286
+ .item-image-container {
287
+ position: relative;
288
+ overflow: hidden;
289
+ height: 180px;
290
+ }
291
+
292
+ .item-image-container img {
293
+ width: 100%;
294
+ height: 100%;
295
+ object-fit: cover;
296
+ transition: transform 0.3s ease;
297
+ }
298
+
299
+ .item-card:hover .item-image-container img {
300
+ transform: scale(1.03);
301
+ }
302
+
303
+ /* Custom Buttons with Poppins */
304
+ .stButton > button {
305
+ background: linear-gradient(135deg, var(--primary-blue), var(--secondary-blue));
306
+ color: white;
307
+ border: none;
308
+ border-radius: 25px;
309
+ padding: 0.7rem 2rem;
310
+ font-family: var(--font-primary);
311
+ font-weight: 500;
312
+ font-size: 0.95rem;
313
+ transition: all 0.3s ease;
314
+ box-shadow: 0 4px 16px var(--shadow-light);
315
+ width: 100%;
316
+ }
317
+
318
+ .stButton > button:hover {
319
+ transform: translateY(-2px);
320
+ box-shadow: 0 6px 20px var(--shadow-medium);
321
+ background: linear-gradient(135deg, var(--secondary-blue), var(--primary-blue));
322
+ }
323
+
324
+ /* Navigation Buttons */
325
+ .nav-button, div[data-testid="column"]:first-child .stButton > button {
326
+ background: var(--surface-bg) !important;
327
+ color: var(--text-primary) !important;
328
+ border-radius: 20px !important;
329
+ padding: 0.4rem 1rem !important;
330
+ font-family: var(--font-primary) !important;
331
+ font-weight: 500 !important;
332
+ font-size: 0.85rem !important;
333
+ border: 1px solid var(--border-color) !important;
334
+ transition: all 0.3s ease !important;
335
+ margin-bottom: 1rem !important;
336
+ width: auto !important;
337
+ min-width: 120px !important;
338
+ }
339
+
340
+ .nav-button:hover, div[data-testid="column"]:first-child .stButton > button:hover {
341
+ background: var(--primary-blue) !important;
342
+ color: white !important;
343
+ transform: translateX(-4px) !important;
344
+ border-color: var(--primary-blue) !important;
345
+ }
346
+
347
+ /* Hero Section - Updated for light theme */
348
+ .hero-section {
349
+ background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end));
350
+ padding: 4rem 2rem;
351
+ margin: -1rem -1rem 3rem -1rem;
352
+ text-align: center;
353
+ border-radius: 0 0 30px 30px;
354
+ border-bottom: 2px solid var(--border-color);
355
+ margin-top: -1rem !important;
356
+ }
357
+
358
+ .hero-subtitle {
359
+ font-family: var(--font-primary);
360
+ font-size: 1.2rem;
361
+ margin-top: 1rem;
362
+ font-weight: 400;
363
+ color: white;
364
+ }
365
+
366
+ /* Item Detail Styles */
367
+ .item-detail-container {
368
+ background: var(--card-bg);
369
+ border-radius: 20px;
370
+ padding: 2rem;
371
+ margin: 2rem 0;
372
+ box-shadow: 0 8px 32px var(--shadow-light);
373
+ border: 1px solid var(--border-color);
374
+ }
375
+
376
+ .item-title {
377
+ font-family: var(--font-display);
378
+ font-size: 2.8rem;
379
+ font-weight: 700;
380
+ color: var(--text-dark);
381
+ text-align: center;
382
+ margin-bottom: 2rem;
383
+ line-height: 1.2;
384
+ }
385
+
386
+ .item-section-title {
387
+ font-family: var(--font-display);
388
+ font-size: 1.6rem;
389
+ font-weight: 600;
390
+ color: var(--text-dark);
391
+ margin: 2rem 0 1rem 0;
392
+ border-bottom: 2px solid var(--primary-blue);
393
+ padding-bottom: 0.5rem;
394
+ }
395
+
396
+ .item-content {
397
+ font-family: var(--font-primary);
398
+ font-size: 1rem;
399
+ line-height: 1.7;
400
+ color: var(--text-secondary);
401
+ margin-bottom: 1.5rem;
402
+ font-weight: 400;
403
+ }
404
+
405
+ /* Image Gallery */
406
+ .image-gallery {
407
+ margin: 2rem 0;
408
+ }
409
+
410
+ .gallery-image {
411
+ border-radius: 15px;
412
+ box-shadow: 0 6px 24px var(--shadow-light);
413
+ transition: transform 0.3s ease;
414
+ margin-bottom: 1rem;
415
+ }
416
+
417
+ .gallery-image:hover {
418
+ transform: scale(1.02);
419
+ }
420
+
421
+ /* Featured Cards */
422
+ .featured-card {
423
+ background: linear-gradient(135deg, var(--card-bg), var(--surface-bg));
424
+ border: 2px solid var(--highlight-color);
425
+ border-radius: 20px;
426
+ box-shadow: 0 8px 32px rgba(255, 152, 0, 0.2);
427
+ overflow: hidden;
428
+ transition: all 0.3s ease;
429
+ margin-bottom: 2rem;
430
+ position: relative;
431
+ }
432
+
433
+ .featured-card:hover {
434
+ transform: translateY(-8px);
435
+ box-shadow: 0 16px 48px rgba(255, 152, 0, 0.3);
436
+ }
437
+
438
+ /* Compact Navigation Button Styles */
439
+ .compact-nav-button button {
440
+ background: var(--surface-bg) !important;
441
+ color: var(--text-primary) !important;
442
+ border-radius: 12px !important;
443
+ padding: 0.3rem 0.6rem !important;
444
+ font-family: var(--font-primary) !important;
445
+ font-size: 0.75rem !important;
446
+ font-weight: 500 !important;
447
+ border: 1px solid var(--border-color) !important;
448
+ width: auto !important;
449
+ min-width: 80px !important;
450
+ max-width: 90px !important;
451
+ transition: all 0.3s ease !important;
452
+ margin: 0 !important;
453
+ }
454
+
455
+ .compact-nav-button button:hover {
456
+ background: var(--primary-blue) !important;
457
+ color: white !important;
458
+ transform: translateX(-1px) !important;
459
+ border-color: var(--primary-blue) !important;
460
+ }
461
+
462
+ .compact-nav-button {
463
+ text-align: left !important;
464
+ margin-bottom: 1rem !important;
465
+ }
466
+
467
+ /* Override Streamlit default styles for light theme */
468
+ .stSelectbox > div > div {
469
+ background-color: var(--card-bg);
470
+ color: var(--text-dark);
471
+ border-color: var(--border-color);
472
+ font-family: var(--font-primary);
473
+ }
474
+
475
+ .stSelectbox > div > div:hover {
476
+ border-color: var(--primary-blue);
477
+ }
478
+
479
+ /* Info boxes and containers */
480
+ div[data-testid="stContainer"] > div {
481
+ background-color: transparent;
482
+ }
483
+
484
+ /* All text elements use Poppins by default */
485
+ .stMarkdown, .stText, p, div, span, h1, h2, h3, h4, h5, h6 {
486
+ font-family: var(--font-primary);
487
+ }
488
+
489
+ /* Specific heading overrides for display font */
490
+ h1, .stMarkdown h1 {
491
+ font-family: var(--font-display);
492
+ font-weight: 700;
493
+ }
494
+
495
+ h2, .stMarkdown h2 {
496
+ font-family: var(--font-display);
497
+ font-weight: 600;
498
+ }
499
+
500
+ h3, .stMarkdown h3 {
501
+ font-family: var(--font-primary);
502
+ font-weight: 700;
503
+ }
504
+
505
+ h4, h5, h6, .stMarkdown h4, .stMarkdown h5, .stMarkdown h6 {
506
+ font-family: var(--font-primary);
507
+ font-weight: 600;
508
+ }
509
+
510
+ /* Body text and paragraphs */
511
+ p, .stMarkdown p, div, span, li {
512
+ font-family: var(--font-primary);
513
+ font-weight: 400;
514
+ }
515
+
516
+ /* Responsive adjustments */
517
+ @media (max-width: 768px) {
518
+ .main-title {
519
+ font-size: 2.5rem;
520
+ }
521
+
522
+ .section-title {
523
+ font-size: 2rem;
524
+ }
525
+
526
+ .item-title {
527
+ font-size: 2.2rem;
528
+ }
529
+
530
+ .hero-section {
531
+ padding: 3rem 1rem;
532
+ }
533
+ }
534
+
535
+ /* Custom scrollbar for light theme */
536
+ ::-webkit-scrollbar {
537
+ width: 8px;
538
+ }
539
+
540
+ ::-webkit-scrollbar-track {
541
+ background: var(--light-bg);
542
+ }
543
+
544
+ ::-webkit-scrollbar-thumb {
545
+ background: var(--primary-blue);
546
+ border-radius: 4px;
547
+ }
548
+
549
+ ::-webkit-scrollbar-thumb:hover {
550
+ background: var(--secondary-blue);
551
+ }
552
+
553
+ /* Loading animation */
554
+ .loading-spinner {
555
+ display: inline-block;
556
+ width: 20px;
557
+ height: 20px;
558
+ border: 3px solid rgba(30, 136, 229, 0.3);
559
+ border-radius: 50%;
560
+ border-top-color: var(--primary-blue);
561
+ animation: spin 1s ease-in-out infinite;
562
+ }
563
+
564
+ @keyframes spin {
565
+ to { transform: rotate(360deg); }
566
+ }
567
+
568
+ /* Success/Info styling for light theme */
569
+ .stAlert {
570
+ border-radius: 15px;
571
+ border-left: 4px solid var(--primary-blue);
572
+ background-color: var(--surface-bg);
573
+ color: var(--text-dark);
574
+ font-family: var(--font-primary);
575
+ }
576
+
577
+ /* Additional light theme improvements */
578
+ .stExpander {
579
+ background-color: var(--card-bg);
580
+ border: 1px solid var(--border-color);
581
+ border-radius: 10px;
582
+ }
583
+
584
+ .stExpander summary {
585
+ color: var(--text-dark);
586
+ font-family: var(--font-primary);
587
+ font-weight: 600;
588
+ }
589
+
590
+ /* Override any remaining backgrounds */
591
+ div[data-testid="column"] > div {
592
+ background-color: transparent;
593
+ }
594
+
595
+ /* Statistics cards styling for light theme */
596
+ .stats-card {
597
+ background: var(--card-bg);
598
+ border: 1px solid var(--border-color);
599
+ color: var(--text-dark);
600
+ box-shadow: 0 4px 16px var(--shadow-light);
601
+ font-family: var(--font-primary);
602
+ }
603
+
604
+ .stats-card h3 {
605
+ color: var(--highlight-color);
606
+ font-family: var(--font-primary);
607
+ font-weight: 700;
608
+ }
609
+
610
+ .stats-card h4 {
611
+ color: var(--text-dark);
612
+ font-family: var(--font-primary);
613
+ font-weight: 600;
614
+ }
615
+
616
+ .stats-card p {
617
+ color: var(--text-secondary);
618
+ font-family: var(--font-primary);
619
+ font-weight: 400;
620
+ }
621
+
622
+ /* Light theme specific adjustments */
623
+ .stApp {
624
+ background-color: var(--light-bg);
625
+ font-family: var(--font-primary);
626
+ }
627
+
628
+ /* Text inputs and form elements */
629
+ .stTextInput > div > div > input {
630
+ background-color: var(--card-bg);
631
+ color: var(--text-dark);
632
+ border-color: var(--border-color);
633
+ font-family: var(--font-primary);
634
+ }
635
+
636
+ .stTextInput > div > div > input:focus {
637
+ border-color: var(--primary-blue);
638
+ box-shadow: 0 0 0 2px rgba(30, 136, 229, 0.2);
639
+ }
640
+
641
+ /* Dataframe and table styling */
642
+ .stDataFrame {
643
+ background-color: var(--card-bg);
644
+ border: 1px solid var(--border-color);
645
+ border-radius: 10px;
646
+ font-family: var(--font-primary);
647
+ }
648
+
649
+ /* Warning and error messages */
650
+ .stWarning {
651
+ background-color: rgba(255, 193, 7, 0.1);
652
+ color: #856404;
653
+ border-left: 4px solid #ffc107;
654
+ font-family: var(--font-primary);
655
+ }
656
+
657
+ .stError {
658
+ background-color: rgba(220, 53, 69, 0.1);
659
+ color: #721c24;
660
+ border-left: 4px solid #dc3545;
661
+ font-family: var(--font-primary);
662
+ }
663
+
664
+ .stSuccess {
665
+ background-color: rgba(40, 167, 69, 0.1);
666
+ color: #155724;
667
+ border-left: 4px solid #28a745;
668
+ font-family: var(--font-primary);
669
+ }
670
+
671
+ .stInfo {
672
+ background-color: rgba(30, 136, 229, 0.1);
673
+ color: var(--text-primary);
674
+ border-left: 4px solid var(--primary-blue);
675
+ font-family: var(--font-primary);
676
+ }
677
+
678
+ /* Enhanced visual hierarchy with light blue gradients */
679
+ .gradient-bg-light {
680
+ background: linear-gradient(135deg, #E3F2FD, #BBDEFB);
681
+ }
682
+
683
+ .gradient-bg-medium {
684
+ background: linear-gradient(135deg, #BBDEFB, #90CAF9);
685
+ }
686
+
687
+ .gradient-text {
688
+ background: linear-gradient(135deg, var(--primary-blue), var(--secondary-blue));
689
+ -webkit-background-clip: text;
690
+ -webkit-text-fill-color: transparent;
691
+ background-clip: text;
692
+ font-family: var(--font-primary);
693
+ font-weight: 700;
694
+ }
695
+
696
+ /* Hover effects for better interactivity */
697
+ .hover-lift {
698
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
699
+ }
700
+
701
+ .hover-lift:hover {
702
+ transform: translateY(-2px);
703
+ box-shadow: 0 8px 25px var(--shadow-medium);
704
+ }
705
+
706
+ /* Utility classes for Poppins font variants */
707
+ .text-regular {
708
+ font-family: "poppins", sans-serif;
709
+ font-weight: 400;
710
+ font-style: normal;
711
+ }
712
+
713
+ .text-italic {
714
+ font-family: "poppins", sans-serif;
715
+ font-weight: 400;
716
+ font-style: italic;
717
+ }
718
+
719
+ .text-bold {
720
+ font-family: "poppins", sans-serif;
721
+ font-weight: 700;
722
+ font-style: normal;
723
+ }
724
+
725
+ .text-bold-italic {
726
+ font-family: "poppins", sans-serif;
727
+ font-weight: 700;
728
+ font-style: italic;
729
+ }
730
+ </style>
731
+ """,
732
+ unsafe_allow_html=True,
733
+ )
734
+
735
+
736
+ def main():
737
+ # Configure page
738
+ enhanced_config = {
739
+ **PAGE_CONFIG,
740
+ "page_title": "🎨 Art & Culture Explorer",
741
+ "page_icon": "🎨",
742
+ }
743
+ st.set_page_config(**enhanced_config)
744
+
745
+ # Apply custom CSS
746
+ apply_custom_css()
747
+
748
+ # Initialize session state
749
+ initialize_session_state()
750
+
751
+ # Apply scroll fix and page positioning
752
+ from utils.session import (
753
+ inject_scroll_fix_css,
754
+ add_page_transition_effect,
755
+ enhanced_scroll_to_top,
756
+ )
757
+
758
+ inject_scroll_fix_css()
759
+ add_page_transition_effect()
760
+ enhanced_scroll_to_top()
761
+
762
+ # Load data
763
+ app_data = load_all_data_streamlit()
764
+
765
+ if app_data is None:
766
+ st.error("Unable to load application data. Please check your data directory.")
767
+ st.stop()
768
+
769
+ # Sync session state with URL parameters
770
+ router.sync_session_from_url(app_data)
771
+
772
+ # Route to appropriate page based on session state
773
+ if st.session_state.view == "home":
774
+ home.render(app_data)
775
+ elif st.session_state.view == "category_detail":
776
+ category_detail.render(app_data)
777
+ elif st.session_state.view == "item_detail":
778
+ item_detail.render(app_data)
779
+
780
+
781
+ if __name__ == "__main__":
782
+ main()
watch_and_restart.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import subprocess
2
+ import time
3
+ import os
4
+ import signal
5
+
6
+ process = None
7
+
8
+
9
+ def restart():
10
+ global process
11
+ if process:
12
+ process.terminate()
13
+ process.wait()
14
+ process = subprocess.Popen(["streamlit", "run", "main.py"])
15
+
16
+
17
+ try:
18
+ restart()
19
+ from watchdog.observers import Observer
20
+ from watchdog.events import FileSystemEventHandler
21
+
22
+ class ChangeHandler(FileSystemEventHandler):
23
+ def on_modified(self, event):
24
+ if event.src_path.endswith(".py"):
25
+ print(f"File changed: {event.src_path}")
26
+ restart()
27
+
28
+ event_handler = ChangeHandler()
29
+ observer = Observer()
30
+ observer.schedule(event_handler, path=".", recursive=True)
31
+ observer.start()
32
+
33
+ while True:
34
+ time.sleep(1)
35
+
36
+ except KeyboardInterrupt:
37
+ if process:
38
+ process.terminate()
39
+ observer.stop()
40
+ observer.join()