Files changed (38) hide show
  1. booknap project/.vscode/launch.json +30 -0
  2. booknap project/DATASET_GUIDE.md +327 -0
  3. booknap project/README.md +134 -0
  4. booknap project/animated-tabs.css +441 -0
  5. booknap project/animated-tabs.html +658 -0
  6. booknap project/animated-tabs.js +143 -0
  7. booknap project/app.py +237 -0
  8. booknap project/assets/audio/7-habits-summary.mp3 +1 -0
  9. booknap project/assets/audio/atomic-habits-summary.mp3 +1 -0
  10. booknap project/assets/audio/rich-dad-poor-dad-summary.mp3 +1 -0
  11. booknap project/assets/audio/thinking-fast-slow-summary.mp3 +1 -0
  12. booknap project/assets/covers/7-habits.jpg +48 -0
  13. booknap project/assets/covers/7-habits.svg +48 -0
  14. booknap project/assets/covers/atomic-habits.jpg +36 -0
  15. booknap project/assets/covers/atomic-habits.svg +36 -0
  16. booknap project/assets/covers/jane-austen-portrait.svg +77 -0
  17. booknap project/assets/covers/rich-dad-poor-dad.jpg +40 -0
  18. booknap project/assets/covers/rich-dad-poor-dad.svg +40 -0
  19. booknap project/assets/covers/start-with-why.svg +51 -0
  20. booknap project/assets/covers/thinking-fast-slow.jpg +38 -0
  21. booknap project/assets/covers/thinking-fast-slow.svg +38 -0
  22. booknap project/assets/covers/zero-to-one.svg +49 -0
  23. booknap project/blog.html +612 -0
  24. booknap project/books.html +1072 -0
  25. booknap project/business-leaders.html +376 -0
  26. booknap project/community-section.html +285 -0
  27. booknap project/data/news.json +86 -0
  28. booknap project/database_schema.sql +21 -0
  29. booknap project/json-blog.html +272 -0
  30. booknap project/login.html +120 -0
  31. booknap project/pricing.html +521 -0
  32. booknap project/requirements.txt +8 -0
  33. booknap project/script.js +1 -0
  34. booknap project/setup_database.py +102 -0
  35. booknap project/signup.html +371 -0
  36. booknap project/static-blog.html +222 -0
  37. booknap project/styles.css +973 -0
  38. booknap project/test_connection.py +49 -0
booknap project/.vscode/launch.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "name": "Launch Edge",
9
+ "request": "launch",
10
+ "type": "msedge",
11
+ "url": "http://localhost:8080",
12
+ "webRoot": "${workspaceFolder}"
13
+ },
14
+ {
15
+ "type": "vscode-edge-devtools.debug",
16
+ "request": "attach",
17
+ "name": "Attach to Microsoft Edge and open the Edge DevTools",
18
+ "url": "http://localhost:8080",
19
+ "webRoot": "${workspaceFolder}"
20
+ },
21
+
22
+
23
+ {
24
+ "type": "chrome",
25
+ "request": "launch",
26
+ "name": "Open book.html",
27
+ "file": "/home/aakash/Documents/booknap project/book.html"
28
+ }
29
+ ]
30
+ }
booknap project/DATASET_GUIDE.md ADDED
@@ -0,0 +1,327 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # How to Use Datasets in Web Pages - Complete Guide
2
+
3
+ ## 🎯 **Overview**
4
+
5
+ There are several ways to integrate datasets into web pages, each with different use cases and complexity levels.
6
+
7
+ ## πŸ“Š **Method 1: Static Data (Simplest)**
8
+
9
+ **Best for:** Small datasets, static content, simple applications
10
+
11
+ ### How it works:
12
+ - Data is embedded directly in JavaScript
13
+ - No server required
14
+ - Works with static hosting (GitHub Pages, Netlify, etc.)
15
+
16
+ ### Example:
17
+ ```javascript
18
+ const dataset = [
19
+ { title: "Article 1", content: "..." },
20
+ { title: "Article 2", content: "..." }
21
+ ];
22
+ ```
23
+
24
+ ### Files created:
25
+ - `static-blog.html` - Complete example with embedded dataset
26
+
27
+ ### Pros:
28
+ - βœ… No server needed
29
+ - βœ… Fast loading
30
+ - βœ… Simple to implement
31
+ - βœ… Works offline
32
+
33
+ ### Cons:
34
+ - ❌ Limited to small datasets
35
+ - ❌ Data can't be updated without code changes
36
+ - ❌ No real-time updates
37
+
38
+ ---
39
+
40
+ ## πŸ“„ **Method 2: External JSON Files**
41
+
42
+ **Best for:** Medium datasets, content that updates occasionally
43
+
44
+ ### How it works:
45
+ - Data stored in separate JSON files
46
+ - Loaded via `fetch()` API
47
+ - Can be updated without changing code
48
+
49
+ ### Example:
50
+ ```javascript
51
+ async function loadData() {
52
+ const response = await fetch('data/dataset.json');
53
+ const data = await response.json();
54
+ displayData(data);
55
+ }
56
+ ```
57
+
58
+ ### Files created:
59
+ - `data/news.json` - Sample dataset
60
+ - `json-blog.html` - Complete example with JSON loading
61
+
62
+ ### Pros:
63
+ - βœ… Separates data from code
64
+ - βœ… Easy to update content
65
+ - βœ… No server required
66
+ - βœ… Good for static sites
67
+
68
+ ### Cons:
69
+ - ❌ Limited by browser CORS policies
70
+ - ❌ No real-time updates
71
+ - ❌ File size limitations
72
+
73
+ ---
74
+
75
+ ## πŸ–₯️ **Method 3: Backend API (Advanced)**
76
+
77
+ **Best for:** Large datasets, real-time updates, complex applications
78
+
79
+ ### How it works:
80
+ - Python/Node.js server processes data
81
+ - REST API endpoints serve data
82
+ - Can integrate with databases
83
+
84
+ ### Example:
85
+ ```python
86
+ from flask import Flask, jsonify
87
+ import pandas as pd
88
+
89
+ app = Flask(__name__)
90
+
91
+ @app.route('/api/data')
92
+ def get_data():
93
+ df = pd.read_csv('dataset.csv')
94
+ return jsonify(df.to_dict('records'))
95
+ ```
96
+
97
+ ### Files created:
98
+ - `app.py` - Flask backend with Kaggle dataset
99
+ - `requirements.txt` - Python dependencies
100
+
101
+ ### Pros:
102
+ - βœ… Handle large datasets
103
+ - βœ… Real-time updates
104
+ - βœ… Database integration
105
+ - βœ… Data processing capabilities
106
+
107
+ ### Cons:
108
+ - ❌ Requires server setup
109
+ - ❌ More complex
110
+ - ❌ Hosting costs
111
+
112
+ ---
113
+
114
+ ## πŸ”§ **Method 4: Database Integration**
115
+
116
+ **Best for:** Production applications, user-generated content
117
+
118
+ ### Options:
119
+ 1. **SQLite** - Lightweight, file-based
120
+ 2. **PostgreSQL** - Full-featured, scalable
121
+ 3. **MongoDB** - NoSQL, flexible
122
+ 4. **Firebase** - Cloud-hosted, real-time
123
+
124
+ ### Example with SQLite:
125
+ ```python
126
+ import sqlite3
127
+
128
+ def get_articles():
129
+ conn = sqlite3.connect('blog.db')
130
+ cursor = conn.cursor()
131
+ cursor.execute('SELECT * FROM articles')
132
+ return cursor.fetchall()
133
+ ```
134
+
135
+ ---
136
+
137
+ ## πŸš€ **Quick Start Guide**
138
+
139
+ ### For Beginners (Static Data):
140
+ 1. Open `static-blog.html`
141
+ 2. Replace the `newsDataset` array with your data
142
+ 3. Open in browser - that's it!
143
+
144
+ ### For Intermediate (JSON Files):
145
+ 1. Create your data in `data/your-data.json`
146
+ 2. Open `json-blog.html`
147
+ 3. Update the fetch path to your JSON file
148
+ 4. Open in browser
149
+
150
+ ### For Advanced (Backend):
151
+ 1. Install Python dependencies: `pip install -r requirements.txt`
152
+ 2. Set up Kaggle API (if using Kaggle datasets)
153
+ 3. Run: `python app.py`
154
+ 4. Open `http://localhost:5000`
155
+
156
+ ---
157
+
158
+ ## πŸ“‹ **Dataset Formats**
159
+
160
+ ### JSON (Recommended):
161
+ ```json
162
+ {
163
+ "articles": [
164
+ {
165
+ "title": "Article Title",
166
+ "content": "Article content...",
167
+ "date": "2024-01-15",
168
+ "tags": ["tag1", "tag2"]
169
+ }
170
+ ]
171
+ }
172
+ ```
173
+
174
+ ### CSV:
175
+ ```csv
176
+ title,content,date,tags
177
+ "Article 1","Content 1","2024-01-15","tag1,tag2"
178
+ "Article 2","Content 2","2024-01-16","tag3"
179
+ ```
180
+
181
+ ### Excel:
182
+ - Convert to CSV or JSON for web use
183
+ - Use Python pandas for processing
184
+
185
+ ---
186
+
187
+ ## 🎨 **Integration Examples**
188
+
189
+ ### Search Functionality:
190
+ ```javascript
191
+ function searchData(query) {
192
+ return dataset.filter(item =>
193
+ item.title.toLowerCase().includes(query.toLowerCase())
194
+ );
195
+ }
196
+ ```
197
+
198
+ ### Filtering:
199
+ ```javascript
200
+ function filterByCategory(category) {
201
+ return dataset.filter(item => item.category === category);
202
+ }
203
+ ```
204
+
205
+ ### Sorting:
206
+ ```javascript
207
+ function sortByDate() {
208
+ return dataset.sort((a, b) => new Date(b.date) - new Date(a.date));
209
+ }
210
+ ```
211
+
212
+ ### Pagination:
213
+ ```javascript
214
+ function getPage(page, itemsPerPage) {
215
+ const start = page * itemsPerPage;
216
+ return dataset.slice(start, start + itemsPerPage);
217
+ }
218
+ ```
219
+
220
+ ---
221
+
222
+ ## πŸ” **Popular Dataset Sources**
223
+
224
+ ### Free Datasets:
225
+ - **Kaggle** - `kagglehub.dataset_download("dataset-name")`
226
+ - **GitHub** - Raw JSON/CSV files
227
+ - **Open Data Portals** - Government data
228
+ - **APIs** - News APIs, weather APIs, etc.
229
+
230
+ ### Creating Your Own:
231
+ 1. **Google Sheets** οΏ½οΏ½ Export as CSV/JSON
232
+ 2. **Excel** β†’ Save as CSV
233
+ 3. **Database** β†’ Export queries
234
+ 4. **Web Scraping** β†’ Collect data programmatically
235
+
236
+ ---
237
+
238
+ ## πŸ› οΈ **Tools & Libraries**
239
+
240
+ ### Frontend:
241
+ - **Vanilla JavaScript** - Built-in fetch API
242
+ - **Axios** - HTTP client
243
+ - **D3.js** - Data visualization
244
+ - **Chart.js** - Charts and graphs
245
+
246
+ ### Backend:
247
+ - **Flask** - Python web framework
248
+ - **Express.js** - Node.js framework
249
+ - **Pandas** - Data processing
250
+ - **SQLAlchemy** - Database ORM
251
+
252
+ ---
253
+
254
+ ## πŸ“± **Mobile Considerations**
255
+
256
+ ### Responsive Design:
257
+ ```css
258
+ @media (max-width: 768px) {
259
+ .blog-grid {
260
+ grid-template-columns: 1fr;
261
+ }
262
+ }
263
+ ```
264
+
265
+ ### Performance:
266
+ - Lazy loading for large datasets
267
+ - Image optimization
268
+ - Data caching
269
+ - Progressive loading
270
+
271
+ ---
272
+
273
+ ## πŸ”’ **Security & Privacy**
274
+
275
+ ### Best Practices:
276
+ - Validate all data inputs
277
+ - Sanitize data before display
278
+ - Use HTTPS for API calls
279
+ - Implement rate limiting
280
+ - Handle errors gracefully
281
+
282
+ ### CORS Issues:
283
+ ```python
284
+ # Flask CORS setup
285
+ from flask_cors import CORS
286
+ app = Flask(__name__)
287
+ CORS(app)
288
+ ```
289
+
290
+ ---
291
+
292
+ ## πŸ“ˆ **Performance Tips**
293
+
294
+ 1. **Compress data** - Use gzip compression
295
+ 2. **Cache responses** - Store data locally
296
+ 3. **Lazy load** - Load data as needed
297
+ 4. **Pagination** - Load data in chunks
298
+ 5. **CDN** - Use content delivery networks
299
+
300
+ ---
301
+
302
+ ## 🎯 **Choose Your Method**
303
+
304
+ | Method | Dataset Size | Complexity | Real-time | Hosting |
305
+ |--------|-------------|------------|-----------|---------|
306
+ | Static | < 1MB | Low | No | Static |
307
+ | JSON | < 10MB | Low | No | Static |
308
+ | API | Any | Medium | Yes | Server |
309
+ | Database | Any | High | Yes | Server |
310
+
311
+ ---
312
+
313
+ ## πŸš€ **Next Steps**
314
+
315
+ 1. **Start with static data** if you're new to web development
316
+ 2. **Move to JSON files** when you need more data
317
+ 3. **Add a backend** when you need real-time updates
318
+ 4. **Integrate a database** for production applications
319
+
320
+ Remember: Start simple and scale up as needed!
321
+
322
+
323
+
324
+
325
+
326
+
327
+
booknap project/README.md ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Booknap - Book Summary Platform
2
+
3
+ A modern web application for accessing book summaries, with user authentication and a beautiful UI.
4
+
5
+ ## Features
6
+
7
+ - **User Authentication**: Login and signup functionality
8
+ - **Book Summaries**: Access to various book summaries and insights
9
+ - **Responsive Design**: Modern, mobile-friendly interface
10
+ - **Database Integration**: PostgreSQL backend with user management
11
+ - **Blog System**: Integrated blog with dynamic content
12
+
13
+ ## Pages
14
+
15
+ - **Home** (`books.html`): Main landing page with book summaries
16
+ - **Login** (`login.html`): User authentication
17
+ - **Signup** (`signup.html`): User registration
18
+ - **Pricing** (`pricing.html`): Subscription plans
19
+ - **Blog** (`blog.html`): Blog articles and insights
20
+
21
+ ## Setup Instructions
22
+
23
+ ### 1. Install Dependencies
24
+
25
+ ```bash
26
+ pip install -r requirements.txt
27
+ ```
28
+
29
+ ### 2. Database Setup
30
+
31
+ #### Option A: Using Python Scripts (Recommended)
32
+ 1. Set your database password:
33
+ ```bash
34
+ export DATABASE_URL="postgresql://postgres:YOUR_PASSWORD@db.ckrqyjfdifjbsuuofegd.supabase.co:5432/postgres"
35
+ ```
36
+ 2. Run the database setup script:
37
+ ```bash
38
+ python setup_database.py
39
+ ```
40
+
41
+ #### Option B: Using psql Command
42
+ 1. Install PostgreSQL client: `sudo dnf install postgresql` (Fedora/RHEL)
43
+ 2. Run the schema:
44
+ ```bash
45
+ PGPASSWORD=YOUR_PASSWORD psql -h db.ckrqyjfdifjbsuuofegd.supabase.co -p 5432 -d postgres -U postgres -f database_schema.sql
46
+ ```
47
+
48
+ **Note**: Replace `YOUR_PASSWORD` with your actual Supabase database password.
49
+
50
+ ### 3. Environment Variables
51
+
52
+ Set your database connection string with your Supabase credentials:
53
+ ```bash
54
+ export DATABASE_URL="postgresql://postgres:YOUR_SUPABASE_PASSWORD@db.ckrqyjfdifjbsuuofegd.supabase.co:5432/postgres"
55
+ ```
56
+
57
+ **Important**: Replace `YOUR_SUPABASE_PASSWORD` with your actual Supabase database password.
58
+
59
+ ### 4. Run the Application
60
+
61
+ ```bash
62
+ python app.py
63
+ ```
64
+
65
+ The application will be available at `http://localhost:5000`
66
+
67
+ ## Database Schema
68
+
69
+ The application uses a simple users table:
70
+ - `id`: Primary key
71
+ - `full_name`: User's full name
72
+ - `email`: Unique email address
73
+ - `password`: User password (should be hashed in production)
74
+ - `created_at`: Account creation timestamp
75
+ - `updated_at`: Last update timestamp
76
+
77
+ ## Security Notes
78
+
79
+ ⚠️ **Important**: This is a demo implementation. For production use:
80
+
81
+ 1. Hash passwords using bcrypt or similar
82
+ 2. Implement proper session management
83
+ 3. Add CSRF protection
84
+ 4. Use HTTPS
85
+ 5. Implement rate limiting
86
+ 6. Add input validation and sanitization
87
+
88
+ ## File Structure
89
+
90
+ ```
91
+ β”œβ”€β”€ app.py # Flask backend
92
+ β”œβ”€β”€ requirements.txt # Python dependencies
93
+ β”œβ”€β”€ database_schema.sql # Database setup
94
+ β”œβ”€β”€ setup_database.py # Database setup script
95
+ β”œβ”€β”€ test_connection.py # Database connection test
96
+ β”œβ”€β”€ books.html # Home page
97
+ β”œβ”€β”€ login.html # Login page
98
+ β”œβ”€β”€ signup.html # Signup page
99
+ β”œβ”€β”€ pricing.html # Pricing page
100
+ β”œβ”€β”€ blog.html # Blog page
101
+ β”œβ”€β”€ static-blog.html # Static blog demo
102
+ β”œβ”€β”€ community-section.html # Community section component
103
+ └── styles.css # Global styles
104
+ ```
105
+
106
+ ## API Endpoints
107
+
108
+ - `POST /login` - User authentication
109
+ - `POST /signup` - User registration
110
+ - `GET /api/news` - News articles
111
+ - `GET /api/business-leaders` - Business insights
112
+ - `GET /api/dataset-info` - Dataset information
113
+
114
+ ## Development
115
+
116
+ To run in development mode:
117
+ ```bash
118
+ export FLASK_ENV=development
119
+ python app.py
120
+ ```
121
+
122
+ ## Contributing
123
+
124
+ 1. Fork the repository
125
+ 2. Create a feature branch
126
+ 3. Make your changes
127
+ 4. Test thoroughly
128
+ 5. Submit a pull request
129
+
130
+ ## License
131
+
132
+ This project is for educational purposes. Please ensure you have proper licenses for any content used.
133
+
134
+
booknap project/animated-tabs.css ADDED
@@ -0,0 +1,441 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Animated Tabs CSS - Blinkist Style */
2
+
3
+ /* Animated Tabs Section */
4
+ .animated-tabs-section {
5
+ padding: 6rem 0;
6
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
7
+ overflow: hidden;
8
+ min-height: 100vh;
9
+ display: flex;
10
+ align-items: center;
11
+ }
12
+
13
+ .tabs-container {
14
+ max-width: 1200px;
15
+ margin: 0 auto;
16
+ padding: 0 20px;
17
+ width: 100%;
18
+ }
19
+
20
+ .tabs-header {
21
+ text-align: center;
22
+ margin-bottom: 4rem;
23
+ }
24
+
25
+ .tabs-header h2 {
26
+ font-size: 3rem;
27
+ font-weight: 700;
28
+ color: #2d3748;
29
+ margin-bottom: 1rem;
30
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
31
+ -webkit-background-clip: text;
32
+ -webkit-text-fill-color: transparent;
33
+ background-clip: text;
34
+ }
35
+
36
+ .tabs-header p {
37
+ font-size: 1.2rem;
38
+ color: #4a5568;
39
+ max-width: 600px;
40
+ margin: 0 auto;
41
+ }
42
+
43
+ .tabs-wrapper {
44
+ display: flex;
45
+ flex-direction: column;
46
+ align-items: center;
47
+ gap: 3rem;
48
+ }
49
+
50
+ /* Tab Navigation */
51
+ .tabs-nav {
52
+ display: flex;
53
+ background: white;
54
+ border-radius: 50px;
55
+ padding: 0.5rem;
56
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
57
+ position: relative;
58
+ overflow: hidden;
59
+ }
60
+
61
+ .tab-button {
62
+ background: none;
63
+ border: none;
64
+ padding: 1rem 2rem;
65
+ border-radius: 40px;
66
+ font-size: 1rem;
67
+ font-weight: 600;
68
+ color: #4a5568;
69
+ cursor: pointer;
70
+ transition: all 0.3s ease;
71
+ position: relative;
72
+ z-index: 2;
73
+ white-space: nowrap;
74
+ display: flex;
75
+ align-items: center;
76
+ gap: 0.5rem;
77
+ }
78
+
79
+ .tab-button.active {
80
+ color: white;
81
+ }
82
+
83
+ .tab-button i {
84
+ font-size: 1.2rem;
85
+ }
86
+
87
+ .tab-slider {
88
+ position: absolute;
89
+ top: 0.5rem;
90
+ left: 0.5rem;
91
+ height: calc(100% - 1rem);
92
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
93
+ border-radius: 40px;
94
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
95
+ z-index: 1;
96
+ }
97
+
98
+ /* Tab Content */
99
+ .tabs-content {
100
+ width: 100%;
101
+ max-width: 1000px;
102
+ position: relative;
103
+ }
104
+
105
+ .tab-panel {
106
+ display: none;
107
+ animation: fadeInUp 0.6s ease-out;
108
+ }
109
+
110
+ .tab-panel.active {
111
+ display: block;
112
+ }
113
+
114
+ .tab-panel-content {
115
+ background: white;
116
+ border-radius: 20px;
117
+ padding: 3rem;
118
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
119
+ position: relative;
120
+ overflow: hidden;
121
+ }
122
+
123
+ .tab-panel-content::before {
124
+ content: '';
125
+ position: absolute;
126
+ top: 0;
127
+ left: 0;
128
+ right: 0;
129
+ height: 4px;
130
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
131
+ }
132
+
133
+ /* Tab-specific styles */
134
+ .read-tab {
135
+ display: grid;
136
+ grid-template-columns: 1fr 1fr;
137
+ gap: 3rem;
138
+ align-items: center;
139
+ }
140
+
141
+ .read-content h3 {
142
+ font-size: 2rem;
143
+ font-weight: 700;
144
+ color: #2d3748;
145
+ margin-bottom: 1rem;
146
+ }
147
+
148
+ .read-content p {
149
+ font-size: 1.1rem;
150
+ color: #4a5568;
151
+ line-height: 1.7;
152
+ margin-bottom: 2rem;
153
+ }
154
+
155
+ .read-features {
156
+ display: flex;
157
+ flex-direction: column;
158
+ gap: 1rem;
159
+ }
160
+
161
+ .read-feature {
162
+ display: flex;
163
+ align-items: center;
164
+ gap: 1rem;
165
+ padding: 1rem;
166
+ background: #f8fafc;
167
+ border-radius: 10px;
168
+ transition: all 0.3s ease;
169
+ }
170
+
171
+ .read-feature:hover {
172
+ background: #e2e8f0;
173
+ transform: translateX(10px);
174
+ }
175
+
176
+ .read-feature i {
177
+ font-size: 1.5rem;
178
+ color: #667eea;
179
+ width: 40px;
180
+ height: 40px;
181
+ display: flex;
182
+ align-items: center;
183
+ justify-content: center;
184
+ background: white;
185
+ border-radius: 50%;
186
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.2);
187
+ }
188
+
189
+ .read-feature-text h4 {
190
+ font-weight: 600;
191
+ color: #2d3748;
192
+ margin-bottom: 0.25rem;
193
+ }
194
+
195
+ .read-feature-text p {
196
+ font-size: 0.9rem;
197
+ color: #4a5568;
198
+ margin: 0;
199
+ }
200
+
201
+ .read-visual {
202
+ position: relative;
203
+ text-align: center;
204
+ }
205
+
206
+ .read-visual img {
207
+ max-width: 100%;
208
+ height: auto;
209
+ border-radius: 15px;
210
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
211
+ }
212
+
213
+ .listen-tab {
214
+ display: grid;
215
+ grid-template-columns: 1fr 1fr;
216
+ gap: 3rem;
217
+ align-items: center;
218
+ }
219
+
220
+ .listen-content h3 {
221
+ font-size: 2rem;
222
+ font-weight: 700;
223
+ color: #2d3748;
224
+ margin-bottom: 1rem;
225
+ }
226
+
227
+ .listen-content p {
228
+ font-size: 1.1rem;
229
+ color: #4a5568;
230
+ line-height: 1.7;
231
+ margin-bottom: 2rem;
232
+ }
233
+
234
+ .listen-features {
235
+ display: flex;
236
+ flex-direction: column;
237
+ gap: 1rem;
238
+ }
239
+
240
+ .listen-feature {
241
+ display: flex;
242
+ align-items: center;
243
+ gap: 1rem;
244
+ padding: 1rem;
245
+ background: #f8fafc;
246
+ border-radius: 10px;
247
+ transition: all 0.3s ease;
248
+ }
249
+
250
+ .listen-feature:hover {
251
+ background: #e2e8f0;
252
+ transform: translateX(10px);
253
+ }
254
+
255
+ .listen-feature i {
256
+ font-size: 1.5rem;
257
+ color: #667eea;
258
+ width: 40px;
259
+ height: 40px;
260
+ display: flex;
261
+ align-items: center;
262
+ justify-content: center;
263
+ background: white;
264
+ border-radius: 50%;
265
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.2);
266
+ }
267
+
268
+ .listen-feature-text h4 {
269
+ font-weight: 600;
270
+ color: #2d3748;
271
+ margin-bottom: 0.25rem;
272
+ }
273
+
274
+ .listen-feature-text p {
275
+ font-size: 0.9rem;
276
+ color: #4a5568;
277
+ margin: 0;
278
+ }
279
+
280
+ .listen-visual {
281
+ position: relative;
282
+ text-align: center;
283
+ }
284
+
285
+ .listen-visual img {
286
+ max-width: 100%;
287
+ height: auto;
288
+ border-radius: 15px;
289
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
290
+ }
291
+
292
+ .learn-tab {
293
+ text-align: center;
294
+ }
295
+
296
+ .learn-content h3 {
297
+ font-size: 2.5rem;
298
+ font-weight: 700;
299
+ color: #2d3748;
300
+ margin-bottom: 1.5rem;
301
+ }
302
+
303
+ .learn-content p {
304
+ font-size: 1.2rem;
305
+ color: #4a5568;
306
+ line-height: 1.7;
307
+ margin-bottom: 3rem;
308
+ max-width: 600px;
309
+ margin-left: auto;
310
+ margin-right: auto;
311
+ }
312
+
313
+ .learn-grid {
314
+ display: grid;
315
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
316
+ gap: 2rem;
317
+ margin-top: 3rem;
318
+ }
319
+
320
+ .learn-card {
321
+ background: #f8fafc;
322
+ border-radius: 15px;
323
+ padding: 2rem;
324
+ transition: all 0.3s ease;
325
+ border: 2px solid transparent;
326
+ }
327
+
328
+ .learn-card:hover {
329
+ background: white;
330
+ border-color: #667eea;
331
+ transform: translateY(-10px);
332
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
333
+ }
334
+
335
+ .learn-card i {
336
+ font-size: 3rem;
337
+ color: #667eea;
338
+ margin-bottom: 1rem;
339
+ }
340
+
341
+ .learn-card h4 {
342
+ font-size: 1.25rem;
343
+ font-weight: 600;
344
+ color: #2d3748;
345
+ margin-bottom: 1rem;
346
+ }
347
+
348
+ .learn-card p {
349
+ font-size: 1rem;
350
+ color: #4a5568;
351
+ line-height: 1.6;
352
+ margin: 0;
353
+ }
354
+
355
+ /* Animations */
356
+ @keyframes fadeInUp {
357
+ from {
358
+ opacity: 0;
359
+ transform: translateY(30px);
360
+ }
361
+ to {
362
+ opacity: 1;
363
+ transform: translateY(0);
364
+ }
365
+ }
366
+
367
+ @keyframes slideIn {
368
+ from {
369
+ opacity: 0;
370
+ transform: translateX(-30px);
371
+ }
372
+ to {
373
+ opacity: 1;
374
+ transform: translateX(0);
375
+ }
376
+ }
377
+
378
+ /* Responsive Design */
379
+ @media (max-width: 768px) {
380
+ .tabs-header h2 {
381
+ font-size: 2rem;
382
+ }
383
+
384
+ .tabs-nav {
385
+ flex-direction: column;
386
+ border-radius: 20px;
387
+ padding: 0.25rem;
388
+ }
389
+
390
+ .tab-button {
391
+ padding: 0.75rem 1.5rem;
392
+ font-size: 0.9rem;
393
+ }
394
+
395
+ .tab-slider {
396
+ display: none;
397
+ }
398
+
399
+ .tab-button.active {
400
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
401
+ color: white;
402
+ }
403
+
404
+ .read-tab,
405
+ .listen-tab {
406
+ grid-template-columns: 1fr;
407
+ gap: 2rem;
408
+ }
409
+
410
+ .tab-panel-content {
411
+ padding: 2rem;
412
+ }
413
+
414
+ .learn-grid {
415
+ grid-template-columns: 1fr;
416
+ }
417
+ }
418
+
419
+ @media (max-width: 480px) {
420
+ .tabs-header h2 {
421
+ font-size: 1.75rem;
422
+ }
423
+
424
+ .tabs-header p {
425
+ font-size: 1rem;
426
+ }
427
+
428
+ .tab-panel-content {
429
+ padding: 1.5rem;
430
+ }
431
+
432
+ .read-content h3,
433
+ .listen-content h3 {
434
+ font-size: 1.5rem;
435
+ }
436
+
437
+ .learn-content h3 {
438
+ font-size: 2rem;
439
+ }
440
+ }
441
+
booknap project/animated-tabs.html ADDED
@@ -0,0 +1,658 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>BookNap - Animated Tabs</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
9
+ <style>
10
+ /* Reset and Base Styles */
11
+ * {
12
+ margin: 0;
13
+ padding: 0;
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ body {
18
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
19
+ line-height: 1.6;
20
+ color: #333;
21
+ background-color: #f8fafc;
22
+ }
23
+
24
+ .container {
25
+ max-width: 1200px;
26
+ margin: 0 auto;
27
+ padding: 0 20px;
28
+ }
29
+
30
+ /* Animated Tabs Section - Blinkist Style */
31
+ .animated-tabs-section {
32
+ padding: 6rem 0;
33
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
34
+ overflow: hidden;
35
+ min-height: 100vh;
36
+ display: flex;
37
+ align-items: center;
38
+ }
39
+
40
+ .tabs-container {
41
+ max-width: 1200px;
42
+ margin: 0 auto;
43
+ padding: 0 20px;
44
+ width: 100%;
45
+ }
46
+
47
+ .tabs-header {
48
+ text-align: center;
49
+ margin-bottom: 4rem;
50
+ }
51
+
52
+ .tabs-header h2 {
53
+ font-size: 3rem;
54
+ font-weight: 700;
55
+ color: #2d3748;
56
+ margin-bottom: 1rem;
57
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
58
+ -webkit-background-clip: text;
59
+ -webkit-text-fill-color: transparent;
60
+ background-clip: text;
61
+ }
62
+
63
+ .tabs-header p {
64
+ font-size: 1.2rem;
65
+ color: #4a5568;
66
+ max-width: 600px;
67
+ margin: 0 auto;
68
+ }
69
+
70
+ .tabs-wrapper {
71
+ display: flex;
72
+ flex-direction: column;
73
+ align-items: center;
74
+ gap: 3rem;
75
+ }
76
+
77
+ .tabs-nav {
78
+ display: flex;
79
+ background: white;
80
+ border-radius: 50px;
81
+ padding: 0.5rem;
82
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
83
+ position: relative;
84
+ overflow: hidden;
85
+ }
86
+
87
+ .tab-button {
88
+ background: none;
89
+ border: none;
90
+ padding: 1rem 2rem;
91
+ border-radius: 40px;
92
+ font-size: 1rem;
93
+ font-weight: 600;
94
+ color: #4a5568;
95
+ cursor: pointer;
96
+ transition: all 0.3s ease;
97
+ position: relative;
98
+ z-index: 2;
99
+ white-space: nowrap;
100
+ display: flex;
101
+ align-items: center;
102
+ gap: 0.5rem;
103
+ }
104
+
105
+ .tab-button.active {
106
+ color: white;
107
+ }
108
+
109
+ .tab-button i {
110
+ font-size: 1.2rem;
111
+ }
112
+
113
+ .tab-slider {
114
+ position: absolute;
115
+ top: 0.5rem;
116
+ left: 0.5rem;
117
+ height: calc(100% - 1rem);
118
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
119
+ border-radius: 40px;
120
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
121
+ z-index: 1;
122
+ }
123
+
124
+ .tabs-content {
125
+ width: 100%;
126
+ max-width: 1000px;
127
+ position: relative;
128
+ }
129
+
130
+ .tab-panel {
131
+ display: none;
132
+ animation: fadeInUp 0.6s ease-out;
133
+ }
134
+
135
+ .tab-panel.active {
136
+ display: block;
137
+ }
138
+
139
+ .tab-panel-content {
140
+ background: white;
141
+ border-radius: 20px;
142
+ padding: 3rem;
143
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
144
+ position: relative;
145
+ overflow: hidden;
146
+ }
147
+
148
+ .tab-panel-content::before {
149
+ content: '';
150
+ position: absolute;
151
+ top: 0;
152
+ left: 0;
153
+ right: 0;
154
+ height: 4px;
155
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
156
+ }
157
+
158
+ /* Tab-specific styles */
159
+ .read-tab {
160
+ display: grid;
161
+ grid-template-columns: 1fr 1fr;
162
+ gap: 3rem;
163
+ align-items: center;
164
+ }
165
+
166
+ .read-content h3 {
167
+ font-size: 2rem;
168
+ font-weight: 700;
169
+ color: #2d3748;
170
+ margin-bottom: 1rem;
171
+ }
172
+
173
+ .read-content p {
174
+ font-size: 1.1rem;
175
+ color: #4a5568;
176
+ line-height: 1.7;
177
+ margin-bottom: 2rem;
178
+ }
179
+
180
+ .read-features {
181
+ display: flex;
182
+ flex-direction: column;
183
+ gap: 1rem;
184
+ }
185
+
186
+ .read-feature {
187
+ display: flex;
188
+ align-items: center;
189
+ gap: 1rem;
190
+ padding: 1rem;
191
+ background: #f8fafc;
192
+ border-radius: 10px;
193
+ transition: all 0.3s ease;
194
+ }
195
+
196
+ .read-feature:hover {
197
+ background: #e2e8f0;
198
+ transform: translateX(10px);
199
+ }
200
+
201
+ .read-feature i {
202
+ font-size: 1.5rem;
203
+ color: #667eea;
204
+ width: 40px;
205
+ height: 40px;
206
+ display: flex;
207
+ align-items: center;
208
+ justify-content: center;
209
+ background: white;
210
+ border-radius: 50%;
211
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.2);
212
+ }
213
+
214
+ .read-feature-text h4 {
215
+ font-weight: 600;
216
+ color: #2d3748;
217
+ margin-bottom: 0.25rem;
218
+ }
219
+
220
+ .read-feature-text p {
221
+ font-size: 0.9rem;
222
+ color: #4a5568;
223
+ margin: 0;
224
+ }
225
+
226
+ .read-visual {
227
+ position: relative;
228
+ text-align: center;
229
+ }
230
+
231
+ .read-visual img {
232
+ max-width: 100%;
233
+ height: auto;
234
+ border-radius: 15px;
235
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
236
+ }
237
+
238
+ .listen-tab {
239
+ display: grid;
240
+ grid-template-columns: 1fr 1fr;
241
+ gap: 3rem;
242
+ align-items: center;
243
+ }
244
+
245
+ .listen-content h3 {
246
+ font-size: 2rem;
247
+ font-weight: 700;
248
+ color: #2d3748;
249
+ margin-bottom: 1rem;
250
+ }
251
+
252
+ .listen-content p {
253
+ font-size: 1.1rem;
254
+ color: #4a5568;
255
+ line-height: 1.7;
256
+ margin-bottom: 2rem;
257
+ }
258
+
259
+ .listen-features {
260
+ display: flex;
261
+ flex-direction: column;
262
+ gap: 1rem;
263
+ }
264
+
265
+ .listen-feature {
266
+ display: flex;
267
+ align-items: center;
268
+ gap: 1rem;
269
+ padding: 1rem;
270
+ background: #f8fafc;
271
+ border-radius: 10px;
272
+ transition: all 0.3s ease;
273
+ }
274
+
275
+ .listen-feature:hover {
276
+ background: #e2e8f0;
277
+ transform: translateX(10px);
278
+ }
279
+
280
+ .listen-feature i {
281
+ font-size: 1.5rem;
282
+ color: #667eea;
283
+ width: 40px;
284
+ height: 40px;
285
+ display: flex;
286
+ align-items: center;
287
+ justify-content: center;
288
+ background: white;
289
+ border-radius: 50%;
290
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.2);
291
+ }
292
+
293
+ .listen-feature-text h4 {
294
+ font-weight: 600;
295
+ color: #2d3748;
296
+ margin-bottom: 0.25rem;
297
+ }
298
+
299
+ .listen-feature-text p {
300
+ font-size: 0.9rem;
301
+ color: #4a5568;
302
+ margin: 0;
303
+ }
304
+
305
+ .listen-visual {
306
+ position: relative;
307
+ text-align: center;
308
+ }
309
+
310
+ .listen-visual img {
311
+ max-width: 100%;
312
+ height: auto;
313
+ border-radius: 15px;
314
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
315
+ }
316
+
317
+ .learn-tab {
318
+ text-align: center;
319
+ }
320
+
321
+ .learn-content h3 {
322
+ font-size: 2.5rem;
323
+ font-weight: 700;
324
+ color: #2d3748;
325
+ margin-bottom: 1.5rem;
326
+ }
327
+
328
+ .learn-content p {
329
+ font-size: 1.2rem;
330
+ color: #4a5568;
331
+ line-height: 1.7;
332
+ margin-bottom: 3rem;
333
+ max-width: 600px;
334
+ margin-left: auto;
335
+ margin-right: auto;
336
+ }
337
+
338
+ .learn-grid {
339
+ display: grid;
340
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
341
+ gap: 2rem;
342
+ margin-top: 3rem;
343
+ }
344
+
345
+ .learn-card {
346
+ background: #f8fafc;
347
+ border-radius: 15px;
348
+ padding: 2rem;
349
+ transition: all 0.3s ease;
350
+ border: 2px solid transparent;
351
+ }
352
+
353
+ .learn-card:hover {
354
+ background: white;
355
+ border-color: #667eea;
356
+ transform: translateY(-10px);
357
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
358
+ }
359
+
360
+ .learn-card i {
361
+ font-size: 3rem;
362
+ color: #667eea;
363
+ margin-bottom: 1rem;
364
+ }
365
+
366
+ .learn-card h4 {
367
+ font-size: 1.25rem;
368
+ font-weight: 600;
369
+ color: #2d3748;
370
+ margin-bottom: 1rem;
371
+ }
372
+
373
+ .learn-card p {
374
+ font-size: 1rem;
375
+ color: #4a5568;
376
+ line-height: 1.6;
377
+ margin: 0;
378
+ }
379
+
380
+ /* Animations */
381
+ @keyframes fadeInUp {
382
+ from {
383
+ opacity: 0;
384
+ transform: translateY(30px);
385
+ }
386
+ to {
387
+ opacity: 1;
388
+ transform: translateY(0);
389
+ }
390
+ }
391
+
392
+ @keyframes slideIn {
393
+ from {
394
+ opacity: 0;
395
+ transform: translateX(-30px);
396
+ }
397
+ to {
398
+ opacity: 1;
399
+ transform: translateX(0);
400
+ }
401
+ }
402
+
403
+ /* Responsive Design */
404
+ @media (max-width: 768px) {
405
+ .tabs-header h2 {
406
+ font-size: 2rem;
407
+ }
408
+
409
+ .tabs-nav {
410
+ flex-direction: column;
411
+ border-radius: 20px;
412
+ padding: 0.25rem;
413
+ }
414
+
415
+ .tab-button {
416
+ padding: 0.75rem 1.5rem;
417
+ font-size: 0.9rem;
418
+ }
419
+
420
+ .tab-slider {
421
+ display: none;
422
+ }
423
+
424
+ .tab-button.active {
425
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
426
+ color: white;
427
+ }
428
+
429
+ .read-tab,
430
+ .listen-tab {
431
+ grid-template-columns: 1fr;
432
+ gap: 2rem;
433
+ }
434
+
435
+ .tab-panel-content {
436
+ padding: 2rem;
437
+ }
438
+
439
+ .learn-grid {
440
+ grid-template-columns: 1fr;
441
+ }
442
+ }
443
+
444
+ @media (max-width: 480px) {
445
+ .tabs-header h2 {
446
+ font-size: 1.75rem;
447
+ }
448
+
449
+ .tabs-header p {
450
+ font-size: 1rem;
451
+ }
452
+
453
+ .tab-panel-content {
454
+ padding: 1.5rem;
455
+ }
456
+
457
+ .read-content h3,
458
+ .listen-content h3 {
459
+ font-size: 1.5rem;
460
+ }
461
+
462
+ .learn-content h3 {
463
+ font-size: 2rem;
464
+ }
465
+ }
466
+ </style>
467
+ </head>
468
+ <body>
469
+ <section class="animated-tabs-section">
470
+ <div class="tabs-container">
471
+ <div class="tabs-header">
472
+ <h2>Bite-sized bestsellers</h2>
473
+ <p>Get powerful ideas in minutesβ€”not hours or days with our summaries of today's most transformative books.</p>
474
+ </div>
475
+
476
+ <div class="tabs-wrapper">
477
+ <div class="tabs-nav">
478
+ <div class="tab-slider"></div>
479
+ <button class="tab-button active" data-tab="read">
480
+ <i class="fas fa-book-open"></i>
481
+ Read
482
+ </button>
483
+ <button class="tab-button" data-tab="listen">
484
+ <i class="fas fa-headphones"></i>
485
+ Listen
486
+ </button>
487
+ <button class="tab-button" data-tab="learn">
488
+ <i class="fas fa-graduation-cap"></i>
489
+ Learn
490
+ </button>
491
+ </div>
492
+
493
+ <div class="tabs-content">
494
+ <!-- Read Tab -->
495
+ <div class="tab-panel active" id="read">
496
+ <div class="tab-panel-content">
497
+ <div class="read-tab">
498
+ <div class="read-content">
499
+ <h3>Read powerful insights</h3>
500
+ <p>Transform your reading experience with concise, well-structured summaries that capture the essence of bestselling books. Perfect for busy professionals who want to stay ahead.</p>
501
+
502
+ <div class="read-features">
503
+ <div class="read-feature">
504
+ <i class="fas fa-clock"></i>
505
+ <div class="read-feature-text">
506
+ <h4>15-minute reads</h4>
507
+ <p>Get the key insights in just 15 minutes</p>
508
+ </div>
509
+ </div>
510
+ <div class="read-feature">
511
+ <i class="fas fa-mobile-alt"></i>
512
+ <div class="read-feature-text">
513
+ <h4>Read anywhere</h4>
514
+ <p>Sync across all your devices seamlessly</p>
515
+ </div>
516
+ </div>
517
+ <div class="read-feature">
518
+ <i class="fas fa-bookmark"></i>
519
+ <div class="read-feature-text">
520
+ <h4>Save highlights</h4>
521
+ <p>Mark important passages for later review</p>
522
+ </div>
523
+ </div>
524
+ </div>
525
+ </div>
526
+ <div class="read-visual">
527
+ <img src="https://images.unsplash.com/photo-1481627834876-b7833e8f5570?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1000&q=80" alt="Reading on mobile device">
528
+ </div>
529
+ </div>
530
+ </div>
531
+ </div>
532
+
533
+ <!-- Listen Tab -->
534
+ <div class="tab-panel" id="listen">
535
+ <div class="tab-panel-content">
536
+ <div class="listen-tab">
537
+ <div class="listen-content">
538
+ <h3>Listen on the go</h3>
539
+ <p>Turn your commute into a learning opportunity with our professionally narrated audio summaries. Perfect for multitaskers who want to absorb knowledge while staying active.</p>
540
+
541
+ <div class="listen-features">
542
+ <div class="listen-feature">
543
+ <i class="fas fa-volume-up"></i>
544
+ <div class="listen-feature-text">
545
+ <h4>Professional narration</h4>
546
+ <p>Crystal clear audio with engaging voices</p>
547
+ </div>
548
+ </div>
549
+ <div class="listen-feature">
550
+ <i class="fas fa-tachometer-alt"></i>
551
+ <div class="listen-feature-text">
552
+ <h4>Adjustable speed</h4>
553
+ <p>Listen at your preferred pace</p>
554
+ </div>
555
+ </div>
556
+ <div class="listen-feature">
557
+ <i class="fas fa-download"></i>
558
+ <div class="listen-feature-text">
559
+ <h4>Offline listening</h4>
560
+ <p>Download and listen without internet</p>
561
+ </div>
562
+ </div>
563
+ </div>
564
+ </div>
565
+ <div class="listen-visual">
566
+ <img src="https://images.unsplash.com/photo-1511671782779-c97d3d27a1d4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1000&q=80" alt="Listening to audio">
567
+ </div>
568
+ </div>
569
+ </div>
570
+ </div>
571
+
572
+ <!-- Learn Tab -->
573
+ <div class="tab-panel" id="learn">
574
+ <div class="tab-panel-content">
575
+ <div class="learn-tab">
576
+ <div class="learn-content">
577
+ <h3>An expert guides you</h3>
578
+ <p>Let a pro lead you through the most important concepts and apply what you learn with practical tools and actionable steps.</p>
579
+
580
+ <div class="learn-grid">
581
+ <div class="learn-card">
582
+ <i class="fas fa-lightbulb"></i>
583
+ <h4>Key Insights</h4>
584
+ <p>Extract the most valuable lessons from each book with expert analysis and real-world applications.</p>
585
+ </div>
586
+ <div class="learn-card">
587
+ <i class="fas fa-tasks"></i>
588
+ <h4>Action Plans</h4>
589
+ <p>Turn knowledge into action with step-by-step implementation guides and practical exercises.</p>
590
+ </div>
591
+ <div class="learn-card">
592
+ <i class="fas fa-users"></i>
593
+ <h4>Community</h4>
594
+ <p>Join discussions with like-minded learners and share insights with our growing community.</p>
595
+ </div>
596
+ </div>
597
+ </div>
598
+ </div>
599
+ </div>
600
+ </div>
601
+ </div>
602
+ </div>
603
+ </div>
604
+ </section>
605
+
606
+ <script>
607
+ // Animated Tabs JavaScript
608
+ document.addEventListener('DOMContentLoaded', function() {
609
+ const tabButtons = document.querySelectorAll('.tab-button');
610
+ const tabPanels = document.querySelectorAll('.tab-panel');
611
+ const tabSlider = document.querySelector('.tab-slider');
612
+
613
+ // Set initial slider position
614
+ const activeButton = document.querySelector('.tab-button.active');
615
+ if (activeButton && tabSlider) {
616
+ tabSlider.style.width = activeButton.offsetWidth + 'px';
617
+ tabSlider.style.left = activeButton.offsetLeft + 'px';
618
+ }
619
+
620
+ tabButtons.forEach(button => {
621
+ button.addEventListener('click', () => {
622
+ const targetTab = button.getAttribute('data-tab');
623
+
624
+ // Remove active class from all buttons and panels
625
+ tabButtons.forEach(btn => btn.classList.remove('active'));
626
+ tabPanels.forEach(panel => panel.classList.remove('active'));
627
+
628
+ // Add active class to clicked button and target panel
629
+ button.classList.add('active');
630
+ document.getElementById(targetTab).classList.add('active');
631
+
632
+ // Animate slider
633
+ if (tabSlider) {
634
+ tabSlider.style.width = button.offsetWidth + 'px';
635
+ tabSlider.style.left = button.offsetLeft + 'px';
636
+ }
637
+ });
638
+ });
639
+
640
+ // Add hover effects for mobile
641
+ if (window.innerWidth <= 768) {
642
+ tabButtons.forEach(button => {
643
+ button.addEventListener('mouseenter', () => {
644
+ if (!button.classList.contains('active')) {
645
+ button.style.transform = 'scale(1.05)';
646
+ }
647
+ });
648
+
649
+ button.addEventListener('mouseleave', () => {
650
+ button.style.transform = 'scale(1)';
651
+ });
652
+ });
653
+ }
654
+ });
655
+ </script>
656
+ </body>
657
+ </html>
658
+
booknap project/animated-tabs.js ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Animated Tabs JavaScript - Blinkist Style
2
+ class AnimatedTabs {
3
+ constructor(container) {
4
+ this.container = container;
5
+ this.tabButtons = container.querySelectorAll('.tab-button');
6
+ this.tabPanels = container.querySelectorAll('.tab-panel');
7
+ this.tabSlider = container.querySelector('.tab-slider');
8
+ this.isAnimating = false;
9
+
10
+ this.init();
11
+ }
12
+
13
+ init() {
14
+ this.setInitialState();
15
+ this.bindEvents();
16
+ this.addResponsiveBehavior();
17
+ }
18
+
19
+ setInitialState() {
20
+ // Set initial slider position
21
+ const activeButton = this.container.querySelector('.tab-button.active');
22
+ if (activeButton && this.tabSlider) {
23
+ this.updateSliderPosition(activeButton);
24
+ }
25
+
26
+ // Ensure first tab is active if none are
27
+ if (!activeButton && this.tabButtons.length > 0) {
28
+ this.tabButtons[0].classList.add('active');
29
+ this.tabPanels[0].classList.add('active');
30
+ this.updateSliderPosition(this.tabButtons[0]);
31
+ }
32
+ }
33
+
34
+ bindEvents() {
35
+ this.tabButtons.forEach(button => {
36
+ button.addEventListener('click', (e) => {
37
+ e.preventDefault();
38
+ this.switchTab(button);
39
+ });
40
+ });
41
+ }
42
+
43
+ switchTab(activeButton) {
44
+ if (this.isAnimating) return;
45
+
46
+ this.isAnimating = true;
47
+ const targetTab = activeButton.getAttribute('data-tab');
48
+
49
+ // Remove active class from all buttons and panels
50
+ this.tabButtons.forEach(btn => btn.classList.remove('active'));
51
+ this.tabPanels.forEach(panel => panel.classList.remove('active'));
52
+
53
+ // Add active class to clicked button and target panel
54
+ activeButton.classList.add('active');
55
+ const targetPanel = this.container.querySelector(`#${targetTab}`);
56
+ if (targetPanel) {
57
+ targetPanel.classList.add('active');
58
+ }
59
+
60
+ // Animate slider
61
+ this.updateSliderPosition(activeButton);
62
+
63
+ // Trigger custom event
64
+ this.container.dispatchEvent(new CustomEvent('tabChanged', {
65
+ detail: {
66
+ activeTab: targetTab,
67
+ activeButton: activeButton,
68
+ activePanel: targetPanel
69
+ }
70
+ }));
71
+
72
+ // Reset animation flag after transition
73
+ setTimeout(() => {
74
+ this.isAnimating = false;
75
+ }, 400);
76
+ }
77
+
78
+ updateSliderPosition(button) {
79
+ if (!this.tabSlider) return;
80
+
81
+ const buttonRect = button.getBoundingClientRect();
82
+ const containerRect = this.container.getBoundingClientRect();
83
+
84
+ this.tabSlider.style.width = button.offsetWidth + 'px';
85
+ this.tabSlider.style.left = (button.offsetLeft - this.container.offsetLeft) + 'px';
86
+ }
87
+
88
+ addResponsiveBehavior() {
89
+ // Handle window resize
90
+ let resizeTimeout;
91
+ window.addEventListener('resize', () => {
92
+ clearTimeout(resizeTimeout);
93
+ resizeTimeout = setTimeout(() => {
94
+ const activeButton = this.container.querySelector('.tab-button.active');
95
+ if (activeButton) {
96
+ this.updateSliderPosition(activeButton);
97
+ }
98
+ }, 100);
99
+ });
100
+
101
+ // Add hover effects for mobile
102
+ if (window.innerWidth <= 768) {
103
+ this.tabButtons.forEach(button => {
104
+ button.addEventListener('mouseenter', () => {
105
+ if (!button.classList.contains('active')) {
106
+ button.style.transform = 'scale(1.05)';
107
+ }
108
+ });
109
+
110
+ button.addEventListener('mouseleave', () => {
111
+ button.style.transform = 'scale(1)';
112
+ });
113
+ });
114
+ }
115
+ }
116
+
117
+ // Public methods
118
+ switchToTab(tabId) {
119
+ const button = this.container.querySelector(`[data-tab="${tabId}"]`);
120
+ if (button) {
121
+ this.switchTab(button);
122
+ }
123
+ }
124
+
125
+ getActiveTab() {
126
+ const activeButton = this.container.querySelector('.tab-button.active');
127
+ return activeButton ? activeButton.getAttribute('data-tab') : null;
128
+ }
129
+ }
130
+
131
+ // Auto-initialize tabs when DOM is loaded
132
+ document.addEventListener('DOMContentLoaded', function() {
133
+ const tabsContainers = document.querySelectorAll('.tabs-wrapper');
134
+ tabsContainers.forEach(container => {
135
+ new AnimatedTabs(container);
136
+ });
137
+ });
138
+
139
+ // Export for module usage
140
+ if (typeof module !== 'undefined' && module.exports) {
141
+ module.exports = AnimatedTabs;
142
+ }
143
+
booknap project/app.py ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, jsonify, render_template, request
2
+ from flask_cors import CORS
3
+ from sqlalchemy import create_engine, text
4
+ import kagglehub
5
+ from kagglehub import KaggleDatasetAdapter
6
+ import pandas as pd
7
+ import os
8
+
9
+ app = Flask(__name__)
10
+ CORS(app)
11
+
12
+ # Database configuration
13
+ DATABASE_URL = os.environ.get(
14
+ "DATABASE_URL",
15
+ "postgresql://postgres:postgres@db.ckrqyjfdifjbsuuofegd.supabase.co:5432/postgres",
16
+ )
17
+ engine = create_engine(DATABASE_URL, pool_pre_ping=True)
18
+
19
+ # Download the datasets
20
+ @app.before_first_request
21
+ def download_datasets():
22
+ try:
23
+ print("Downloading datasets...")
24
+
25
+ # Download news dataset
26
+ news_path = kagglehub.dataset_download("therohk/global-news-week")
27
+ print("Path to news dataset files:", news_path)
28
+
29
+ # Download business leaders dataset
30
+ business_path = kagglehub.dataset_download("beatafaron/wisdom-from-business-leaders-and-innovators")
31
+ print("Path to business leaders dataset files:", business_path)
32
+
33
+ return {"news": news_path, "business": business_path}
34
+ except Exception as e:
35
+ print(f"Error downloading datasets: {e}")
36
+ return None
37
+
38
+ @app.route('/')
39
+ def home():
40
+ return render_template('business-leaders.html')
41
+
42
+ @app.route('/blog')
43
+ def blog():
44
+ return render_template('blog.html')
45
+
46
+ @app.route('/login', methods=['POST'])
47
+ def login():
48
+ try:
49
+ payload = request.get_json(silent=True) or request.form
50
+ email = (payload.get('email') or '').strip().lower()
51
+ password = payload.get('password') or ''
52
+ if not email or not password:
53
+ return jsonify({"error": "Email and password are required"}), 400
54
+
55
+ # Simple credentials check against users table
56
+ # Expected schema: users(id serial pk, email text unique, password text)
57
+ with engine.connect() as conn:
58
+ row = conn.execute(
59
+ text("SELECT id, email, password FROM users WHERE email = :email"),
60
+ {"email": email},
61
+ ).mappings().first()
62
+
63
+ if not row:
64
+ return jsonify({"error": "Invalid credentials"}), 401
65
+
66
+ # NOTE: For demo purposes comparing plaintext. In production, store hashed passwords and verify with bcrypt.
67
+ if password != row["password"]:
68
+ return jsonify({"error": "Invalid credentials"}), 401
69
+
70
+ return jsonify({"ok": True, "user": {"id": row["id"], "email": row["email"]}})
71
+ except Exception as e:
72
+ return jsonify({"error": str(e)}), 500
73
+
74
+ @app.route('/signup', methods=['POST'])
75
+ def signup():
76
+ try:
77
+ payload = request.get_json(silent=True) or request.form
78
+ full_name = (payload.get('fullName') or '').strip()
79
+ email = (payload.get('email') or '').strip().lower()
80
+ password = payload.get('password') or ''
81
+
82
+ if not full_name or not email or not password:
83
+ return jsonify({"error": "Full name, email and password are required"}), 400
84
+
85
+ # Check if user already exists
86
+ with engine.connect() as conn:
87
+ existing_user = conn.execute(
88
+ text("SELECT id FROM users WHERE email = :email"),
89
+ {"email": email},
90
+ ).mappings().first()
91
+
92
+ if existing_user:
93
+ return jsonify({"error": "User with this email already exists"}), 409
94
+
95
+ # Insert new user
96
+ # Expected schema: users(id serial pk, full_name text, email text unique, password text)
97
+ result = conn.execute(
98
+ text("INSERT INTO users (full_name, email, password) VALUES (:full_name, :email, :password) RETURNING id"),
99
+ {"full_name": full_name, "email": email, "password": password},
100
+ )
101
+
102
+ # Commit the transaction
103
+ conn.commit()
104
+
105
+ user_id = result.fetchone()[0]
106
+
107
+ return jsonify({
108
+ "message": "Account created successfully! Redirecting to login...",
109
+ "user": {"id": user_id, "full_name": full_name, "email": email}
110
+ }), 201
111
+
112
+ except Exception as e:
113
+ return jsonify({"error": str(e)}), 500
114
+
115
+ @app.route('/api/news')
116
+ def get_news():
117
+ try:
118
+ # Find the CSV file in the downloaded dataset
119
+ dataset_path = None
120
+ for root, dirs, files in os.walk('.'):
121
+ for file in files:
122
+ if file.endswith('.csv') and 'global-news' in root:
123
+ dataset_path = os.path.join(root, file)
124
+ break
125
+ if dataset_path:
126
+ break
127
+
128
+ if dataset_path:
129
+ # Read the CSV file
130
+ df = pd.read_csv(dataset_path)
131
+
132
+ # Convert to JSON format for the blog
133
+ news_data = []
134
+ for index, row in df.head(20).iterrows(): # Get first 20 articles
135
+ news_item = {
136
+ 'title': row.get('title', 'No title'),
137
+ 'description': row.get('description', 'No description'),
138
+ 'date': row.get('date', 'No date'),
139
+ 'source': row.get('source', 'Unknown source'),
140
+ 'category': row.get('category', 'General')
141
+ }
142
+ news_data.append(news_item)
143
+
144
+ return jsonify(news_data)
145
+ else:
146
+ return jsonify({'error': 'News dataset file not found'})
147
+
148
+ except Exception as e:
149
+ return jsonify({'error': str(e)})
150
+
151
+ @app.route('/api/business-leaders')
152
+ def get_business_leaders():
153
+ try:
154
+ # Load the business leaders dataset using kagglehub
155
+ df = kagglehub.load_dataset(
156
+ KaggleDatasetAdapter.PANDAS,
157
+ "beatafaron/wisdom-from-business-leaders-and-innovators",
158
+ "", # Empty string for default file
159
+ )
160
+
161
+ # Convert to JSON format
162
+ business_data = []
163
+ for index, row in df.head(20).iterrows(): # Get first 20 records
164
+ business_item = {
165
+ 'id': index + 1,
166
+ 'quote': row.get('quote', 'No quote available'),
167
+ 'author': row.get('author', 'Unknown author'),
168
+ 'category': row.get('category', 'General'),
169
+ 'source': row.get('source', 'Unknown source'),
170
+ 'year': row.get('year', 'Unknown year')
171
+ }
172
+ business_data.append(business_item)
173
+
174
+ return jsonify(business_data)
175
+
176
+ except Exception as e:
177
+ return jsonify({'error': str(e)})
178
+
179
+ @app.route('/api/business-leaders/<int:record_id>')
180
+ def get_business_leader(record_id):
181
+ try:
182
+ # Load the business leaders dataset
183
+ df = kagglehub.load_dataset(
184
+ KaggleDatasetAdapter.PANDAS,
185
+ "beatafaron/wisdom-from-business-leaders-and-innovators",
186
+ "",
187
+ )
188
+
189
+ if record_id < len(df):
190
+ row = df.iloc[record_id]
191
+ business_item = {
192
+ 'id': record_id + 1,
193
+ 'quote': row.get('quote', 'No quote available'),
194
+ 'author': row.get('author', 'Unknown author'),
195
+ 'category': row.get('category', 'General'),
196
+ 'source': row.get('source', 'Unknown source'),
197
+ 'year': row.get('year', 'Unknown year')
198
+ }
199
+ return jsonify(business_item)
200
+ else:
201
+ return jsonify({'error': 'Record not found'})
202
+
203
+ except Exception as e:
204
+ return jsonify({'error': str(e)})
205
+
206
+ @app.route('/api/dataset-info')
207
+ def dataset_info():
208
+ try:
209
+ # Get info about both datasets
210
+ news_path = kagglehub.dataset_download("therohk/global-news-week")
211
+ business_path = kagglehub.dataset_download("beatafaron/wisdom-from-business-leaders-and-innovators")
212
+
213
+ return jsonify({
214
+ 'status': 'success',
215
+ 'datasets': {
216
+ 'news': {
217
+ 'name': 'Global News Week',
218
+ 'path': str(news_path),
219
+ 'description': 'Latest news articles from various sources'
220
+ },
221
+ 'business_leaders': {
222
+ 'name': 'Wisdom from Business Leaders and Innovators',
223
+ 'path': str(business_path),
224
+ 'description': 'Inspirational quotes and wisdom from business leaders'
225
+ }
226
+ },
227
+ 'message': 'All datasets downloaded successfully'
228
+ })
229
+ except Exception as e:
230
+ return jsonify({
231
+ 'status': 'error',
232
+ 'error': str(e)
233
+ })
234
+
235
+ if __name__ == '__main__':
236
+ app.run(debug=True, port=5000)
237
+
booknap project/assets/audio/7-habits-summary.mp3 ADDED
@@ -0,0 +1 @@
 
 
1
+ Placeholder audio file
booknap project/assets/audio/atomic-habits-summary.mp3 ADDED
@@ -0,0 +1 @@
 
 
1
+ Placeholder audio file
booknap project/assets/audio/rich-dad-poor-dad-summary.mp3 ADDED
@@ -0,0 +1 @@
 
 
1
+ Placeholder audio file
booknap project/assets/audio/thinking-fast-slow-summary.mp3 ADDED
@@ -0,0 +1 @@
 
 
1
+ Placeholder audio file
booknap project/assets/covers/7-habits.jpg ADDED
booknap project/assets/covers/7-habits.svg ADDED
booknap project/assets/covers/atomic-habits.jpg ADDED
booknap project/assets/covers/atomic-habits.svg ADDED
booknap project/assets/covers/jane-austen-portrait.svg ADDED
booknap project/assets/covers/rich-dad-poor-dad.jpg ADDED
booknap project/assets/covers/rich-dad-poor-dad.svg ADDED
booknap project/assets/covers/start-with-why.svg ADDED
booknap project/assets/covers/thinking-fast-slow.jpg ADDED
booknap project/assets/covers/thinking-fast-slow.svg ADDED
booknap project/assets/covers/zero-to-one.svg ADDED
booknap project/blog.html ADDED
@@ -0,0 +1,612 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Blog - booknap</title>
7
+ <link rel="stylesheet" href="styles.css" />
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" />
10
+ <style>
11
+ :root {
12
+ --bg: #0f172a;
13
+ --card: #0b1223;
14
+ --muted: #94a3b8;
15
+ --text: #e2e8f0;
16
+ --brand: #3b82f6;
17
+ --brand-2: #6366f1;
18
+ }
19
+ body {
20
+ background: linear-gradient(180deg, #0b1020, #0b1022 30%, #0b1124);
21
+ min-height: 100vh;
22
+ color: var(--text);
23
+ }
24
+ /* Match pricing header/nav styling */
25
+ .header { position: sticky; top: 0; -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); background: rgba(7,10,20,0.55); z-index: 20; box-shadow: none; }
26
+ .nav { border-bottom: 1px solid rgba(255,255,255,0.06); }
27
+ .nav-logo i { color: var(--brand); }
28
+ .nav-link { color: var(--muted); text-decoration: none; font-weight: 600; }
29
+ .nav-link:hover, .nav-link.active { color: var(--text); }
30
+
31
+ /* Navigation Login Button */
32
+ .nav-container {
33
+ display: flex;
34
+ align-items: center;
35
+ gap: 2rem;
36
+ }
37
+
38
+ .nav-menu {
39
+ display: flex;
40
+ align-items: center;
41
+ gap: 2rem;
42
+ margin-left: auto;
43
+ list-style: none;
44
+ }
45
+
46
+ .nav-menu li {
47
+ position: relative;
48
+ }
49
+
50
+ .nav-login {
51
+ margin-left: 0;
52
+ }
53
+
54
+ .login-btn {
55
+ background: linear-gradient(90deg, #3b82f6, #6366f1);
56
+ color: white;
57
+ padding: 0.75rem 1.5rem;
58
+ border-radius: 8px;
59
+ text-decoration: none;
60
+ font-weight: 600;
61
+ transition: background-color 0.2s ease;
62
+ display: inline-block;
63
+ }
64
+
65
+ .login-btn:hover {
66
+ background: linear-gradient(90deg, #2563eb, #4f46e5);
67
+ }
68
+
69
+ .signup-btn {
70
+ background: transparent;
71
+ color: var(--text);
72
+ padding: 0.75rem 1.5rem;
73
+ border: 2px solid rgba(255, 255, 255, 0.2);
74
+ border-radius: 8px;
75
+ text-decoration: none;
76
+ font-weight: 600;
77
+ transition: all 0.2s ease;
78
+ display: inline-block;
79
+ margin-left: 0.5rem;
80
+ }
81
+
82
+ .signup-btn:hover {
83
+ background: rgba(255, 255, 255, 0.1);
84
+ border-color: rgba(255, 255, 255, 0.4);
85
+ }
86
+
87
+ /* Search Bar Styles */
88
+ .search-container {
89
+ margin-left: 0.5rem;
90
+ }
91
+
92
+ .search-bar {
93
+ position: relative;
94
+ display: flex;
95
+ align-items: center;
96
+ background: rgba(0, 0, 0, 0.3);
97
+ border: 1px solid rgba(255, 255, 255, 0.2);
98
+ border-radius: 25px;
99
+ padding: 0.5rem 1rem;
100
+ min-width: 300px;
101
+ transition: all 0.3s ease;
102
+ }
103
+
104
+ .search-bar:focus-within {
105
+ background: rgba(0, 0, 0, 0.4);
106
+ border-color: rgba(59, 130, 246, 0.5);
107
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
108
+ }
109
+
110
+ .search-icon {
111
+ color: rgba(255, 255, 255, 0.6);
112
+ margin-right: 0.75rem;
113
+ font-size: 0.9rem;
114
+ }
115
+
116
+ .search-input {
117
+ background: transparent;
118
+ border: none;
119
+ color: var(--text);
120
+ font-size: 0.9rem;
121
+ font-weight: 500;
122
+ width: 100%;
123
+ outline: none;
124
+ }
125
+
126
+ .search-input::placeholder {
127
+ color: rgba(255, 255, 255, 0.5);
128
+ }
129
+
130
+ /* Dropdown Menu Styles */
131
+ .dropdown {
132
+ position: relative;
133
+ }
134
+
135
+ .dropdown-toggle {
136
+ display: flex;
137
+ align-items: center;
138
+ gap: 0.5rem;
139
+ }
140
+
141
+ .dropdown-toggle i {
142
+ font-size: 0.8rem;
143
+ transition: transform 0.2s ease;
144
+ }
145
+
146
+ .dropdown.active .dropdown-toggle i {
147
+ transform: rotate(180deg);
148
+ }
149
+
150
+ .dropdown-menu {
151
+ position: absolute;
152
+ top: 100%;
153
+ left: 50%;
154
+ transform: translateX(-50%);
155
+ background: rgba(15, 23, 42, 0.95);
156
+ border: 1px solid rgba(255, 255, 255, 0.1);
157
+ border-radius: 12px;
158
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
159
+ min-width: 500px;
160
+ opacity: 0;
161
+ visibility: hidden;
162
+ transition: all 0.3s ease;
163
+ z-index: 1000;
164
+ margin-top: 1rem;
165
+ -webkit-backdrop-filter: blur(10px);
166
+ backdrop-filter: blur(10px);
167
+ }
168
+
169
+ .dropdown.active .dropdown-menu {
170
+ opacity: 1;
171
+ visibility: visible;
172
+ }
173
+
174
+ .dropdown-content {
175
+ display: flex;
176
+ padding: 2rem;
177
+ }
178
+
179
+ .dropdown-section {
180
+ flex: 1;
181
+ }
182
+
183
+ .dropdown-section h4 {
184
+ color: #e2e8f0;
185
+ font-size: 0.875rem;
186
+ font-weight: 600;
187
+ margin: 0 0 1rem 0;
188
+ text-transform: uppercase;
189
+ letter-spacing: 0.05em;
190
+ }
191
+
192
+ .dropdown-section ul {
193
+ list-style: none;
194
+ margin: 0;
195
+ padding: 0;
196
+ }
197
+
198
+ .dropdown-section li {
199
+ margin-bottom: 0.75rem;
200
+ }
201
+
202
+ .dropdown-section a {
203
+ display: flex;
204
+ align-items: center;
205
+ gap: 0.75rem;
206
+ color: #94a3b8;
207
+ text-decoration: none;
208
+ font-size: 0.875rem;
209
+ padding: 0.5rem;
210
+ border-radius: 8px;
211
+ transition: all 0.2s ease;
212
+ }
213
+
214
+ .dropdown-section a:hover {
215
+ background: rgba(255, 255, 255, 0.1);
216
+ color: #e2e8f0;
217
+ }
218
+
219
+ .dropdown-section i {
220
+ font-size: 1rem;
221
+ width: 20px;
222
+ text-align: center;
223
+ }
224
+
225
+ .dropdown-divider {
226
+ width: 1px;
227
+ background: rgba(255, 255, 255, 0.2);
228
+ margin: 0 1.5rem;
229
+ }
230
+
231
+ .all-categories {
232
+ color: #60a5fa !important;
233
+ font-weight: 600;
234
+ margin-top: 0.5rem;
235
+ display: inline-flex;
236
+ align-items: center;
237
+ gap: 0.25rem;
238
+ }
239
+
240
+ .all-categories:hover {
241
+ color: #93c5fd !important;
242
+ }
243
+
244
+ /* Mobile Navigation */
245
+ .nav-toggle {
246
+ display: none;
247
+ flex-direction: column;
248
+ cursor: pointer;
249
+ gap: 4px;
250
+ }
251
+
252
+ .nav-toggle span {
253
+ width: 25px;
254
+ height: 3px;
255
+ background: var(--text);
256
+ border-radius: 2px;
257
+ transition: all 0.3s ease;
258
+ }
259
+
260
+ @media (max-width: 768px) {
261
+ .nav-menu {
262
+ display: none;
263
+ }
264
+
265
+ .nav-menu.active {
266
+ display: flex;
267
+ flex-direction: column;
268
+ position: absolute;
269
+ top: 100%;
270
+ left: 0;
271
+ right: 0;
272
+ background: rgba(15, 23, 42, 0.95);
273
+ -webkit-backdrop-filter: blur(10px);
274
+ backdrop-filter: blur(10px);
275
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
276
+ padding: 1rem;
277
+ }
278
+
279
+ .nav-toggle {
280
+ display: flex;
281
+ }
282
+
283
+ .search-container {
284
+ display: none;
285
+ }
286
+ }
287
+
288
+ /* Blog Page Styles */
289
+ .blog-hero {
290
+ padding: 4rem 0 3rem;
291
+ text-align: center;
292
+ max-width: 800px;
293
+ margin: 0 auto;
294
+ }
295
+ .blog-hero h1 {
296
+ font-size: 3rem;
297
+ font-weight: 700;
298
+ margin-bottom: 1rem;
299
+ background: linear-gradient(135deg, #3b82f6, #6366f1);
300
+ -webkit-background-clip: text;
301
+ -webkit-text-fill-color: transparent;
302
+ background-clip: text;
303
+ }
304
+ .blog-hero p {
305
+ font-size: 1.25rem;
306
+ color: var(--muted);
307
+ line-height: 1.6;
308
+ margin-bottom: 2rem;
309
+ }
310
+
311
+ .blog-grid {
312
+ max-width: 1200px;
313
+ margin: 0 auto;
314
+ padding: 0 1rem 4rem;
315
+ display: grid;
316
+ grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
317
+ gap: 2rem;
318
+ }
319
+
320
+ .blog-card {
321
+ background: rgba(255, 255, 255, 0.05);
322
+ border-radius: 16px;
323
+ overflow: hidden;
324
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
325
+ border: 1px solid rgba(255, 255, 255, 0.1);
326
+ }
327
+ .blog-card:hover {
328
+ transform: translateY(-8px);
329
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
330
+ }
331
+
332
+ .blog-card-image {
333
+ width: 100%;
334
+ height: 200px;
335
+ background-size: cover;
336
+ background-position: center;
337
+ position: relative;
338
+ }
339
+
340
+ .blog-card-content {
341
+ padding: 1.5rem;
342
+ }
343
+
344
+ .blog-card-title {
345
+ font-size: 1.25rem;
346
+ font-weight: 600;
347
+ margin-bottom: 0.5rem;
348
+ color: var(--text);
349
+ line-height: 1.4;
350
+ }
351
+
352
+ .blog-card-date {
353
+ color: var(--muted);
354
+ font-size: 0.875rem;
355
+ margin-bottom: 1rem;
356
+ }
357
+
358
+ .blog-card-link {
359
+ color: #8b5cf6;
360
+ text-decoration: none;
361
+ font-weight: 600;
362
+ font-size: 0.875rem;
363
+ text-transform: uppercase;
364
+ letter-spacing: 0.5px;
365
+ transition: color 0.3s ease;
366
+ }
367
+ .blog-card-link:hover {
368
+ color: #a78bfa;
369
+ }
370
+
371
+ .pagination {
372
+ display: flex;
373
+ justify-content: center;
374
+ align-items: center;
375
+ gap: 0.5rem;
376
+ margin: 3rem 0;
377
+ }
378
+
379
+ .pagination-btn {
380
+ background: rgba(255, 255, 255, 0.1);
381
+ border: 1px solid rgba(255, 255, 255, 0.2);
382
+ color: var(--text);
383
+ padding: 0.5rem 1rem;
384
+ border-radius: 8px;
385
+ text-decoration: none;
386
+ transition: all 0.3s ease;
387
+ }
388
+ .pagination-btn:hover {
389
+ background: var(--brand);
390
+ border-color: var(--brand);
391
+ }
392
+ .pagination-btn.active {
393
+ background: var(--brand);
394
+ border-color: var(--brand);
395
+ }
396
+
397
+ @media (max-width: 768px) {
398
+ .blog-hero h1 {
399
+ font-size: 2rem;
400
+ }
401
+ .blog-grid {
402
+ grid-template-columns: 1fr;
403
+ padding: 0 1rem 2rem;
404
+ }
405
+ }
406
+ </style>
407
+ </head>
408
+ <body>
409
+ <header class="header">
410
+ <nav class="nav">
411
+ <div class="nav-container">
412
+ <div class="nav-logo">
413
+ <i class="fas fa-book-open"></i>
414
+ <span>booknap</span>
415
+ </div>
416
+ <div class="search-container">
417
+ <div class="search-bar">
418
+ <i class="fas fa-search search-icon"></i>
419
+ <input type="text" placeholder="Find a book..." class="search-input">
420
+ </div>
421
+ </div>
422
+ <ul class="nav-menu">
423
+ <li><a href="books.html" class="nav-link">Home</a></li>
424
+ <li class="dropdown">
425
+ <a href="#" class="nav-link dropdown-toggle">Book Summaries <i class="fas fa-chevron-down"></i></a>
426
+ <div class="dropdown-menu">
427
+ <div class="dropdown-content">
428
+ <div class="dropdown-section">
429
+ <h4>Browse by type</h4>
430
+ <ul>
431
+ <li><a href="#"><i class="fas fa-book-open" style="color: #10b981;"></i> Text Summaries</a></li>
432
+ <li><a href="#"><i class="fas fa-headphones" style="color: #3b82f6;"></i> Audio Summaries</a></li>
433
+ <li><a href="#"><i class="fas fa-play-circle" style="color: #8b5cf6;"></i> Video Summaries</a></li>
434
+ <li><a href="#"><i class="fas fa-file-pdf" style="color: #f59e0b;"></i> PDF Downloads</a></li>
435
+ <li><a href="#"><i class="fas fa-mobile-alt" style="color: #06b6d4;"></i> Mobile App</a></li>
436
+ </ul>
437
+ </div>
438
+ <div class="dropdown-divider"></div>
439
+ <div class="dropdown-section">
440
+ <h4>Browse by topic</h4>
441
+ <ul>
442
+ <li><a href="#"><i class="fas fa-brain" style="color: #f59e0b;"></i> Psychology</a></li>
443
+ <li><a href="#"><i class="fas fa-chart-line" style="color: #10b981;"></i> Business</a></li>
444
+ <li><a href="#"><i class="fas fa-heart" style="color: #ef4444;"></i> Self-Help</a></li>
445
+ <li><a href="#"><i class="fas fa-graduation-cap" style="color: #8b5cf6;"></i> Education</a></li>
446
+ <li><a href="#"><i class="fas fa-lightbulb" style="color: #06b6d4;"></i> Innovation</a></li>
447
+ </ul>
448
+ <a href="#" class="all-categories">all categories <i class="fas fa-arrow-right"></i></a>
449
+ </div>
450
+ </div>
451
+ </div>
452
+ </li>
453
+ <li><a href="pricing.html" class="nav-link">Pricing</a></li>
454
+ <li><a href="blog.html" class="nav-link active">Blog</a></li>
455
+ </ul>
456
+ <div class="nav-login">
457
+ <a href="login.html" class="login-btn">Login</a>
458
+ <a href="signup.html" class="signup-btn">Sign Up</a>
459
+ </div>
460
+ <div class="nav-toggle">
461
+ <span></span>
462
+ <span></span>
463
+ <span></span>
464
+ </div>
465
+ </div>
466
+ </nav>
467
+ </header>
468
+
469
+ <main>
470
+ <section class="blog-hero">
471
+ <h1>Read Our Blog</h1>
472
+ <p>Weekly articles with insights into the latest book summaries and reading strategies. Our blog takes the key concepts from popular books and lays out practical next steps, so you can learn and apply knowledge in meaningful ways.</p>
473
+ </section>
474
+
475
+ <div class="blog-grid">
476
+ <!-- Blog Card 1 -->
477
+ <article class="blog-card">
478
+ <div class="blog-card-image" style="background-image: url('https://images.unsplash.com/photo-1506905925346-21bda4d32df4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80');"></div>
479
+ <div class="blog-card-content">
480
+ <h3 class="blog-card-title">How to Access Your Inner Strength Through Reading</h3>
481
+ <p class="blog-card-date">June 17, 2025</p>
482
+ <a href="#" class="blog-card-link">VIEW THESE RESOURCES</a>
483
+ </div>
484
+ </article>
485
+
486
+ <!-- Blog Card 2 -->
487
+ <article class="blog-card">
488
+ <div class="blog-card-image" style="background-image: url('https://images.unsplash.com/photo-1544716278-ca5e3f4abd8c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1974&q=80');"></div>
489
+ <div class="blog-card-content">
490
+ <h3 class="blog-card-title">Meditation is the Key to a Flourishing Life</h3>
491
+ <p class="blog-card-date">June 11, 2025</p>
492
+ <a href="#" class="blog-card-link">VIEW THESE RESOURCES</a>
493
+ </div>
494
+ </article>
495
+
496
+ <!-- Blog Card 3 -->
497
+ <article class="blog-card">
498
+ <div class="blog-card-image" style="background-image: url('https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1976&q=80');"></div>
499
+ <div class="blog-card-content">
500
+ <h3 class="blog-card-title">Women's Leadership in Literature Isn't Optional</h3>
501
+ <p class="blog-card-date">June 5, 2025</p>
502
+ <a href="#" class="blog-card-link">VIEW THESE RESOURCES</a>
503
+ </div>
504
+ </article>
505
+
506
+ <!-- Blog Card 4 -->
507
+ <article class="blog-card">
508
+ <div class="blog-card-image" style="background-image: url('https://images.unsplash.com/photo-1522202176988-66273c2fd55f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2071&q=80');"></div>
509
+ <div class="blog-card-content">
510
+ <h3 class="blog-card-title">Modeling Success for the Next Generation</h3>
511
+ <p class="blog-card-date">May 14, 2025</p>
512
+ <a href="#" class="blog-card-link">VIEW THESE RESOURCES</a>
513
+ </div>
514
+ </article>
515
+
516
+ <!-- Blog Card 5 -->
517
+ <article class="blog-card">
518
+ <div class="blog-card-image" style="background-image: url('https://images.unsplash.com/photo-1554224155-6726b3ff858f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2011&q=80');"></div>
519
+ <div class="blog-card-content">
520
+ <h3 class="blog-card-title">How to Honor Tradition and Innovation</h3>
521
+ <p class="blog-card-date">May 6, 2025</p>
522
+ <a href="#" class="blog-card-link">VIEW THESE RESOURCES</a>
523
+ </div>
524
+ </article>
525
+
526
+ <!-- Blog Card 6 -->
527
+ <article class="blog-card">
528
+ <div class="blog-card-image" style="background-image: url('https://images.unsplash.com/photo-1506905925346-21bda4d32df4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80');"></div>
529
+ <div class="blog-card-content">
530
+ <h3 class="blog-card-title">Slow Down to Hear Your Inner Voice</h3>
531
+ <p class="blog-card-date">April 30, 2025</p>
532
+ <a href="#" class="blog-card-link">VIEW THESE RESOURCES</a>
533
+ </div>
534
+ </article>
535
+
536
+ <!-- Blog Card 7 -->
537
+ <article class="blog-card">
538
+ <div class="blog-card-image" style="background-image: url('https://images.unsplash.com/photo-1544716278-ca5e3f4abd8c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1974&q=80');"></div>
539
+ <div class="blog-card-content">
540
+ <h3 class="blog-card-title">You Are Under Construction</h3>
541
+ <p class="blog-card-date">June 10, 2024</p>
542
+ <a href="#" class="blog-card-link">VIEW THESE RESOURCES</a>
543
+ </div>
544
+ </article>
545
+
546
+ <!-- Blog Card 8 -->
547
+ <article class="blog-card">
548
+ <div class="blog-card-image" style="background-image: url('https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1976&q=80');"></div>
549
+ <div class="blog-card-content">
550
+ <h3 class="blog-card-title">Knowledge at the Center</h3>
551
+ <p class="blog-card-date">June 3, 2024</p>
552
+ <a href="#" class="blog-card-link">VIEW THESE RESOURCES</a>
553
+ </div>
554
+ </article>
555
+
556
+ <!-- Blog Card 9 -->
557
+ <article class="blog-card">
558
+ <div class="blog-card-image" style="background-image: url('https://images.unsplash.com/photo-1522202176988-66273c2fd55f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2071&q=80');"></div>
559
+ <div class="blog-card-content">
560
+ <h3 class="blog-card-title">Let's Grow Together</h3>
561
+ <p class="blog-card-date">May 27, 2024</p>
562
+ <a href="#" class="blog-card-link">VIEW THESE RESOURCES</a>
563
+ </div>
564
+ </article>
565
+ </div>
566
+
567
+ <!-- Pagination -->
568
+ <div class="pagination">
569
+ <a href="#" class="pagination-btn active">1</a>
570
+ <a href="#" class="pagination-btn">2</a>
571
+ <a href="#" class="pagination-btn">3</a>
572
+ <span style="color: var(--muted); margin: 0 0.5rem;">…</span>
573
+ <a href="#" class="pagination-btn">16</a>
574
+ <a href="#" class="pagination-btn">Next Β»</a>
575
+ </div>
576
+ </main>
577
+
578
+ <script>
579
+ // Simple navigation toggle for mobile
580
+ document.querySelector('.nav-toggle').addEventListener('click', function() {
581
+ document.querySelector('.nav-menu').classList.toggle('active');
582
+ });
583
+
584
+ // Dropdown click behavior
585
+ document.addEventListener('DOMContentLoaded', function() {
586
+ const dropdown = document.querySelector('.dropdown');
587
+ const dropdownToggle = document.querySelector('.dropdown-toggle');
588
+
589
+ if (dropdown && dropdownToggle) {
590
+ dropdownToggle.addEventListener('click', function(e) {
591
+ e.preventDefault();
592
+ dropdown.classList.toggle('active');
593
+ });
594
+
595
+ // Close dropdown when clicking outside
596
+ document.addEventListener('click', function(e) {
597
+ if (!dropdown.contains(e.target)) {
598
+ dropdown.classList.remove('active');
599
+ }
600
+ });
601
+
602
+ // Close dropdown when pressing Escape key
603
+ document.addEventListener('keydown', function(e) {
604
+ if (e.key === 'Escape') {
605
+ dropdown.classList.remove('active');
606
+ }
607
+ });
608
+ }
609
+ });
610
+ </script>
611
+ </body>
612
+ </html>
booknap project/books.html ADDED
@@ -0,0 +1,1072 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>All Books - booknap</title>
7
+ <link rel="stylesheet" href="styles.css" />
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" />
10
+ <style>
11
+ :root {
12
+ --bg: #0f172a;
13
+ --card: #0b1223;
14
+ --muted: #94a3b8;
15
+ --text: #e2e8f0;
16
+ --brand: #3b82f6;
17
+ --brand-2: #6366f1;
18
+ }
19
+ body {
20
+ background: linear-gradient(180deg, #0b1020, #0b1022 30%, #0b1124);
21
+ min-height: 100vh;
22
+ color: var(--text);
23
+ }
24
+ /* Match pricing header/nav styling */
25
+ .header { position: sticky; top: 0; -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); background: rgba(7,10,20,0.55); z-index: 20; box-shadow: none; }
26
+ .nav { border-bottom: 1px solid rgba(255,255,255,0.06); }
27
+ .nav-logo i { color: var(--brand); }
28
+ .nav-link { color: var(--muted); text-decoration: none; font-weight: 600; }
29
+ .nav-link:hover, .nav-link.active { color: var(--text); }
30
+ .login-btn { background: var(--brand); color: white; padding: 0.6rem 1.1rem; border-radius: 9px; text-decoration: none; font-weight: 700; display: inline-block; }
31
+
32
+ /* Improved Navigation Layout */
33
+ .nav-container {
34
+ max-width: 1200px;
35
+ margin: 0 auto;
36
+ padding: 0 20px;
37
+ display: flex;
38
+ align-items: center;
39
+ gap: 2rem;
40
+ }
41
+
42
+ .nav-logo {
43
+ display: flex;
44
+ align-items: center;
45
+ gap: 0.5rem;
46
+ font-size: 1.5rem;
47
+ font-weight: 700;
48
+ color: white;
49
+ flex-shrink: 0;
50
+ }
51
+
52
+ .nav-logo i {
53
+ color: var(--brand);
54
+ font-size: 1.8rem;
55
+ }
56
+
57
+ .nav-menu {
58
+ display: flex;
59
+ align-items: center;
60
+ gap: 2rem;
61
+ list-style: none;
62
+ margin: 0;
63
+ padding: 0;
64
+ flex: 1;
65
+ justify-content: center;
66
+ }
67
+
68
+ .nav-link {
69
+ color: var(--muted);
70
+ text-decoration: none;
71
+ font-weight: 600;
72
+ font-size: 0.95rem;
73
+ transition: color 0.2s ease;
74
+ padding: 0.5rem 0;
75
+ }
76
+
77
+ .nav-link:hover, .nav-link.active {
78
+ color: var(--text);
79
+ }
80
+
81
+ .nav-login {
82
+ display: flex;
83
+ align-items: center;
84
+ gap: 1rem;
85
+ flex-shrink: 0;
86
+ }
87
+ /* Guide Right-Swiping Tabs */
88
+ .guide-tabs-section {
89
+ padding: 2rem 0 5rem;
90
+ }
91
+ .guide-tabs-container {
92
+ max-width: 1200px;
93
+ margin: 0 auto;
94
+ padding: 0 10px;
95
+ display: flex;
96
+ flex-direction: column;
97
+ }
98
+ .guide-tabs-panels {
99
+ order: 1;
100
+ }
101
+ .guide-tabs-nav {
102
+ order: 2;
103
+ display: flex;
104
+ justify-content: center;
105
+ background: rgba(255, 255, 255, 0.1);
106
+ border-radius: 16px;
107
+ padding: 0.3rem;
108
+ box-shadow: 0 8px 24px rgba(0,0,0,0.08);
109
+ position: relative;
110
+ overflow: hidden;
111
+ margin: 2rem auto 0 auto;
112
+ gap: 0.25rem;
113
+ width: fit-content;
114
+ -webkit-backdrop-filter: blur(10px);
115
+ backdrop-filter: blur(10px);
116
+ }
117
+ .guide-tab-btn {
118
+ background: transparent;
119
+ border: 0;
120
+ padding: 0.75rem 1.25rem;
121
+ border-radius: 16px;
122
+ font-weight: 600;
123
+ color: rgba(255, 255, 255, 0.8);
124
+ cursor: pointer;
125
+ position: relative;
126
+ z-index: 2;
127
+ transition: color 0.25s ease;
128
+ white-space: nowrap;
129
+ }
130
+ .guide-tab-btn.active { color: #ffffff; }
131
+ .guide-tab-slider {
132
+ position: absolute;
133
+ top: 0.4rem;
134
+ left: 0.4rem;
135
+ height: calc(100% - 0.8rem);
136
+ border-radius: 16px;
137
+ background: linear-gradient(90deg, #3b82f6, #6366f1);
138
+ box-shadow: 0 8px 24px rgba(59, 130, 246, 0.35);
139
+ transition: all 320ms cubic-bezier(0.4, 0, 0.2, 1);
140
+ z-index: 1;
141
+ width: 0;
142
+ }
143
+
144
+ .guide-tabs-panels { position: relative; }
145
+ .guide-tab-panel { display: none; }
146
+ .guide-tab-panel.active { display: block; }
147
+
148
+ .guide-card {
149
+ display: grid;
150
+ grid-template-columns: 1.25fr 1fr;
151
+ gap: 0;
152
+ border-radius: 16px;
153
+ overflow: hidden;
154
+ background: rgba(255, 255, 255, 0.1);
155
+ box-shadow: 0 16px 40px rgba(0,0,0,0.12);
156
+ -webkit-backdrop-filter: blur(10px);
157
+ backdrop-filter: blur(10px);
158
+ }
159
+ .guide-info {
160
+ background: linear-gradient(90deg, #3b82f6, #6366f1);
161
+ color: #ffffff;
162
+ padding: 2rem 2rem 2rem 2rem;
163
+ display: flex;
164
+ flex-direction: column;
165
+ justify-content: center;
166
+ height: 260px;
167
+ }
168
+ .guide-title {
169
+ font-size: 1.8rem;
170
+ font-weight: 800;
171
+ line-height: 1.2;
172
+ margin: 0 0 0.75rem 0;
173
+ }
174
+ .guide-text { opacity: 0.95; margin: 0 0 1.25rem 0; }
175
+ .guide-cta {
176
+ display: inline-flex;
177
+ align-items: center;
178
+ gap: 0.5rem;
179
+ color: #ffffff;
180
+ font-weight: 600;
181
+ text-decoration: none;
182
+ border-bottom: 2px solid rgba(255,255,255,0.45);
183
+ width: fit-content;
184
+ padding-bottom: 2px;
185
+ }
186
+ .guide-cta i { transition: transform 0.2s ease; }
187
+ .guide-cta:hover i { transform: translateX(3px); }
188
+
189
+ .guide-image { position: relative; background: rgba(255, 255, 255, 0.1); height: 260px; }
190
+ .guide-image img {
191
+ width: 100%; height: 100%; object-fit: cover;
192
+ display: block;
193
+ }
194
+ /* Nudge Shakespeare image so face is more centered/visible */
195
+ #guide-shakespeare .guide-image img { object-position: 10% 25%; }
196
+ /* Nudge Jane Austen image so face is more centered/visible */
197
+ #guide-austen .guide-image img { object-position: 10% 20%; }
198
+ /* Nudge Charles Dickens image so face is more centered/visible */
199
+ #guide-dickens .guide-image img { object-position: 40% 25%; }
200
+
201
+ @media (max-width: 900px) {
202
+ .guide-card { grid-template-columns: 1fr; }
203
+ .guide-image { order: -1; }
204
+ }
205
+
206
+ /* Navigation Login Button */
207
+ .nav-container {
208
+ display: flex;
209
+ align-items: center;
210
+ gap: 2rem;
211
+ }
212
+
213
+ .nav-menu {
214
+ display: flex;
215
+ align-items: center;
216
+ gap: 2rem;
217
+ margin-left: auto;
218
+ }
219
+
220
+ .nav-login {
221
+ margin-left: 0;
222
+ }
223
+
224
+ .login-btn {
225
+ background: linear-gradient(90deg, #3b82f6, #6366f1);
226
+ color: white;
227
+ padding: 0.75rem 1.5rem;
228
+ border-radius: 8px;
229
+ text-decoration: none;
230
+ font-weight: 600;
231
+ transition: background-color 0.2s ease;
232
+ display: inline-block;
233
+ }
234
+
235
+ .login-btn:hover {
236
+ background: linear-gradient(90deg, #2563eb, #4f46e5);
237
+ }
238
+
239
+ .signup-btn {
240
+ background: transparent;
241
+ color: var(--text);
242
+ padding: 0.75rem 1.5rem;
243
+ border: 2px solid rgba(255, 255, 255, 0.2);
244
+ border-radius: 8px;
245
+ text-decoration: none;
246
+ font-weight: 600;
247
+ transition: all 0.2s ease;
248
+ display: inline-block;
249
+ margin-left: 0.5rem;
250
+ }
251
+
252
+ .signup-btn:hover {
253
+ background: rgba(255, 255, 255, 0.1);
254
+ border-color: rgba(255, 255, 255, 0.4);
255
+ }
256
+
257
+ /* Profile Picture Upload Styles */
258
+ .profile-upload {
259
+ position: relative;
260
+ margin-right: 1rem;
261
+ margin-left: 1.5rem;
262
+ display: inline-block;
263
+ }
264
+
265
+ .profile-avatar {
266
+ width: 40px;
267
+ height: 40px;
268
+ border-radius: 50%;
269
+ background: linear-gradient(135deg, #3b82f6, #8b5cf6);
270
+ border: 2px solid rgba(255, 255, 255, 0.2);
271
+ cursor: pointer;
272
+ display: flex;
273
+ align-items: center;
274
+ justify-content: center;
275
+ color: white;
276
+ font-weight: bold;
277
+ font-size: 16px;
278
+ transition: all 0.3s ease;
279
+ overflow: hidden;
280
+ }
281
+
282
+ .profile-avatar:hover {
283
+ border-color: rgba(255, 255, 255, 0.4);
284
+ transform: scale(1.05);
285
+ }
286
+
287
+ .profile-avatar img {
288
+ width: 100%;
289
+ height: 100%;
290
+ object-fit: cover;
291
+ border-radius: 50%;
292
+ }
293
+
294
+ .profile-upload input[type="file"] {
295
+ position: absolute;
296
+ opacity: 0;
297
+ width: 100%;
298
+ height: 100%;
299
+ cursor: pointer;
300
+ }
301
+
302
+ .profile-upload:hover .profile-avatar {
303
+ border-color: rgba(255, 255, 255, 0.4);
304
+ }
305
+
306
+ /* Search Bar Styles */
307
+ .search-container {
308
+ margin-left: 0.5rem;
309
+ flex: 1;
310
+ max-width: 400px;
311
+ margin: 0 2rem;
312
+ }
313
+
314
+ .search-bar {
315
+ position: relative;
316
+ display: flex;
317
+ align-items: center;
318
+ background: rgba(0, 0, 0, 0.3);
319
+ border: 1px solid rgba(255, 255, 255, 0.2);
320
+ border-radius: 25px;
321
+ padding: 0.5rem 1rem;
322
+ min-width: 300px;
323
+ transition: all 0.3s ease;
324
+ }
325
+
326
+ .search-bar:focus-within {
327
+ background: rgba(0, 0, 0, 0.4);
328
+ border-color: rgba(59, 130, 246, 0.5);
329
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
330
+ }
331
+
332
+ .search-icon {
333
+ color: rgba(255, 255, 255, 0.6);
334
+ margin-right: 0.75rem;
335
+ font-size: 0.9rem;
336
+ }
337
+
338
+ .search-input {
339
+ background: transparent;
340
+ border: none;
341
+ color: var(--text);
342
+ font-size: 0.9rem;
343
+ font-weight: 500;
344
+ width: 100%;
345
+ outline: none;
346
+ }
347
+
348
+ .search-input::placeholder {
349
+ color: rgba(255, 255, 255, 0.5);
350
+ }
351
+
352
+ .search-input:focus::placeholder {
353
+ color: rgba(255, 255, 255, 0.3);
354
+ }
355
+
356
+ /* Responsive Navigation */
357
+ @media (max-width: 1024px) {
358
+ .nav-container {
359
+ gap: 1rem;
360
+ }
361
+
362
+ .nav-menu {
363
+ gap: 1.5rem;
364
+ }
365
+
366
+ .search-container {
367
+ margin: 0 1rem;
368
+ max-width: 300px;
369
+ }
370
+ }
371
+
372
+ @media (max-width: 768px) {
373
+ .nav-container {
374
+ flex-wrap: wrap;
375
+ gap: 1rem;
376
+ }
377
+
378
+ .nav-menu {
379
+ order: 3;
380
+ width: 100%;
381
+ justify-content: center;
382
+ gap: 1rem;
383
+ margin-top: 1rem;
384
+ }
385
+
386
+ .search-container {
387
+ order: 2;
388
+ margin: 0;
389
+ max-width: 100%;
390
+ flex: 1;
391
+ }
392
+
393
+ .nav-login {
394
+ order: 1;
395
+ margin-left: auto;
396
+ }
397
+
398
+ .search-bar {
399
+ min-width: 200px;
400
+ }
401
+ }
402
+
403
+ @media (max-width: 600px) {
404
+ .nav-container {
405
+ padding: 0 15px;
406
+ }
407
+
408
+ .nav-menu {
409
+ gap: 0.75rem;
410
+ font-size: 0.9rem;
411
+ }
412
+
413
+ .search-container {
414
+ margin: 0;
415
+ }
416
+
417
+ .search-bar {
418
+ min-width: 150px;
419
+ padding: 0.4rem 0.8rem;
420
+ }
421
+
422
+ .nav-login {
423
+ gap: 0.75rem;
424
+ }
425
+
426
+ .profile-avatar {
427
+ width: 35px;
428
+ height: 35px;
429
+ font-size: 14px;
430
+ }
431
+
432
+ .login-btn, .signup-btn {
433
+ padding: 0.5rem 1rem;
434
+ font-size: 0.9rem;
435
+ }
436
+ }
437
+
438
+ /* Community Section (homepage hero under header) */
439
+ .community-section { background: transparent; padding: 4rem 0; margin-top: 0; }
440
+ .community-container {
441
+ max-width: 1200px;
442
+ margin: 0 auto;
443
+ padding: 0 20px;
444
+ display: grid;
445
+ grid-template-columns: 1fr 1fr;
446
+ gap: 4rem;
447
+ align-items: center;
448
+ }
449
+ .community-content { color: var(--text); }
450
+ .community-title { font-size: 3.5rem; font-weight: 800; line-height: 1.1; margin-bottom: 1.5rem; color: var(--text); }
451
+ .community-description { font-size: 1.125rem; line-height: 1.7; color: var(--muted); margin-bottom: 0; }
452
+ .community-image-wrap { display: flex; align-items: center; justify-content: center; min-height: 220px; }
453
+ .community-image { width: 100%; max-width: 380px; height: auto; border-radius: 12px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08); object-fit: contain; display: block; }
454
+
455
+ @media (max-width: 768px) {
456
+ .community-container { grid-template-columns: 1fr; gap: 2rem; }
457
+ .community-title { font-size: 2.5rem; }
458
+ }
459
+
460
+ /* Dropdown Menu Styles */
461
+ .dropdown {
462
+ position: relative;
463
+ }
464
+
465
+ .dropdown-toggle {
466
+ display: flex;
467
+ align-items: center;
468
+ gap: 0.5rem;
469
+ }
470
+
471
+ .dropdown-toggle i {
472
+ font-size: 0.8rem;
473
+ transition: transform 0.2s ease;
474
+ }
475
+
476
+ .dropdown.active .dropdown-toggle i {
477
+ transform: rotate(180deg);
478
+ }
479
+
480
+ .dropdown-menu {
481
+ position: absolute;
482
+ top: 100%;
483
+ left: 50%;
484
+ transform: translateX(-50%);
485
+ background: rgba(15, 23, 42, 0.95);
486
+ border: 1px solid rgba(255, 255, 255, 0.1);
487
+ border-radius: 12px;
488
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
489
+ min-width: 500px;
490
+ opacity: 0;
491
+ visibility: hidden;
492
+ transition: all 0.3s ease;
493
+ z-index: 1000;
494
+ margin-top: 1rem;
495
+ -webkit-backdrop-filter: blur(10px);
496
+ backdrop-filter: blur(10px);
497
+ }
498
+
499
+ .dropdown.active .dropdown-menu {
500
+ opacity: 1;
501
+ visibility: visible;
502
+ }
503
+
504
+ .dropdown-content {
505
+ display: flex;
506
+ padding: 2rem;
507
+ }
508
+
509
+ .dropdown-section {
510
+ flex: 1;
511
+ }
512
+
513
+ .dropdown-section h4 {
514
+ color: #e2e8f0;
515
+ font-size: 0.875rem;
516
+ font-weight: 600;
517
+ margin: 0 0 1rem 0;
518
+ text-transform: uppercase;
519
+ letter-spacing: 0.05em;
520
+ }
521
+
522
+ .dropdown-section ul {
523
+ list-style: none;
524
+ margin: 0;
525
+ padding: 0;
526
+ }
527
+
528
+ .dropdown-section li {
529
+ margin-bottom: 0.75rem;
530
+ }
531
+
532
+ .dropdown-section a {
533
+ display: flex;
534
+ align-items: center;
535
+ gap: 0.75rem;
536
+ color: #94a3b8;
537
+ text-decoration: none;
538
+ font-size: 0.875rem;
539
+ padding: 0.5rem;
540
+ border-radius: 8px;
541
+ transition: all 0.2s ease;
542
+ }
543
+
544
+ .dropdown-section a:hover {
545
+ background: rgba(255, 255, 255, 0.1);
546
+ color: #e2e8f0;
547
+ }
548
+
549
+ .dropdown-section i {
550
+ font-size: 1rem;
551
+ width: 20px;
552
+ text-align: center;
553
+ }
554
+
555
+ .dropdown-divider {
556
+ width: 1px;
557
+ background: rgba(255, 255, 255, 0.2);
558
+ margin: 0 1.5rem;
559
+ }
560
+
561
+ .all-categories {
562
+ color: #60a5fa !important;
563
+ font-weight: 500;
564
+ margin-top: 1rem;
565
+ display: inline-flex;
566
+ align-items: center;
567
+ gap: 0.5rem;
568
+ }
569
+
570
+ .all-categories:hover {
571
+ background: rgba(59, 130, 246, 0.2) !important;
572
+ color: #93c5fd !important;
573
+ }
574
+
575
+ .all-categories i {
576
+ font-size: 0.75rem;
577
+ transition: transform 0.2s ease;
578
+ }
579
+
580
+ .all-categories:hover i {
581
+ transform: translateX(3px);
582
+ }
583
+
584
+ /* Books Grid Section */
585
+ .books-grid-section {
586
+ padding: 4rem 0;
587
+ background: linear-gradient(135deg, #0b1020, #0b1022 30%, #0b1124);
588
+ }
589
+
590
+ .books-grid {
591
+ display: grid;
592
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
593
+ gap: 2rem;
594
+ margin-top: 2rem;
595
+ }
596
+
597
+ .book-card {
598
+ background: rgba(255, 255, 255, 0.1);
599
+ border-radius: 15px;
600
+ overflow: hidden;
601
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
602
+ transition: all 0.3s ease;
603
+ cursor: pointer;
604
+ -webkit-backdrop-filter: blur(10px);
605
+ backdrop-filter: blur(10px);
606
+ }
607
+
608
+ .book-card:hover {
609
+ transform: translateY(-10px);
610
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
611
+ background: rgba(255, 255, 255, 0.15);
612
+ }
613
+
614
+ .book-cover {
615
+ position: relative;
616
+ height: 200px;
617
+ overflow: hidden;
618
+ }
619
+
620
+ .book-cover img {
621
+ width: 100%;
622
+ height: 100%;
623
+ object-fit: cover;
624
+ transition: transform 0.3s ease;
625
+ }
626
+
627
+ .book-card:hover .book-cover img {
628
+ transform: scale(1.05);
629
+ }
630
+
631
+ .book-overlay {
632
+ position: absolute;
633
+ top: 0;
634
+ left: 0;
635
+ right: 0;
636
+ bottom: 0;
637
+ background: rgba(59, 130, 246, 0.8);
638
+ display: flex;
639
+ align-items: center;
640
+ justify-content: center;
641
+ opacity: 0;
642
+ transition: opacity 0.3s ease;
643
+ }
644
+
645
+ .book-overlay i {
646
+ color: white;
647
+ font-size: 2rem;
648
+ }
649
+
650
+ .book-card:hover .book-overlay {
651
+ opacity: 1;
652
+ }
653
+
654
+ .book-info {
655
+ padding: 1.5rem;
656
+ }
657
+
658
+ .book-info h3 {
659
+ font-size: 1.25rem;
660
+ font-weight: 600;
661
+ color: white;
662
+ margin-bottom: 0.5rem;
663
+ line-height: 1.3;
664
+ }
665
+
666
+ .book-info .book-author {
667
+ color: rgba(255, 255, 255, 0.8);
668
+ font-size: 0.875rem;
669
+ margin-bottom: 0.25rem;
670
+ }
671
+
672
+ .book-info .book-category {
673
+ background: rgba(255, 255, 255, 0.2);
674
+ color: white;
675
+ padding: 0.25rem 0.75rem;
676
+ border-radius: 15px;
677
+ font-size: 0.75rem;
678
+ font-weight: 600;
679
+ display: inline-block;
680
+ margin-bottom: 0.75rem;
681
+ }
682
+
683
+ .book-info .book-description {
684
+ color: rgba(255, 255, 255, 0.7);
685
+ font-size: 0.875rem;
686
+ line-height: 1.5;
687
+ }
688
+
689
+ /* Responsive navigation adjustments */
690
+ @media (max-width: 768px) {
691
+ .nav-login {
692
+ margin-left: 0;
693
+ margin-top: 1rem;
694
+ }
695
+
696
+ .dropdown-menu {
697
+ min-width: 300px;
698
+ left: 0;
699
+ transform: none;
700
+ }
701
+
702
+ .dropdown-content {
703
+ flex-direction: column;
704
+ padding: 1.5rem;
705
+ }
706
+
707
+ .dropdown-divider {
708
+ width: 100%;
709
+ height: 1px;
710
+ margin: 1rem 0;
711
+ }
712
+
713
+ .books-grid {
714
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
715
+ gap: 1.5rem;
716
+ }
717
+ }
718
+ </style>
719
+ </head>
720
+ <body>
721
+ <header class="header">
722
+ <nav class="nav">
723
+ <div class="nav-container">
724
+ <div class="nav-logo">
725
+ <i class="fas fa-book-open"></i>
726
+ <span>booknap</span>
727
+ </div>
728
+ <div class="search-container">
729
+ <div class="search-bar">
730
+ <i class="fas fa-search search-icon"></i>
731
+ <input type="text" placeholder="Find a book..." class="search-input">
732
+ </div>
733
+ </div>
734
+ <ul class="nav-menu">
735
+ <li><a href="books.html" class="nav-link active">Home</a></li>
736
+ <li class="dropdown">
737
+ <a href="#" class="nav-link dropdown-toggle">Book Summaries <i class="fas fa-chevron-down"></i></a>
738
+ <div class="dropdown-menu">
739
+ <div class="dropdown-content">
740
+ <div class="dropdown-section">
741
+ <h4>Browse by type</h4>
742
+ <ul>
743
+ <li><a href="#"><i class="fas fa-book-open" style="color: #10b981;"></i> Text Summaries</a></li>
744
+ <li><a href="#"><i class="fas fa-headphones" style="color: #3b82f6;"></i> Audio Summaries</a></li>
745
+ <li><a href="#"><i class="fas fa-play-circle" style="color: #8b5cf6;"></i> Video Summaries</a></li>
746
+ <li><a href="#"><i class="fas fa-file-pdf" style="color: #f59e0b;"></i> PDF Downloads</a></li>
747
+ <li><a href="#"><i class="fas fa-mobile-alt" style="color: #06b6d4;"></i> Mobile App</a></li>
748
+ </ul>
749
+ </div>
750
+ <div class="dropdown-divider"></div>
751
+ <div class="dropdown-section">
752
+ <h4>Browse by topic</h4>
753
+ <ul>
754
+ <li><a href="#"><i class="fas fa-brain" style="color: #f59e0b;"></i> Psychology</a></li>
755
+ <li><a href="#"><i class="fas fa-chart-line" style="color: #10b981;"></i> Business</a></li>
756
+ <li><a href="#"><i class="chevron-down"></i> Self-Help</a></li>
757
+ <li><a href="#"><i class="fas fa-graduation-cap" style="color: #8b5cf6;"></i> Education</a></li>
758
+ <li><a href="#"><i class="fas fa-lightbulb" style="color: #06b6d4;"></i> Innovation</a></li>
759
+ </ul>
760
+ <a href="#" class="all-categories">all categories <i class="fas fa-arrow-right"></i></a>
761
+ </div>
762
+ </div>
763
+ </div>
764
+ </li>
765
+ <li><a href="pricing.html" class="nav-link">Pricing</a></li>
766
+ <li><a href="blog.html" class="nav-link">Blog</a></li>
767
+ </ul>
768
+ <div class="nav-login">
769
+ <a href="login.html" class="login-btn">Login</a>
770
+ <a href="signup.html" class="signup-btn">Sign Up</a>
771
+ <div class="profile-upload">
772
+ <label for="profileInput" class="profile-avatar" id="profileAvatar" title="Click to upload profile picture">
773
+ <span>U</span>
774
+ </label>
775
+ <input type="file" id="profileInput" accept="image/*" onchange="updateProfilePicture(event)" aria-label="Upload profile picture">
776
+ </div>
777
+ </div>
778
+ <div class="nav-toggle">
779
+ <span></span>
780
+ <span></span>
781
+ <span></span>
782
+ </div>
783
+ </div>
784
+ </nav>
785
+ </header>
786
+
787
+ <main>
788
+ <!-- Community Section under header -->
789
+ <section class="community-section">
790
+ <div class="community-container">
791
+ <div class="community-content">
792
+ <h1 class="community-title">
793
+ Level up with the largest<br>
794
+ <span style="color: #3b82f6;">reading community</span>
795
+ </h1>
796
+ <p class="community-description">
797
+ Join book lovers to share insights, discuss ideas, and stay up-to-date on all the latest books and reading techniques.
798
+ </p>
799
+ </div>
800
+ <div class="community-image-wrap">
801
+ <img class="community-image" src="https://i.pinimg.com/736x/f4/a0/48/f4a0480397a1c019a2a1a238b2ffc594.jpg" alt="Reading illustration" />
802
+ </div>
803
+ </div>
804
+ </section>
805
+
806
+
807
+ <!-- Right-swiping tabs (matching screenshot layout) -->
808
+ <section class="guide-tabs-section">
809
+ <div class="guide-tabs-container">
810
+ <div class="guide-tabs-nav" role="tablist" aria-label="Author guides">
811
+ <div class="guide-tab-slider" aria-hidden="true"></div>
812
+ <button class="guide-tab-btn active" role="tab" aria-selected="true" aria-controls="guide-dickens" id="tab-dickens">Dickens</button>
813
+ <button class="guide-tab-btn" role="tab" aria-selected="false" aria-controls="guide-austen" id="tab-austen">Austen</button>
814
+ <button class="guide-tab-btn" role="tab" aria-selected="false" aria-controls="guide-shakespeare" id="tab-shakespeare">Shakespeare</button>
815
+ </div>
816
+
817
+ <div class="guide-tabs-panels">
818
+ <!-- Charles Dickens (now first) -->
819
+ <div class="guide-tab-panel active" id="guide-dickens" role="tabpanel" aria-labelledby="tab-dickens">
820
+ <div class="guide-card">
821
+ <div class="guide-info">
822
+ <h2 class="guide-title">Charles Dickens' London</h2>
823
+ <p class="guide-text">Walk the foggy streets of Victorian London and uncover the life and times that shaped Dickens' unforgettable characters.</p>
824
+ <a class="guide-cta" href="#"><span>Read the guide</span> <i class="fas fa-arrow-right"></i></a>
825
+ </div>
826
+ <div class="guide-image">
827
+ <img alt="Charles Dickens" src="https://www.historic-uk.com/wp-content/uploads/2019/06/dickens-in-study.jpg" />
828
+ </div>
829
+ </div>
830
+ </div>
831
+
832
+ <!-- Jane Austen (remains second) -->
833
+ <div class="guide-tab-panel" id="guide-austen" role="tabpanel" aria-labelledby="tab-austen">
834
+ <div class="guide-card">
835
+ <div class="guide-info">
836
+ <h2 class="guide-title">Jane Austen's World</h2>
837
+ <p class="guide-text">Explore the Regency era, societal norms, and the life behind the beloved novels. Perfect for essays and deeper reading.</p>
838
+ <a class="guide-cta" href="#"><span>Read the guide</span> <i class="fas fa-arrow-right"></i></a>
839
+ </div>
840
+ <div class="guide-image">
841
+ <img alt="Jane Austen" src="https://wordsworth-editions.com/wp-content/uploads/2022/02/jane-austen.jpg" />
842
+ </div>
843
+ </div>
844
+ </div>
845
+
846
+ <!-- William Shakespeare (now third) -->
847
+ <div class="guide-tab-panel" id="guide-shakespeare" role="tabpanel" aria-labelledby="tab-shakespeare">
848
+ <div class="guide-card">
849
+ <div class="guide-info">
850
+ <h2 class="guide-title">William Shakespeare's Life & Times</h2>
851
+ <p class="guide-text">Our comprehensive guide includes a detailed biography, social and historical context, quotes, and more to help you write your essay on Shakespeare or understand his plays and poems.</p>
852
+ <a class="guide-cta" href="#"><span>Read the guide</span> <i class="fas fa-arrow-right"></i></a>
853
+ </div>
854
+ <div class="guide-image">
855
+ <img alt="William Shakespeare" src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/Shakespeare.jpg/640px-Shakespeare.jpg" />
856
+ </div>
857
+ </div>
858
+ </div>
859
+ </div>
860
+ </div>
861
+ </section>
862
+
863
+ <section class="books-grid-section">
864
+ <div class="container">
865
+ <div class="books-grid">
866
+ <div class="book-card" onclick="window.location.href='book.html?id=1'">
867
+ <div class="book-cover">
868
+ <img src="assets/covers/atomic-habits.svg" alt="Atomic Habits" />
869
+ <div class="book-overlay"><i class="fas fa-play"></i></div>
870
+ </div>
871
+ <div class="book-info">
872
+ <h3>Atomic Habits</h3>
873
+ <p class="book-author">James Clear</p>
874
+ <p class="book-category">Self-Help</p>
875
+ <p class="book-description">Learn how tiny changes create remarkable results in your life.</p>
876
+ </div>
877
+ </div>
878
+
879
+ <div class="book-card" onclick="window.location.href='book.html?id=2'">
880
+ <div class="book-cover">
881
+ <img src="assets/covers/thinking-fast-slow.svg" alt="Thinking, Fast and Slow" />
882
+ <div class="book-overlay"><i class="fas fa-play"></i></div>
883
+ </div>
884
+ <div class="book-info">
885
+ <h3>Thinking, Fast and Slow</h3>
886
+ <p class="book-author">Daniel Kahneman</p>
887
+ <p class="book-category">Psychology</p>
888
+ <p class="book-description">Understanding the two systems that drive the way we think.</p>
889
+ </div>
890
+ </div>
891
+
892
+ <div class="book-card" onclick="window.location.href='book.html?id=3'">
893
+ <div class="book-cover">
894
+ <img src="assets/covers/7-habits.svg" alt="The 7 Habits of Highly Effective People" />
895
+ <div class="book-overlay"><i class="fas fa-play"></i></div>
896
+ </div>
897
+ <div class="book-info">
898
+ <h3>The 7 Habits of Highly Effective People</h3>
899
+ <p class="book-author">Stephen R. Covey</p>
900
+ <p class="book-category">Self-Help</p>
901
+ <p class="book-description">Powerful lessons in personal change and effectiveness.</p>
902
+ </div>
903
+ </div>
904
+
905
+ <div class="book-card" onclick="window.location.href='book.html?id=4'">
906
+ <div class="book-cover">
907
+ <img src="assets/covers/rich-dad-poor-dad.svg" alt="Rich Dad Poor Dad" />
908
+ <div class="book-overlay"><i class="fas fa-play"></i></div>
909
+ </div>
910
+ <div class="book-info">
911
+ <h3>Rich Dad Poor Dad</h3>
912
+ <p class="book-author">Robert T. Kiyosaki</p>
913
+ <p class="book-category">Finance</p>
914
+ <p class="book-description">What the rich teach their kids about money.</p>
915
+ </div>
916
+ </div>
917
+
918
+ <div class="book-card" onclick="window.location.href='book.html?id=5'">
919
+ <div class="book-cover">
920
+ <img src="assets/covers/zero-to-one.svg" alt="Zero to One" />
921
+ <div class="book-overlay"><i class="fas fa-play"></i></div>
922
+ </div>
923
+ <div class="book-info">
924
+ <h3>Zero to One</h3>
925
+ <p class="book-author">Peter Thiel</p>
926
+ <p class="book-category">Business</p>
927
+ <p class="book-description">Notes on startups, or how to build the future.</p>
928
+ </div>
929
+ </div>
930
+
931
+ <div class="book-card" onclick="window.location.href='book.html?id=6'">
932
+ <div class="book-cover">
933
+ <img src="assets/covers/start-with-why.svg" alt="Start With Why" />
934
+ <div class="book-overlay"><i class="fas fa-play"></i></div>
935
+ </div>
936
+ <div class="book-info">
937
+ <h3>Start With Why</h3>
938
+ <p class="book-author">Simon Sinek</p>
939
+ <p class="book-category">Leadership</p>
940
+ <p class="book-description">How great leaders inspire everyone to take action.</p>
941
+ </div>
942
+ </div>
943
+ </div>
944
+ </div>
945
+ </section>
946
+ </main>
947
+
948
+ <footer class="footer">
949
+ <div class="container">
950
+ <p>&copy; 2024 booknap. All rights reserved.</p>
951
+ </div>
952
+ </footer>
953
+
954
+ <script src="script.js"></script>
955
+ <script>
956
+ // Dropdown click behavior
957
+ (function() {
958
+ const dropdown = document.querySelector('.dropdown');
959
+ const dropdownToggle = document.querySelector('.dropdown-toggle');
960
+
961
+ if (dropdown && dropdownToggle) {
962
+ dropdownToggle.addEventListener('click', function(e) {
963
+ e.preventDefault();
964
+ e.stopPropagation();
965
+ dropdown.classList.toggle('active');
966
+ });
967
+
968
+ // Close dropdown when clicking outside
969
+ document.addEventListener('click', function(e) {
970
+ if (!dropdown.contains(e.target)) {
971
+ dropdown.classList.remove('active');
972
+ }
973
+ });
974
+
975
+ // Close dropdown when pressing Escape key
976
+ document.addEventListener('keydown', function(e) {
977
+ if (e.key === 'Escape') {
978
+ dropdown.classList.remove('active');
979
+ }
980
+ });
981
+ }
982
+ })();
983
+
984
+ // Guide right-swiping tabs behavior
985
+ (function() {
986
+ const nav = document.querySelector('.guide-tabs-nav');
987
+ if (!nav) return;
988
+ const buttons = Array.from(nav.querySelectorAll('.guide-tab-btn'));
989
+ const slider = nav.querySelector('.guide-tab-slider');
990
+ const panels = Array.from(document.querySelectorAll('.guide-tab-panel'));
991
+
992
+ function activate(idx) {
993
+ buttons.forEach((b, i) => {
994
+ const isActive = i === idx;
995
+ b.classList.toggle('active', isActive);
996
+ b.setAttribute('aria-selected', String(isActive));
997
+ panels[i].classList.toggle('active', isActive);
998
+ });
999
+ const activeBtn = buttons[idx];
1000
+ if (activeBtn && slider) {
1001
+ slider.style.width = activeBtn.offsetWidth + 'px';
1002
+ slider.style.left = activeBtn.offsetLeft + 'px'; // swipe right visual
1003
+ }
1004
+ activeIndex = idx;
1005
+ }
1006
+
1007
+ let activeIndex = buttons.findIndex(b => b.classList.contains('active'));
1008
+ if (activeIndex < 0) activeIndex = 0;
1009
+ // init slider position after layout
1010
+ window.requestAnimationFrame(() => activate(activeIndex));
1011
+
1012
+ buttons.forEach((btn, i) => btn.addEventListener('click', () => activate(i)));
1013
+
1014
+ // Touch swipe support on the whole tabs section
1015
+ const swipeHost = document.querySelector('.guide-tabs-section');
1016
+ let touchStartX = 0;
1017
+ let touchEndX = 0;
1018
+ const threshold = 40; // px
1019
+
1020
+ function handleGesture() {
1021
+ const dx = touchEndX - touchStartX;
1022
+ if (Math.abs(dx) < threshold) return;
1023
+ if (dx < 0) {
1024
+ // swipe left -> next (slider moves right)
1025
+ activate(Math.min(activeIndex + 1, buttons.length - 1));
1026
+ } else {
1027
+ // swipe right -> prev
1028
+ activate(Math.max(activeIndex - 1, 0));
1029
+ }
1030
+ }
1031
+
1032
+ if (swipeHost) {
1033
+ swipeHost.addEventListener('touchstart', e => { touchStartX = e.changedTouches[0].clientX; }, { passive: true });
1034
+ swipeHost.addEventListener('touchend', e => { touchEndX = e.changedTouches[0].clientX; handleGesture(); }, { passive: true });
1035
+ }
1036
+
1037
+ // Reposition slider on resize
1038
+ window.addEventListener('resize', () => activate(activeIndex));
1039
+ })();
1040
+
1041
+ // Profile picture update function
1042
+ function updateProfilePicture(event) {
1043
+ const file = event.target.files[0];
1044
+ if (file) {
1045
+ if (file.type.startsWith('image/')) {
1046
+ const reader = new FileReader();
1047
+ reader.onload = function(e) {
1048
+ const profileAvatar = document.getElementById('profileAvatar');
1049
+ profileAvatar.innerHTML = `<img src="${e.target.result}" alt="Profile picture">`;
1050
+
1051
+ // Store in localStorage for persistence
1052
+ localStorage.setItem('profilePicture', e.target.result);
1053
+ };
1054
+ reader.readAsDataURL(file);
1055
+ } else {
1056
+ alert('Please select a valid image file.');
1057
+ }
1058
+ }
1059
+ }
1060
+
1061
+ // Load saved profile picture on page load
1062
+ document.addEventListener('DOMContentLoaded', function() {
1063
+ const savedPicture = localStorage.getItem('profilePicture');
1064
+ if (savedPicture) {
1065
+ const profileAvatar = document.getElementById('profileAvatar');
1066
+ profileAvatar.innerHTML = `<img src="${savedPicture}" alt="Profile picture">`;
1067
+ }
1068
+ });
1069
+ </script>
1070
+ </body>
1071
+ </html>
1072
+
booknap project/business-leaders.html ADDED
@@ -0,0 +1,376 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Booknap - News & Business Wisdom</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" />
9
+ <style>
10
+ :root {
11
+ --bg: #0f172a;
12
+ --card: #0b1223;
13
+ --muted: #94a3b8;
14
+ --text: #e2e8f0;
15
+ --brand: #3b82f6;
16
+ --brand-2: #6366f1;
17
+ }
18
+
19
+ body {
20
+ font-family: 'Inter', sans-serif;
21
+ background: linear-gradient(180deg, #0b1020, #0b1022 30%, #0b1124);
22
+ color: var(--text);
23
+ margin: 0;
24
+ padding: 0;
25
+ }
26
+
27
+ .container {
28
+ max-width: 1200px;
29
+ margin: 0 auto;
30
+ padding: 20px;
31
+ }
32
+
33
+ .header {
34
+ text-align: center;
35
+ margin-bottom: 3rem;
36
+ }
37
+
38
+ .header h1 {
39
+ font-size: 3rem;
40
+ font-weight: 700;
41
+ margin-bottom: 1rem;
42
+ background: linear-gradient(135deg, #3b82f6, #6366f1);
43
+ -webkit-background-clip: text;
44
+ -webkit-text-fill-color: transparent;
45
+ background-clip: text;
46
+ }
47
+
48
+ .header p {
49
+ font-size: 1.25rem;
50
+ color: var(--muted);
51
+ line-height: 1.6;
52
+ }
53
+
54
+ /* Tab Navigation */
55
+ .tab-nav {
56
+ display: flex;
57
+ justify-content: center;
58
+ gap: 1rem;
59
+ margin-bottom: 3rem;
60
+ background: rgba(255, 255, 255, 0.05);
61
+ border-radius: 16px;
62
+ padding: 0.5rem;
63
+ max-width: 500px;
64
+ margin-left: auto;
65
+ margin-right: auto;
66
+ }
67
+
68
+ .tab-btn {
69
+ background: transparent;
70
+ border: none;
71
+ color: var(--muted);
72
+ padding: 0.75rem 1.5rem;
73
+ border-radius: 12px;
74
+ cursor: pointer;
75
+ font-weight: 600;
76
+ transition: all 0.3s ease;
77
+ flex: 1;
78
+ }
79
+
80
+ .tab-btn.active {
81
+ background: var(--brand);
82
+ color: white;
83
+ }
84
+
85
+ .tab-btn:hover:not(.active) {
86
+ color: var(--text);
87
+ }
88
+
89
+ /* Tab Content */
90
+ .tab-content {
91
+ display: none;
92
+ }
93
+
94
+ .tab-content.active {
95
+ display: block;
96
+ }
97
+
98
+ /* Grid Layout */
99
+ .grid {
100
+ display: grid;
101
+ grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
102
+ gap: 2rem;
103
+ }
104
+
105
+ /* News Cards */
106
+ .news-card {
107
+ background: rgba(255, 255, 255, 0.05);
108
+ border-radius: 16px;
109
+ overflow: hidden;
110
+ border: 1px solid rgba(255, 255, 255, 0.1);
111
+ transition: transform 0.3s ease;
112
+ }
113
+
114
+ .news-card:hover {
115
+ transform: translateY(-8px);
116
+ }
117
+
118
+ .news-card-image {
119
+ width: 100%;
120
+ height: 200px;
121
+ background-size: cover;
122
+ background-position: center;
123
+ }
124
+
125
+ .news-card-content {
126
+ padding: 1.5rem;
127
+ }
128
+
129
+ .news-card-title {
130
+ font-size: 1.25rem;
131
+ font-weight: 600;
132
+ margin-bottom: 0.5rem;
133
+ }
134
+
135
+ .news-card-date {
136
+ color: var(--muted);
137
+ font-size: 0.875rem;
138
+ margin-bottom: 1rem;
139
+ }
140
+
141
+ /* Business Wisdom Cards */
142
+ .wisdom-card {
143
+ background: rgba(255, 255, 255, 0.05);
144
+ border-radius: 16px;
145
+ padding: 2rem;
146
+ border: 1px solid rgba(255, 255, 255, 0.1);
147
+ transition: transform 0.3s ease;
148
+ position: relative;
149
+ overflow: hidden;
150
+ }
151
+
152
+ .wisdom-card:hover {
153
+ transform: translateY(-8px);
154
+ }
155
+
156
+ .wisdom-card::before {
157
+ content: '"';
158
+ position: absolute;
159
+ top: 1rem;
160
+ left: 1.5rem;
161
+ font-size: 4rem;
162
+ color: var(--brand);
163
+ opacity: 0.3;
164
+ font-family: serif;
165
+ }
166
+
167
+ .wisdom-quote {
168
+ font-size: 1.1rem;
169
+ line-height: 1.6;
170
+ margin-bottom: 1.5rem;
171
+ font-style: italic;
172
+ color: var(--text);
173
+ }
174
+
175
+ .wisdom-author {
176
+ font-weight: 600;
177
+ color: var(--brand);
178
+ margin-bottom: 0.5rem;
179
+ }
180
+
181
+ .wisdom-meta {
182
+ color: var(--muted);
183
+ font-size: 0.875rem;
184
+ }
185
+
186
+ .loading {
187
+ text-align: center;
188
+ padding: 3rem;
189
+ color: var(--muted);
190
+ }
191
+
192
+ .error {
193
+ text-align: center;
194
+ padding: 3rem;
195
+ color: #ef4444;
196
+ }
197
+
198
+ /* Responsive */
199
+ @media (max-width: 768px) {
200
+ .header h1 {
201
+ font-size: 2rem;
202
+ }
203
+
204
+ .tab-nav {
205
+ flex-direction: column;
206
+ }
207
+
208
+ .grid {
209
+ grid-template-columns: 1fr;
210
+ }
211
+ }
212
+ </style>
213
+ </head>
214
+ <body>
215
+ <div class="container">
216
+ <div class="header">
217
+ <h1>News & Business Wisdom</h1>
218
+ <p>Stay informed with the latest news and inspired by wisdom from business leaders</p>
219
+ </div>
220
+
221
+ <!-- Tab Navigation -->
222
+ <div class="tab-nav">
223
+ <button class="tab-btn active" onclick="showTab('news')">
224
+ <i class="fas fa-newspaper"></i> Latest News
225
+ </button>
226
+ <button class="tab-btn" onclick="showTab('wisdom')">
227
+ <i class="fas fa-lightbulb"></i> Business Wisdom
228
+ </button>
229
+ </div>
230
+
231
+ <!-- News Tab -->
232
+ <div id="news-tab" class="tab-content active">
233
+ <div class="grid" id="news-grid">
234
+ <div class="loading">Loading news...</div>
235
+ </div>
236
+ </div>
237
+
238
+ <!-- Business Wisdom Tab -->
239
+ <div id="wisdom-tab" class="tab-content">
240
+ <div class="grid" id="wisdom-grid">
241
+ <div class="loading">Loading business wisdom...</div>
242
+ </div>
243
+ </div>
244
+ </div>
245
+
246
+ <script>
247
+ // Tab functionality
248
+ function showTab(tabName) {
249
+ // Hide all tabs
250
+ document.querySelectorAll('.tab-content').forEach(tab => {
251
+ tab.classList.remove('active');
252
+ });
253
+
254
+ // Remove active class from all buttons
255
+ document.querySelectorAll('.tab-btn').forEach(btn => {
256
+ btn.classList.remove('active');
257
+ });
258
+
259
+ // Show selected tab
260
+ document.getElementById(tabName + '-tab').classList.add('active');
261
+
262
+ // Add active class to clicked button
263
+ event.target.classList.add('active');
264
+
265
+ // Load data for the selected tab
266
+ if (tabName === 'news') {
267
+ loadNewsData();
268
+ } else if (tabName === 'wisdom') {
269
+ loadWisdomData();
270
+ }
271
+ }
272
+
273
+ // Load news data
274
+ async function loadNewsData() {
275
+ try {
276
+ const response = await fetch('/api/news');
277
+ const newsData = await response.json();
278
+
279
+ if (newsData.error) {
280
+ document.getElementById('news-grid').innerHTML =
281
+ `<div class="error">Error loading news: ${newsData.error}</div>`;
282
+ return;
283
+ }
284
+
285
+ displayNewsData(newsData);
286
+
287
+ } catch (error) {
288
+ document.getElementById('news-grid').innerHTML =
289
+ '<div class="error">Error loading news data</div>';
290
+ }
291
+ }
292
+
293
+ // Display news data
294
+ function displayNewsData(newsData) {
295
+ const newsGrid = document.getElementById('news-grid');
296
+
297
+ if (newsData.length === 0) {
298
+ newsGrid.innerHTML = '<div class="loading">No news articles found.</div>';
299
+ return;
300
+ }
301
+
302
+ const imageUrls = [
303
+ 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=500',
304
+ 'https://images.unsplash.com/photo-1544716278-ca5e3f4abd8c?w=500',
305
+ 'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=500',
306
+ 'https://images.unsplash.com/photo-1522202176988-66273c2fd55f?w=500',
307
+ 'https://images.unsplash.com/photo-1554224155-6726b3ff858f?w=500'
308
+ ];
309
+
310
+ newsGrid.innerHTML = newsData.map((article, index) => `
311
+ <article class="news-card">
312
+ <div class="news-card-image" style="background-image: url('${imageUrls[index % imageUrls.length]}');"></div>
313
+ <div class="news-card-content">
314
+ <h3 class="news-card-title">${article.title}</h3>
315
+ <p class="news-card-date">${article.date} β€’ ${article.source} β€’ ${article.category}</p>
316
+ <p style="color: var(--muted); font-size: 0.875rem; margin-bottom: 1rem;">${article.description}</p>
317
+ <a href="#" style="color: var(--brand); text-decoration: none; font-weight: 600; font-size: 0.875rem; text-transform: uppercase;">READ MORE</a>
318
+ </div>
319
+ </article>
320
+ `).join('');
321
+ }
322
+
323
+ // Load business wisdom data
324
+ async function loadWisdomData() {
325
+ try {
326
+ const response = await fetch('/api/business-leaders');
327
+ const wisdomData = await response.json();
328
+
329
+ if (wisdomData.error) {
330
+ document.getElementById('wisdom-grid').innerHTML =
331
+ `<div class="error">Error loading wisdom: ${wisdomData.error}</div>`;
332
+ return;
333
+ }
334
+
335
+ displayWisdomData(wisdomData);
336
+
337
+ } catch (error) {
338
+ document.getElementById('wisdom-grid').innerHTML =
339
+ '<div class="error">Error loading business wisdom data</div>';
340
+ }
341
+ }
342
+
343
+ // Display business wisdom data
344
+ function displayWisdomData(wisdomData) {
345
+ const wisdomGrid = document.getElementById('wisdom-grid');
346
+
347
+ if (wisdomData.length === 0) {
348
+ wisdomGrid.innerHTML = '<div class="loading">No wisdom quotes found.</div>';
349
+ return;
350
+ }
351
+
352
+ wisdomGrid.innerHTML = wisdomData.map(quote => `
353
+ <article class="wisdom-card">
354
+ <p class="wisdom-quote">${quote.quote}</p>
355
+ <div class="wisdom-author">β€” ${quote.author}</div>
356
+ <div class="wisdom-meta">
357
+ ${quote.category} β€’ ${quote.year} β€’ ${quote.source}
358
+ </div>
359
+ </article>
360
+ `).join('');
361
+ }
362
+
363
+ // Initialize the page
364
+ document.addEventListener('DOMContentLoaded', function() {
365
+ // Load news data by default
366
+ loadNewsData();
367
+ });
368
+ </script>
369
+ </body>
370
+ </html>
371
+
372
+
373
+
374
+
375
+
376
+
booknap project/community-section.html ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Booknap - Join Our Community</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" />
9
+ <style>
10
+ :root {
11
+ --bg: #0f172a;
12
+ --card: #0b1223;
13
+ --muted: #94a3b8;
14
+ --text: #e2e8f0;
15
+ --brand: #3b82f6;
16
+ --brand-2: #6366f1;
17
+ }
18
+
19
+ body {
20
+ font-family: 'Inter', sans-serif;
21
+ background: linear-gradient(180deg, #0b1020, #0b1022 30%, #0b1124);
22
+ color: var(--text);
23
+ margin: 0;
24
+ padding: 0;
25
+ }
26
+
27
+ /* Header Styles */
28
+ .header {
29
+ position: sticky;
30
+ top: 0;
31
+ -webkit-backdrop-filter: blur(8px);
32
+ backdrop-filter: blur(8px);
33
+ background: rgba(7,10,20,0.55);
34
+ z-index: 20;
35
+ box-shadow: none;
36
+ }
37
+
38
+ .nav {
39
+ border-bottom: 1px solid rgba(255,255,255,0.06);
40
+ }
41
+
42
+ .nav-container {
43
+ display: flex;
44
+ align-items: center;
45
+ gap: 2rem;
46
+ max-width: 1200px;
47
+ margin: 0 auto;
48
+ padding: 0 20px;
49
+ }
50
+
51
+ .nav-logo {
52
+ display: flex;
53
+ align-items: center;
54
+ gap: 0.5rem;
55
+ color: white;
56
+ font-size: 1.5rem;
57
+ font-weight: 700;
58
+ text-decoration: none;
59
+ }
60
+
61
+ .nav-logo i {
62
+ font-size: 1.8rem;
63
+ color: var(--brand);
64
+ }
65
+
66
+ .nav-menu {
67
+ display: flex;
68
+ list-style: none;
69
+ gap: 2rem;
70
+ margin-left: auto;
71
+ }
72
+
73
+ .nav-link {
74
+ color: var(--muted);
75
+ text-decoration: none;
76
+ font-weight: 600;
77
+ transition: color 0.3s ease;
78
+ }
79
+
80
+ .nav-link:hover, .nav-link.active {
81
+ color: var(--text);
82
+ }
83
+
84
+ .nav-login {
85
+ margin-left: 0;
86
+ }
87
+
88
+ .login-btn {
89
+ background: linear-gradient(90deg, #3b82f6, #6366f1);
90
+ color: white;
91
+ padding: 0.75rem 1.5rem;
92
+ border-radius: 8px;
93
+ text-decoration: none;
94
+ font-weight: 600;
95
+ transition: background-color 0.2s ease;
96
+ display: inline-block;
97
+ }
98
+
99
+ .login-btn:hover {
100
+ background: linear-gradient(90deg, #2563eb, #4f46e5);
101
+ }
102
+
103
+ /* Community Section Styles */
104
+ .community-section {
105
+ background: transparent;
106
+ padding: 4rem 0;
107
+ margin-top: 0;
108
+ }
109
+
110
+ .community-container {
111
+ max-width: 1200px;
112
+ margin: 0 auto;
113
+ padding: 0 20px;
114
+ display: grid;
115
+ grid-template-columns: 1fr 1fr;
116
+ gap: 4rem;
117
+ align-items: center;
118
+ }
119
+
120
+ .community-content {
121
+ color: var(--text);
122
+ }
123
+
124
+ .community-title {
125
+ font-size: 3.5rem;
126
+ font-weight: 800;
127
+ line-height: 1.1;
128
+ margin-bottom: 1.5rem;
129
+ color: var(--text);
130
+ }
131
+
132
+ .community-description {
133
+ font-size: 1.125rem;
134
+ line-height: 1.7;
135
+ color: var(--muted);
136
+ margin-bottom: 2.5rem;
137
+ }
138
+
139
+ .community-buttons {
140
+ display: flex;
141
+ gap: 1rem;
142
+ flex-wrap: wrap;
143
+ }
144
+
145
+ .btn {
146
+ display: inline-flex;
147
+ align-items: center;
148
+ gap: 0.75rem;
149
+ padding: 0.875rem 1.5rem;
150
+ border: 1px solid #d1d5db;
151
+ border-radius: 8px;
152
+ background: white;
153
+ color: #374151;
154
+ text-decoration: none;
155
+ font-weight: 500;
156
+ font-size: 0.875rem;
157
+ transition: all 0.2s ease;
158
+ }
159
+
160
+ .btn:hover {
161
+ border-color: #9ca3af;
162
+ background: #f9fafb;
163
+ }
164
+
165
+ .btn-google {
166
+ border-color: #d1d5db;
167
+ }
168
+
169
+ .btn-email {
170
+ border-color: #d1d5db;
171
+ }
172
+
173
+ .google-icon {
174
+ width: 18px;
175
+ height: 18px;
176
+ background: conic-gradient(from -45deg, #ea4335 110deg, #4285f4 90deg 180deg, #34a853 180deg 270deg, #fbbc05 270deg);
177
+ border-radius: 2px;
178
+ position: relative;
179
+ }
180
+
181
+ .google-icon::before {
182
+ content: '';
183
+ position: absolute;
184
+ top: 50%;
185
+ left: 50%;
186
+ transform: translate(-50%, -50%);
187
+ width: 8px;
188
+ height: 8px;
189
+ background: white;
190
+ border-radius: 1px;
191
+ }
192
+
193
+ /* Right-side image */
194
+ .community-image-wrap {
195
+ display: flex;
196
+ align-items: center;
197
+ justify-content: center;
198
+ min-height: 220px;
199
+ }
200
+ .community-image {
201
+ width: 100%;
202
+ max-width: 380px;
203
+ height: auto;
204
+ border-radius: 12px;
205
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
206
+ object-fit: contain;
207
+ display: block;
208
+ }
209
+
210
+ /* Illustration styles removed: using a single image on the right side */
211
+
212
+ /* Responsive Design */
213
+ @media (max-width: 768px) {
214
+ .community-container {
215
+ grid-template-columns: 1fr;
216
+ gap: 2rem;
217
+ }
218
+
219
+ .community-title {
220
+ font-size: 2.5rem;
221
+ }
222
+
223
+ .community-buttons {
224
+ flex-direction: column;
225
+ }
226
+
227
+ /* no right-side illustration adjustments needed */
228
+ }
229
+ </style>
230
+ </head>
231
+ <body>
232
+ <!-- Header -->
233
+ <header class="header">
234
+ <nav class="nav">
235
+ <div class="nav-container">
236
+ <div class="nav-logo">
237
+ <i class="fas fa-book-open"></i>
238
+ <span>booknap</span>
239
+ </div>
240
+ <ul class="nav-menu">
241
+ <li><a href="#" class="nav-link active">Home</a></li>
242
+ <li><a href="#" class="nav-link">Book Summaries</a></li>
243
+ <li><a href="#" class="nav-link">Pricing</a></li>
244
+ <li><a href="#" class="nav-link">Blog</a></li>
245
+ </ul>
246
+ <div class="nav-login">
247
+ <a href="login.html" class="login-btn">Login</a>
248
+ </div>
249
+ </div>
250
+ </nav>
251
+ </header>
252
+
253
+ <!-- Community Section -->
254
+ <section class="community-section">
255
+ <div class="community-container">
256
+ <!-- Left Side - Content -->
257
+ <div class="community-content">
258
+ <h1 class="community-title">
259
+ Level up with the largest<br>
260
+ <span style="color: var(--brand);">reading community</span>
261
+ </h1>
262
+
263
+ <p class="community-description">
264
+ Join over 25M+ book lovers to share insights, discuss ideas, and stay up-to-date on all the latest books and reading techniques. Discover a huge repository of community-published book summaries, reviews & reading guides for your next learning journey.
265
+ </p>
266
+
267
+ </div>
268
+
269
+ <!-- Right Side - Image -->
270
+ <div class="community-image-wrap">
271
+ <img class="community-image" src="https://i.pinimg.com/736x/f4/a0/48/f4a0480397a1c019a2a1a238b2ffc594.jpg" alt="Reading illustration" />
272
+ </div>
273
+
274
+ </div>
275
+ </section>
276
+
277
+ <!-- Rest of your content can go here -->
278
+ <div style="background: var(--bg); padding: 2rem; color: var(--text);">
279
+ <div style="max-width: 1200px; margin: 0 auto;">
280
+ <h2>Continue Your Reading Journey</h2>
281
+ <p>Explore our book summaries, join reading discussions, and discover new insights with our community of book lovers.</p>
282
+ </div>
283
+ </div>
284
+ </body>
285
+ </html>
booknap project/data/news.json ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "articles": [
3
+ {
4
+ "id": 1,
5
+ "title": "The Future of Artificial Intelligence in 2024",
6
+ "description": "Exploring the latest developments in AI technology and their impact on various industries.",
7
+ "date": "2024-01-15",
8
+ "source": "Tech News",
9
+ "category": "Technology",
10
+ "image": "https://images.unsplash.com/photo-1485827404703-89b55fcc595e?w=500",
11
+ "tags": ["AI", "Technology", "Innovation"]
12
+ },
13
+ {
14
+ "id": 2,
15
+ "title": "Sustainable Business Practices That Drive Growth",
16
+ "description": "How companies are implementing eco-friendly strategies while maintaining profitability.",
17
+ "date": "2024-01-14",
18
+ "source": "Business Weekly",
19
+ "category": "Business",
20
+ "image": "https://images.unsplash.com/photo-1554224155-6726b3ff858f?w=500",
21
+ "tags": ["Sustainability", "Business", "Growth"]
22
+ },
23
+ {
24
+ "id": 3,
25
+ "title": "Mental Health Awareness in the Digital Age",
26
+ "description": "Understanding the impact of social media and technology on mental well-being.",
27
+ "date": "2024-01-13",
28
+ "source": "Health Journal",
29
+ "category": "Health",
30
+ "image": "https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=500",
31
+ "tags": ["Mental Health", "Digital", "Wellness"]
32
+ },
33
+ {
34
+ "id": 4,
35
+ "title": "Climate Change Solutions: What Works",
36
+ "description": "Evidence-based approaches to addressing climate change at individual and corporate levels.",
37
+ "date": "2024-01-12",
38
+ "source": "Environmental Times",
39
+ "category": "Environment",
40
+ "image": "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=500",
41
+ "tags": ["Climate", "Environment", "Solutions"]
42
+ },
43
+ {
44
+ "id": 5,
45
+ "title": "The Rise of Remote Work Culture",
46
+ "description": "How remote work is reshaping company culture and employee expectations.",
47
+ "date": "2024-01-11",
48
+ "source": "Workplace Insights",
49
+ "category": "Work",
50
+ "image": "https://images.unsplash.com/photo-1522202176988-66273c2fd55f?w=500",
51
+ "tags": ["Remote Work", "Culture", "Workplace"]
52
+ },
53
+ {
54
+ "id": 6,
55
+ "title": "Digital Privacy in the Age of Big Data",
56
+ "description": "Protecting personal information in an increasingly connected world.",
57
+ "date": "2024-01-10",
58
+ "source": "Privacy Today",
59
+ "category": "Technology",
60
+ "image": "https://images.unsplash.com/photo-1544716278-ca5e3f4abd8c?w=500",
61
+ "tags": ["Privacy", "Data", "Security"]
62
+ }
63
+ ],
64
+ "categories": [
65
+ "Technology",
66
+ "Business",
67
+ "Health",
68
+ "Environment",
69
+ "Work"
70
+ ],
71
+ "sources": [
72
+ "Tech News",
73
+ "Business Weekly",
74
+ "Health Journal",
75
+ "Environmental Times",
76
+ "Workplace Insights",
77
+ "Privacy Today"
78
+ ]
79
+ }
80
+
81
+
82
+
83
+
84
+
85
+
86
+
booknap project/database_schema.sql ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -- Database schema for Booknap user authentication
2
+ -- Run this in your PostgreSQL database
3
+
4
+ -- Create users table
5
+ CREATE TABLE IF NOT EXISTS users (
6
+ id SERIAL PRIMARY KEY,
7
+ full_name VARCHAR(255) NOT NULL,
8
+ email VARCHAR(255) UNIQUE NOT NULL,
9
+ password VARCHAR(255) NOT NULL,
10
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
11
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
12
+ );
13
+
14
+ -- Create index on email for faster lookups
15
+ CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
16
+
17
+ -- Insert a sample user for testing (password: test123)
18
+ -- INSERT INTO users (full_name, email, password) VALUES ('Test User', 'test@example.com', 'test123');
19
+
20
+ -- Note: In production, passwords should be hashed using bcrypt or similar
21
+ -- The current implementation stores plaintext passwords for demo purposes only
booknap project/json-blog.html ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Blog with JSON Dataset</title>
7
+ <style>
8
+ body {
9
+ font-family: 'Inter', sans-serif;
10
+ background: linear-gradient(180deg, #0b1020, #0b1022 30%, #0b1124);
11
+ color: #e2e8f0;
12
+ margin: 0;
13
+ padding: 20px;
14
+ }
15
+
16
+ .container {
17
+ max-width: 1200px;
18
+ margin: 0 auto;
19
+ }
20
+
21
+ .controls {
22
+ display: flex;
23
+ gap: 1rem;
24
+ margin: 2rem 0;
25
+ flex-wrap: wrap;
26
+ }
27
+
28
+ .search-bar, .category-filter {
29
+ background: rgba(255, 255, 255, 0.1);
30
+ border: 1px solid rgba(255, 255, 255, 0.2);
31
+ border-radius: 25px;
32
+ padding: 0.75rem 1.5rem;
33
+ color: #e2e8f0;
34
+ }
35
+
36
+ .search-bar {
37
+ flex: 1;
38
+ min-width: 200px;
39
+ }
40
+
41
+ .category-filter {
42
+ min-width: 150px;
43
+ }
44
+
45
+ .blog-grid {
46
+ display: grid;
47
+ grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
48
+ gap: 2rem;
49
+ margin-top: 2rem;
50
+ }
51
+
52
+ .blog-card {
53
+ background: rgba(255, 255, 255, 0.05);
54
+ border-radius: 16px;
55
+ overflow: hidden;
56
+ border: 1px solid rgba(255, 255, 255, 0.1);
57
+ transition: transform 0.3s ease;
58
+ }
59
+
60
+ .blog-card:hover {
61
+ transform: translateY(-8px);
62
+ }
63
+
64
+ .blog-card-image {
65
+ width: 100%;
66
+ height: 200px;
67
+ background-size: cover;
68
+ background-position: center;
69
+ }
70
+
71
+ .blog-card-content {
72
+ padding: 1.5rem;
73
+ }
74
+
75
+ .blog-card-title {
76
+ font-size: 1.25rem;
77
+ font-weight: 600;
78
+ margin-bottom: 0.5rem;
79
+ }
80
+
81
+ .blog-card-date {
82
+ color: #94a3b8;
83
+ font-size: 0.875rem;
84
+ margin-bottom: 1rem;
85
+ }
86
+
87
+ .blog-card-link {
88
+ color: #8b5cf6;
89
+ text-decoration: none;
90
+ font-weight: 600;
91
+ font-size: 0.875rem;
92
+ text-transform: uppercase;
93
+ }
94
+
95
+ .tags {
96
+ display: flex;
97
+ gap: 0.5rem;
98
+ margin-top: 1rem;
99
+ flex-wrap: wrap;
100
+ }
101
+
102
+ .tag {
103
+ background: rgba(139, 92, 246, 0.2);
104
+ color: #a78bfa;
105
+ padding: 0.25rem 0.75rem;
106
+ border-radius: 15px;
107
+ font-size: 0.75rem;
108
+ }
109
+
110
+ .loading {
111
+ text-align: center;
112
+ padding: 2rem;
113
+ color: #94a3b8;
114
+ }
115
+
116
+ .stats {
117
+ display: flex;
118
+ gap: 2rem;
119
+ margin: 1rem 0;
120
+ color: #94a3b8;
121
+ font-size: 0.875rem;
122
+ }
123
+ </style>
124
+ </head>
125
+ <body>
126
+ <div class="container">
127
+ <h1>Blog with JSON Dataset</h1>
128
+
129
+ <div class="stats" id="stats">
130
+ <span>Loading...</span>
131
+ </div>
132
+
133
+ <div class="controls">
134
+ <input type="text" class="search-bar" placeholder="Search articles..." id="searchInput">
135
+ <select class="category-filter" id="categoryFilter" aria-label="Filter by category">
136
+ <option value="">All Categories</option>
137
+ </select>
138
+ </div>
139
+
140
+ <div class="blog-grid" id="blogGrid">
141
+ <div class="loading">Loading articles...</div>
142
+ </div>
143
+ </div>
144
+
145
+ <script>
146
+ let allArticles = [];
147
+ let filteredArticles = [];
148
+
149
+ // Load data from JSON file
150
+ async function loadDataset() {
151
+ try {
152
+ const response = await fetch('data/news.json');
153
+ const data = await response.json();
154
+ allArticles = data.articles;
155
+ filteredArticles = [...allArticles];
156
+
157
+ // Populate category filter
158
+ populateCategoryFilter(data.categories);
159
+
160
+ // Display articles
161
+ displayArticles(filteredArticles);
162
+
163
+ // Update stats
164
+ updateStats();
165
+
166
+ } catch (error) {
167
+ console.error('Error loading dataset:', error);
168
+ document.getElementById('blogGrid').innerHTML =
169
+ '<div class="loading">Error loading data. Please check if data/news.json exists.</div>';
170
+ }
171
+ }
172
+
173
+ // Populate category filter dropdown
174
+ function populateCategoryFilter(categories) {
175
+ const categoryFilter = document.getElementById('categoryFilter');
176
+ categories.forEach(category => {
177
+ const option = document.createElement('option');
178
+ option.value = category;
179
+ option.textContent = category;
180
+ categoryFilter.appendChild(option);
181
+ });
182
+ }
183
+
184
+ // Create article card
185
+ function createArticleCard(article) {
186
+ const tags = article.tags ? article.tags.map(tag =>
187
+ `<span class="tag">${tag}</span>`
188
+ ).join('') : '';
189
+
190
+ return `
191
+ <article class="blog-card">
192
+ <div class="blog-card-image" style="background-image: url('${article.image}');"></div>
193
+ <div class="blog-card-content">
194
+ <h3 class="blog-card-title">${article.title}</h3>
195
+ <p class="blog-card-date">${article.date} β€’ ${article.source} β€’ ${article.category}</p>
196
+ <p style="color: #94a3b8; font-size: 0.875rem; margin-bottom: 1rem;">${article.description}</p>
197
+ <div class="tags">${tags}</div>
198
+ <a href="#" class="blog-card-link">READ MORE</a>
199
+ </div>
200
+ </article>
201
+ `;
202
+ }
203
+
204
+ // Display articles
205
+ function displayArticles(articles) {
206
+ const blogGrid = document.getElementById('blogGrid');
207
+ if (articles.length === 0) {
208
+ blogGrid.innerHTML = '<div class="loading">No articles found.</div>';
209
+ } else {
210
+ blogGrid.innerHTML = articles.map(createArticleCard).join('');
211
+ }
212
+ }
213
+
214
+ // Filter articles
215
+ function filterArticles() {
216
+ const searchTerm = document.getElementById('searchInput').value.toLowerCase();
217
+ const selectedCategory = document.getElementById('categoryFilter').value;
218
+
219
+ filteredArticles = allArticles.filter(article => {
220
+ const matchesSearch =
221
+ article.title.toLowerCase().includes(searchTerm) ||
222
+ article.description.toLowerCase().includes(searchTerm) ||
223
+ article.tags.some(tag => tag.toLowerCase().includes(searchTerm));
224
+
225
+ const matchesCategory = !selectedCategory || article.category === selectedCategory;
226
+
227
+ return matchesSearch && matchesCategory;
228
+ });
229
+
230
+ displayArticles(filteredArticles);
231
+ updateStats();
232
+ }
233
+
234
+ // Update statistics
235
+ function updateStats() {
236
+ const stats = document.getElementById('stats');
237
+ stats.innerHTML = `
238
+ <span>Total Articles: ${allArticles.length}</span>
239
+ <span>Showing: ${filteredArticles.length}</span>
240
+ <span>Categories: ${new Set(allArticles.map(a => a.category)).size}</span>
241
+ `;
242
+ }
243
+
244
+ // Initialize the page
245
+ document.addEventListener('DOMContentLoaded', function() {
246
+ // Load dataset
247
+ loadDataset();
248
+
249
+ // Add event listeners
250
+ document.getElementById('searchInput').addEventListener('input', filterArticles);
251
+ document.getElementById('categoryFilter').addEventListener('change', filterArticles);
252
+ });
253
+
254
+ // Example functions for data manipulation
255
+ function getArticlesByCategory(category) {
256
+ return allArticles.filter(article => article.category === category);
257
+ }
258
+
259
+ function getLatestArticles(count = 3) {
260
+ return allArticles
261
+ .sort((a, b) => new Date(b.date) - new Date(a.date))
262
+ .slice(0, count);
263
+ }
264
+
265
+ function searchByTags(tags) {
266
+ return allArticles.filter(article =>
267
+ tags.some(tag => article.tags.includes(tag))
268
+ );
269
+ }
270
+ </script>
271
+ </body>
272
+ </html>
booknap project/login.html ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Login - booknap</title>
7
+ <link rel="stylesheet" href="styles.css" />
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" />
10
+ <style>
11
+ :root {
12
+ --bg: #0f172a;
13
+ --card: #0b1223;
14
+ --muted: #94a3b8;
15
+ --text: #e2e8f0;
16
+ --brand: #3b82f6;
17
+ --brand-2: #6366f1;
18
+ }
19
+ body { background: linear-gradient(180deg, #0b1020, #0b1022 30%, #0b1124); min-height: 100vh; color: var(--text); font-family: 'Inter', system-ui, -apple-system, Segoe UI, Roboto, sans-serif; margin: 0; }
20
+ .header { position: sticky; top: 0; -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); background: rgba(7,10,20,0.55); z-index: 20; box-shadow: none; }
21
+ .nav { border-bottom: 1px solid rgba(255,255,255,0.06); }
22
+ .nav-container { max-width: 1200px; margin: 0 auto; padding: 0 20px; display: flex; align-items: center; gap: 2rem; }
23
+ .nav-logo i { color: var(--brand); }
24
+ .nav-link { color: var(--muted); text-decoration: none; font-weight: 600; }
25
+ .nav-link:hover, .nav-link.active { color: var(--text); }
26
+ .login-btn { background: linear-gradient(90deg, #3b82f6, #6366f1); color: white; padding: 0.75rem 1.5rem; border-radius: 8px; text-decoration: none; font-weight: 600; display: inline-block; }
27
+ .login-btn:hover { background: linear-gradient(90deg, #2563eb, #4f46e5); }
28
+
29
+ .auth { display: grid; place-items: center; padding: 4rem 1rem; }
30
+ .auth-card { width: 100%; max-width: 480px; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); border-radius: 16px; padding: 2rem; box-shadow: 0 16px 40px rgba(0,0,0,0.12); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
31
+ .auth-title { font-size: 1.75rem; font-weight: 800; margin: 0 0 0.25rem 0; }
32
+ .auth-sub { color: var(--muted); margin: 0 0 1.5rem 0; }
33
+ .field { display: grid; gap: 0.4rem; margin-bottom: 1rem; }
34
+ .label { font-weight: 600; font-size: 0.9rem; color: #cbd5e1; }
35
+ .input { background: rgba(15,23,42,0.7); color: var(--text); border: 1px solid rgba(255,255,255,0.12); border-radius: 10px; padding: 0.75rem 0.9rem; outline: none; transition: border-color 0.2s ease, box-shadow 0.2s ease; }
36
+ .input:focus { border-color: rgba(59,130,246,0.55); box-shadow: 0 0 0 3px rgba(59,130,246,0.15); }
37
+ .row { display: flex; justify-content: space-between; align-items: center; gap: 0.75rem; margin: 0.25rem 0 1rem; }
38
+ .muted-link { color: var(--muted); font-size: 0.9rem; text-decoration: none; }
39
+ .muted-link:hover { color: #cbd5e1; }
40
+ .submit { width: 100%; display: inline-block; background: linear-gradient(90deg, var(--brand), var(--brand-2)); color: white; font-weight: 800; text-align: center; padding: 0.85rem 1rem; border-radius: 12px; text-decoration: none; border: 0; cursor: pointer; }
41
+ .or { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 0.75rem; margin: 1.25rem 0; color: var(--muted); }
42
+ .or::before, .or::after { content: ""; height: 1px; background: rgba(255,255,255,0.15); }
43
+ .oauth { width: 100%; display: inline-flex; align-items: center; justify-content: center; gap: 0.6rem; background: rgba(255,255,255,0.06); color: var(--text); padding: 0.75rem 1rem; border-radius: 10px; text-decoration: none; font-weight: 700; border: 1px solid rgba(255,255,255,0.12); }
44
+ .footer-note { margin-top: 1rem; color: var(--muted); font-size: 0.95rem; text-align: center; }
45
+ .footer-note a { color: #93c5fd; text-decoration: none; font-weight: 600; }
46
+ </style>
47
+ </head>
48
+ <body>
49
+ <header class="header">
50
+ <nav class="nav">
51
+ <div class="nav-container">
52
+ <div class="nav-logo">
53
+ <i class="fas fa-book-open"></i>
54
+ <span>booknap</span>
55
+ </div>
56
+ <ul class="nav-menu" style="display:flex; gap:2rem; list-style:none; margin-left:auto;">
57
+ <li><a href="books.html" class="nav-link">Home</a></li>
58
+ <li><a href="pricing.html" class="nav-link">Pricing</a></li>
59
+ <li><a href="blog.html" class="nav-link">Blog</a></li>
60
+ </ul>
61
+ <div class="nav-login">
62
+ <a href="login.html" class="login-btn">Login</a>
63
+ </div>
64
+ </div>
65
+ </nav>
66
+ </header>
67
+
68
+ <main class="auth">
69
+ <section class="auth-card">
70
+ <h1 class="auth-title">Welcome back</h1>
71
+ <p class="auth-sub">Sign in to continue your reading journey</p>
72
+ <form id="loginForm">
73
+ <div class="field">
74
+ <label class="label" for="email">Email</label>
75
+ <input class="input" id="email" name="email" type="email" placeholder="you@example.com" required />
76
+ </div>
77
+ <div class="field">
78
+ <label class="label" for="password">Password</label>
79
+ <input class="input" id="password" name="password" type="password" placeholder="β€’β€’β€’β€’β€’β€’β€’β€’" required />
80
+ </div>
81
+ <div class="row">
82
+ <label style="display:flex; align-items:center; gap:0.5rem; color:#cbd5e1;">
83
+ <input type="checkbox" style="accent-color:#3b82f6;" /> Remember me
84
+ </label>
85
+ <a class="muted-link" href="#">Forgot password?</a>
86
+ </div>
87
+ <button class="submit" type="submit">Sign in</button>
88
+ </form>
89
+ <div class="or">or</div>
90
+ <a class="oauth" href="#"><i class="fab fa-google"></i> Continue with Google</a>
91
+ <p class="footer-note">New to booknap? <a href="signup.html">Create an account</a></p>
92
+ </section>
93
+ </main>
94
+ <script>
95
+ document.getElementById('loginForm').addEventListener('submit', async function(e) {
96
+ e.preventDefault();
97
+ const email = document.getElementById('email').value.trim();
98
+ const password = document.getElementById('password').value;
99
+ try {
100
+ const res = await fetch('/login', {
101
+ method: 'POST',
102
+ headers: { 'Content-Type': 'application/json' },
103
+ body: JSON.stringify({ email, password })
104
+ });
105
+ const data = await res.json();
106
+ if (!res.ok) {
107
+ alert(data.error || 'Login failed');
108
+ return;
109
+ }
110
+ alert('Logged in as ' + data.user.email);
111
+ window.location.href = 'books.html';
112
+ } catch (err) {
113
+ alert('Network error: ' + err.message);
114
+ }
115
+ });
116
+ </script>
117
+ </body>
118
+ </html>
119
+
120
+
booknap project/pricing.html ADDED
@@ -0,0 +1,521 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Pricing - booknap</title>
7
+ <link rel="stylesheet" href="styles.css" />
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" />
10
+ <style>
11
+ :root {
12
+ --bg: #0f172a;
13
+ --card: #0b1223;
14
+ --muted: #94a3b8;
15
+ --text: #e2e8f0;
16
+ --brand: #3b82f6;
17
+ --brand-2: #6366f1;
18
+ }
19
+ body { background: linear-gradient(180deg, #0b1020, #0b1022 30%, #0b1124); color: var(--text); font-family: 'Inter', system-ui, -apple-system, Segoe UI, Roboto, sans-serif; }
20
+ .container { max-width: 100%; margin: 0 auto; padding: 0 20px; }
21
+ /* Match pricing header/nav styling */
22
+ .header { position: sticky; top: 0; -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); background: rgba(7,10,20,0.55); z-index: 20; box-shadow: none; }
23
+ .nav { border-bottom: 1px solid rgba(255,255,255,0.06); }
24
+ .nav-logo i { color: var(--brand); }
25
+ .nav-link { color: var(--muted); text-decoration: none; font-weight: 600; }
26
+ .nav-link:hover, .nav-link.active { color: var(--text); }
27
+ .login-btn { background: var(--brand); color: white; padding: 0.6rem 1.1rem; border-radius: 9px; text-decoration: none; font-weight: 700; display: inline-block; }
28
+
29
+ /* Navigation Login Button */
30
+ .nav-container {
31
+ display: flex;
32
+ align-items: center;
33
+ gap: 2rem;
34
+ }
35
+
36
+ .nav-menu {
37
+ display: flex;
38
+ align-items: center;
39
+ gap: 2rem;
40
+ margin-left: auto;
41
+ }
42
+
43
+ .nav-login {
44
+ margin-left: 0;
45
+ }
46
+
47
+ .login-btn {
48
+ background: linear-gradient(90deg, #3b82f6, #6366f1);
49
+ color: white;
50
+ padding: 0.75rem 1.5rem;
51
+ border-radius: 8px;
52
+ text-decoration: none;
53
+ font-weight: 600;
54
+ transition: background-color 0.2s ease;
55
+ display: inline-block;
56
+ }
57
+
58
+ .login-btn:hover {
59
+ background: linear-gradient(90deg, #2563eb, #4f46e5);
60
+ }
61
+
62
+ .signup-btn {
63
+ background: transparent;
64
+ color: var(--text);
65
+ padding: 0.6rem 1.1rem;
66
+ border: 2px solid rgba(255, 255, 255, 0.2);
67
+ border-radius: 9px;
68
+ text-decoration: none;
69
+ font-weight: 700;
70
+ display: inline-block;
71
+ margin-left: 0.5rem;
72
+ transition: all 0.2s ease;
73
+ }
74
+
75
+ .signup-btn:hover {
76
+ background: rgba(255, 255, 255, 0.1);
77
+ border-color: rgba(255, 255, 255, 0.4);
78
+ }
79
+
80
+ /* Search Bar Styles */
81
+ .search-container {
82
+ margin-left: 0.5rem;
83
+ }
84
+
85
+ .search-bar {
86
+ position: relative;
87
+ display: flex;
88
+ align-items: center;
89
+ background: rgba(0, 0, 0, 0.3);
90
+ border: 1px solid rgba(255, 255, 255, 0.2);
91
+ border-radius: 25px;
92
+ padding: 0.5rem 1rem;
93
+ min-width: 300px;
94
+ transition: all 0.3s ease;
95
+ }
96
+
97
+ .search-bar:focus-within {
98
+ background: rgba(0, 0, 0, 0.4);
99
+ border-color: rgba(59, 130, 246, 0.5);
100
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
101
+ }
102
+
103
+ .search-icon {
104
+ color: rgba(255, 255, 255, 0.6);
105
+ margin-right: 0.75rem;
106
+ font-size: 0.9rem;
107
+ }
108
+
109
+ .search-input {
110
+ background: transparent;
111
+ border: none;
112
+ color: var(--text);
113
+ font-size: 0.9rem;
114
+ font-weight: 500;
115
+ width: 100%;
116
+ outline: none;
117
+ }
118
+
119
+ .search-input::placeholder {
120
+ color: rgba(255, 255, 255, 0.5);
121
+ }
122
+
123
+ .search-input:focus::placeholder {
124
+ color: rgba(255, 255, 255, 0.3);
125
+ }
126
+
127
+ /* Responsive search bar */
128
+ @media (max-width: 768px) {
129
+ .search-container {
130
+ margin-left: 0.5rem;
131
+ }
132
+
133
+ .search-bar {
134
+ min-width: 200px;
135
+ }
136
+ }
137
+
138
+ @media (max-width: 600px) {
139
+ .search-container {
140
+ margin-left: 0.25rem;
141
+ }
142
+
143
+ .search-bar {
144
+ min-width: 150px;
145
+ padding: 0.4rem 0.8rem;
146
+ }
147
+ }
148
+
149
+ .hero { padding: 3.5rem 0 2rem; text-align: center; }
150
+ .hero h1 { font-size: 2.25rem; font-weight: 800; letter-spacing: -0.02em; }
151
+ .hero p { color: var(--muted); max-width: 720px; margin: 0.75rem auto 0; }
152
+
153
+ .plans { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.5rem; margin: 2.5rem 0 3rem; width: 100%; max-width: 100%; }
154
+ /* .plans::-webkit-scrollbar { height: 8px; }
155
+ .plans::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.2); border-radius: 999px; }
156
+ .plans::-webkit-scrollbar-track { background: rgba(255,255,255,0.06); border-radius: 999px; } */
157
+ .plan-card { background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.06); border-radius: 16px; padding: 2rem; display: flex; flex-direction: column; gap: 1rem; min-height: 100%; width: 100%; }
158
+ .plan-card .features { flex: 1; gap: 0.75rem; }
159
+ .plan-card .features li { padding: 0.1rem 0; }
160
+ .plan-card .cta { margin-top: auto; }
161
+
162
+ @media (max-width: 992px) {
163
+ .plans { grid-template-columns: repeat(2, 1fr); gap: 1.5rem; }
164
+ }
165
+ @media (max-width: 600px) {
166
+ .plans { grid-template-columns: 1fr; gap: 1rem; }
167
+ .plan-card { padding: 1.5rem; }
168
+ }
169
+
170
+ .plan-title { font-weight: 800; color: var(--text); letter-spacing: -0.01em; }
171
+ .price { font-size: 2rem; font-weight: 800; }
172
+ .price small { font-size: 0.9rem; color: var(--muted); font-weight: 600; }
173
+ .badge { font-size: 0.75rem; color: white; background: linear-gradient(90deg, var(--brand), var(--brand-2)); padding: 0.25rem 0.5rem; border-radius: 999px; display: inline-block; font-weight: 700; }
174
+ .features { margin-top: 0.5rem; display: grid; gap: 0.5rem; color: var(--text); }
175
+ .features li { display: flex; align-items: center; gap: 0.5rem; }
176
+ .features i { color: #10b981; }
177
+ .cta { margin-top: 0.75rem; display: inline-block; background: linear-gradient(90deg, var(--brand), var(--brand-2)); color: white; text-decoration: none; font-weight: 800; padding: 0.6rem 1rem; border-radius: 10px; text-align: center; }
178
+
179
+ .why { margin: 2.5rem 0 3rem; }
180
+ .why h2 { text-align: center; font-size: 1.5rem; font-weight: 800; margin-bottom: 1rem; }
181
+ .why-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1rem; }
182
+ .why-card { background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.06); border-radius: 14px; padding: 1rem; }
183
+ .why-card h3 { font-weight: 800; margin-bottom: 0.25rem; }
184
+ .why-card p { color: var(--muted); font-size: 0.95rem; }
185
+
186
+ footer { border-top: 1px solid rgba(255,255,255,0.06); padding: 1.5rem 0; color: var(--muted); }
187
+
188
+ /* Dropdown Menu Styles */
189
+ .dropdown {
190
+ position: relative;
191
+ }
192
+
193
+ .dropdown-toggle {
194
+ display: flex;
195
+ align-items: center;
196
+ gap: 0.5rem;
197
+ cursor: pointer;
198
+ }
199
+
200
+ .dropdown-toggle i {
201
+ font-size: 0.8rem;
202
+ transition: transform 0.2s ease;
203
+ }
204
+
205
+ .dropdown.active .dropdown-toggle i {
206
+ transform: rotate(180deg);
207
+ }
208
+
209
+ .dropdown-menu {
210
+ position: absolute;
211
+ top: 100%;
212
+ left: 50%;
213
+ transform: translateX(-50%);
214
+ background: rgba(15, 23, 42, 0.95);
215
+ border: 1px solid rgba(255, 255, 255, 0.1);
216
+ border-radius: 12px;
217
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
218
+ min-width: 500px;
219
+ opacity: 0;
220
+ visibility: hidden;
221
+ transition: all 0.3s ease;
222
+ z-index: 1000;
223
+ margin-top: 1rem;
224
+ -webkit-backdrop-filter: blur(10px);
225
+ backdrop-filter: blur(10px);
226
+ }
227
+
228
+ .dropdown.active .dropdown-menu {
229
+ opacity: 1;
230
+ visibility: visible;
231
+ }
232
+
233
+ .dropdown-content {
234
+ display: flex;
235
+ padding: 2rem;
236
+ }
237
+
238
+ .dropdown-section {
239
+ flex: 1;
240
+ }
241
+
242
+ .dropdown-section h4 {
243
+ color: #e2e8f0;
244
+ font-size: 0.875rem;
245
+ font-weight: 600;
246
+ margin: 0 0 1rem 0;
247
+ text-transform: uppercase;
248
+ letter-spacing: 0.05em;
249
+ }
250
+
251
+ .dropdown-section ul {
252
+ list-style: none;
253
+ margin: 0;
254
+ padding: 0;
255
+ }
256
+
257
+ .dropdown-section li {
258
+ margin-bottom: 0.75rem;
259
+ }
260
+
261
+ .dropdown-section a {
262
+ display: flex;
263
+ align-items: center;
264
+ gap: 0.75rem;
265
+ color: #94a3b8;
266
+ text-decoration: none;
267
+ font-size: 0.875rem;
268
+ padding: 0.5rem;
269
+ border-radius: 8px;
270
+ transition: all 0.2s ease;
271
+ }
272
+
273
+ .dropdown-section a:hover {
274
+ background: rgba(255, 255, 255, 0.1);
275
+ color: #e2e8f0;
276
+ }
277
+
278
+ .dropdown-section i {
279
+ font-size: 1rem;
280
+ width: 20px;
281
+ text-align: center;
282
+ }
283
+
284
+ .dropdown-divider {
285
+ width: 1px;
286
+ background: rgba(255, 255, 255, 0.2);
287
+ margin: 0 1.5rem;
288
+ }
289
+
290
+ .all-categories {
291
+ color: #60a5fa !important;
292
+ font-weight: 500;
293
+ margin-top: 1rem;
294
+ display: inline-flex;
295
+ align-items: center;
296
+ gap: 0.5rem;
297
+ }
298
+
299
+ .all-categories:hover {
300
+ background: rgba(59, 130, 246, 0.2) !important;
301
+ color: #93c5fd !important;
302
+ }
303
+
304
+ .all-categories i {
305
+ font-size: 0.75rem;
306
+ transition: transform 0.2s ease;
307
+ }
308
+
309
+ .all-categories:hover i {
310
+ transform: translateX(3px);
311
+ }
312
+
313
+ /* Responsive dropdown adjustments */
314
+ @media (max-width: 768px) {
315
+ .dropdown-menu {
316
+ min-width: 300px;
317
+ left: 0;
318
+ transform: none;
319
+ }
320
+
321
+ .dropdown-content {
322
+ flex-direction: column;
323
+ padding: 1.5rem;
324
+ }
325
+
326
+ .dropdown-divider {
327
+ width: 100%;
328
+ height: 1px;
329
+ margin: 1rem 0;
330
+ }
331
+ }
332
+ </style>
333
+ </head>
334
+ <body>
335
+ <header class="header">
336
+ <nav class="nav">
337
+ <div class="nav-container">
338
+ <div class="nav-logo">
339
+ <i class="fas fa-book-open"></i>
340
+ <span>booknap</span>
341
+ </div>
342
+ <div class="search-container">
343
+ <div class="search-bar">
344
+ <i class="fas fa-search search-icon"></i>
345
+ <input type="text" placeholder="Find a book..." class="search-input">
346
+ </div>
347
+ </div>
348
+ <ul class="nav-menu">
349
+ <li><a href="books.html" class="nav-link">Home</a></li>
350
+ <li class="dropdown">
351
+ <a href="#" class="nav-link dropdown-toggle">Book Summaries <i class="fas fa-chevron-down"></i></a>
352
+ <div class="dropdown-menu">
353
+ <div class="dropdown-content">
354
+ <div class="dropdown-section">
355
+ <h4>Browse by type</h4>
356
+ <ul>
357
+ <li><a href="#"><i class="fas fa-book-open" style="color: #10b981;"></i> Text Summaries</a></li>
358
+ <li><a href="#"><i class="fas fa-headphones" style="color: #3b82f6;"></i> Audio Summaries</a></li>
359
+ <li><a href="#"><i class="fas fa-play-circle" style="color: #8b5cf6;"></i> Video Summaries</a></li>
360
+ <li><a href="#"><i class="fas fa-file-pdf" style="color: #f59e0b;"></i> PDF Downloads</a></li>
361
+ <li><a href="#"><i class="fas fa-mobile-alt" style="color: #06b6d4;"></i> Mobile App</a></li>
362
+ </ul>
363
+ </div>
364
+ <div class="dropdown-divider"></div>
365
+ <div class="dropdown-section">
366
+ <h4>Browse by topic</h4>
367
+ <ul>
368
+ <li><a href="#"><i class="fas fa-brain" style="color: #f59e0b;"></i> Psychology</a></li>
369
+ <li><a href="#"><i class="fas fa-chart-line" style="color: #10b981;"></i> Business</a></li>
370
+ <li><a href="#"><i class="fas fa-heart" style="color: #ef4444;"></i> Self-Help</a></li>
371
+ <li><a href="#"><i class="fas fa-graduation-cap" style="color: #8b5cf6;"></i> Education</a></li>
372
+ <li><a href="#"><i class="fas fa-lightbulb" style="color: #06b6d4;"></i> Innovation</a></li>
373
+ </ul>
374
+ <a href="#" class="all-categories">all categories <i class="fas fa-arrow-right"></i></a>
375
+ </div>
376
+ </div>
377
+ </div>
378
+ </li>
379
+ <li><a href="pricing.html" class="nav-link active">Pricing</a></li>
380
+ <li><a href="blog.html" class="nav-link">Blog</a></li>
381
+ </ul>
382
+ <div class="nav-login">
383
+ <a href="login.html" class="login-btn">Login</a>
384
+ <a href="signup.html" class="signup-btn">Sign Up</a>
385
+ </div>
386
+ <div class="nav-toggle">
387
+ <span></span>
388
+ <span></span>
389
+ <span></span>
390
+ </div>
391
+ </div>
392
+ </nav>
393
+ </header>
394
+
395
+ <main>
396
+ <section class="hero container">
397
+ <h1>You're ready to grow! We're here to help.</h1>
398
+ <p>booknap helps you achieve your goals efficiently with bite-sized book summaries.</p>
399
+ </section>
400
+
401
+ <section class="plans container">
402
+ <article class="plan-card">
403
+ <div class="plan-title">FREE</div>
404
+ <div class="price">$0 <small>/ forever</small></div>
405
+ <ul class="features">
406
+ <li><i class="fas fa-check-circle"></i> Get access to 2 free summaries</li>
407
+ </ul>
408
+ <a class="cta" href="#">Get Started</a>
409
+ </article>
410
+
411
+ <article class="plan-card">
412
+ <div class="plan-title">Premium Weekly</div>
413
+ <div class="price">$4.99 <small>/ week</small></div>
414
+ <ul class="features">
415
+ <li><i class="fas fa-check-circle"></i> All Premium features</li>
416
+ <li><i class="fas fa-check-circle"></i> Cancel anytime</li>
417
+ <li><i class="fas fa-check-circle"></i> Best for short-term goals</li>
418
+ </ul>
419
+ <a class="cta" href="#">Buy Now</a>
420
+ </article>
421
+
422
+ <article class="plan-card">
423
+ <div class="badge">Best Value</div>
424
+ <div class="plan-title">Premium Yearly</div>
425
+ <div class="price">$49 <small>/ year</small></div>
426
+ <ul class="features">
427
+ <li><i class="fas fa-check-circle"></i> Text, audio, and visual summaries</li>
428
+ <li><i class="fas fa-check-circle"></i> Visual book summaries</li>
429
+ <li><i class="fas fa-check-circle"></i> PDF downloads</li>
430
+ <li><i class="fas fa-check-circle"></i> Mobile app</li>
431
+ <li><i class="fas fa-check-circle"></i> Download offline</li>
432
+ <li><i class="fas fa-check-circle"></i> Audio narrations</li>
433
+ <li><i class="fas fa-check-circle"></i> Quizzes</li>
434
+ <li><i class="fas fa-check-circle"></i> Sync with Kindle</li>
435
+ <li><i class="fas fa-check-circle"></i> New content weekly</li>
436
+ <li><i class="fas fa-check-circle"></i> Cancel anytime</li>
437
+ </ul>
438
+ <a class="cta" href="#">Buy Now</a>
439
+ </article>
440
+
441
+ <article class="plan-card">
442
+ <div class="plan-title">Premium Monthly</div>
443
+ <div class="price">$12.99 <small>/ month</small></div>
444
+ <ul class="features">
445
+ <li><i class="fas fa-check-circle"></i> Text, audio, and visual summaries</li>
446
+ <li><i class="fas fa-check-circle"></i> Visual book summaries</li>
447
+ <li><i class="fas fa-check-circle"></i> PDF downloads</li>
448
+ <li><i class="fas fa-check-circle"></i> Mobile app</li>
449
+ <li><i class="fas fa-check-circle"></i> Download offline</li>
450
+ <li><i class="fas fa-check-circle"></i> Audio narrations</li>
451
+ <li><i class="fas fa-check-circle"></i> Quizzes</li>
452
+ <li><i class="fas fa-check-circle"></i> Sync with Kindle</li>
453
+ <li><i class="fas fa-check-circle"></i> New content weekly</li>
454
+ <li><i class="fas fa-check-circle"></i> Cancel anytime</li>
455
+ </ul>
456
+ <a class="cta" href="#">Buy Now</a>
457
+ </article>
458
+ </section>
459
+
460
+ <section class="why container">
461
+ <h2>Not Sure Yet? Here’s Why booknap Is Worth It</h2>
462
+ <div class="why-grid">
463
+ <div class="why-card">
464
+ <h3>High-Quality Titles</h3>
465
+ <p>Our summaries are unbiased, concise, and comprehensive, giving you the most valuable insights fast.</p>
466
+ </div>
467
+ <div class="why-card">
468
+ <h3>New content added constantly</h3>
469
+ <p>We add new content weekly, including bestsellers.</p>
470
+ </div>
471
+ <div class="why-card">
472
+ <h3>Learn on the go</h3>
473
+ <p>Read or listen anywhereβ€”iOS, tablet, laptop, and Kindle.</p>
474
+ </div>
475
+ <div class="why-card">
476
+ <h3>Cancel anytime</h3>
477
+ <p>Changed your mind? Cancel your subscription anytime.</p>
478
+ </div>
479
+ </div>
480
+ </section>
481
+ </main>
482
+
483
+ <footer>
484
+ <div class="container">
485
+ <p>&copy; 2025 booknap. All rights reserved.</p>
486
+ </div>
487
+ </footer>
488
+
489
+ <script>
490
+ // Book Summaries dropdown functionality - same as home page but click-based
491
+ document.addEventListener('DOMContentLoaded', function() {
492
+ const dropdownToggle = document.querySelector('.dropdown-toggle');
493
+ const dropdown = document.querySelector('.dropdown');
494
+
495
+ if (dropdownToggle && dropdown) {
496
+ // Toggle dropdown on click (instead of hover)
497
+ dropdownToggle.addEventListener('click', function(e) {
498
+ e.preventDefault();
499
+
500
+ // Toggle the active class on the dropdown container
501
+ dropdown.classList.toggle('active');
502
+ });
503
+
504
+ // Close dropdown when clicking outside
505
+ document.addEventListener('click', function(e) {
506
+ if (!dropdown.contains(e.target)) {
507
+ dropdown.classList.remove('active');
508
+ }
509
+ });
510
+
511
+ // Close dropdown when pressing Escape key
512
+ document.addEventListener('keydown', function(e) {
513
+ if (e.key === 'Escape') {
514
+ dropdown.classList.remove('active');
515
+ }
516
+ });
517
+ }
518
+ });
519
+ </script>
520
+ </body>
521
+ </html>
booknap project/requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ flask==2.3.3
2
+ kagglehub[pandas-datasets]==0.1.0
3
+ pandas==2.0.3
4
+ requests==2.31.0
5
+ SQLAlchemy==2.0.30
6
+ psycopg2-binary==2.9.9
7
+ flask-cors==4.0.0
8
+
booknap project/script.js ADDED
@@ -0,0 +1 @@
 
 
1
+
booknap project/setup_database.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Database setup script for Booknap
4
+ Run this script to create the necessary database tables
5
+ """
6
+
7
+ import os
8
+ from sqlalchemy import create_engine, text
9
+ from sqlalchemy.exc import SQLAlchemyError
10
+
11
+ def setup_database():
12
+ """Set up the database schema"""
13
+
14
+ # Database configuration - update with your actual password
15
+ DATABASE_URL = os.environ.get(
16
+ "DATABASE_URL",
17
+ "postgresql://postgres:YOUR_ACTUAL_PASSWORD@db.ckrqyjfdifjbsuuofegd.supabase.co:5432/postgres"
18
+ )
19
+
20
+ print("Connecting to database...")
21
+ print(f"URL: {DATABASE_URL.replace('YOUR_ACTUAL_PASSWORD', '***')}")
22
+
23
+ try:
24
+ # Create engine
25
+ engine = create_engine(DATABASE_URL, pool_pre_ping=True)
26
+
27
+ # Test connection
28
+ with engine.connect() as conn:
29
+ print("βœ… Database connection successful!")
30
+
31
+ # Create users table
32
+ create_users_table = """
33
+ CREATE TABLE IF NOT EXISTS users (
34
+ id SERIAL PRIMARY KEY,
35
+ full_name VARCHAR(255) NOT NULL,
36
+ email VARCHAR(255) UNIQUE NOT NULL,
37
+ password VARCHAR(255) NOT NULL,
38
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
39
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
40
+ );
41
+ """
42
+
43
+ # Create index
44
+ create_index = """
45
+ CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
46
+ """
47
+
48
+ # Execute schema creation
49
+ print("Creating users table...")
50
+ conn.execute(text(create_users_table))
51
+
52
+ print("Creating email index...")
53
+ conn.execute(text(create_index))
54
+
55
+ # Commit changes
56
+ conn.commit()
57
+
58
+ print("βœ… Database schema created successfully!")
59
+
60
+ # Verify table exists
61
+ result = conn.execute(text("SELECT table_name FROM information_schema.tables WHERE table_name = 'users'"))
62
+ if result.fetchone():
63
+ print("βœ… Users table verified!")
64
+
65
+ # Show table structure
66
+ result = conn.execute(text("\\d users"))
67
+ print("\nTable structure:")
68
+ # Note: \d command won't work in Python, let's use a different approach
69
+ result = conn.execute(text("SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE table_name = 'users' ORDER BY ordinal_position"))
70
+ columns = result.fetchall()
71
+ for col in columns:
72
+ print(f" {col[0]}: {col[1]} ({'NULL' if col[2] == 'YES' else 'NOT NULL'})")
73
+
74
+ else:
75
+ print("❌ Users table not found!")
76
+
77
+ except SQLAlchemyError as e:
78
+ print(f"❌ Database error: {e}")
79
+ print("\nPlease check:")
80
+ print("1. Your database password is correct")
81
+ print("2. The database is accessible from your network")
82
+ print("3. Update the DATABASE_URL in this script or set the environment variable")
83
+
84
+ except Exception as e:
85
+ print(f"❌ Unexpected error: {e}")
86
+
87
+ if __name__ == "__main__":
88
+ print("πŸš€ Booknap Database Setup")
89
+ print("=" * 40)
90
+
91
+ # Check if DATABASE_URL is set
92
+ if not os.environ.get("DATABASE_URL"):
93
+ print("⚠️ DATABASE_URL environment variable not set")
94
+ print("Please set it with your actual database password:")
95
+ print("export DATABASE_URL='postgresql://postgres:YOUR_PASSWORD@db.ckrqyjfdifjbsuuofegd.supabase.co:5432/postgres'")
96
+ print()
97
+
98
+ setup_database()
99
+
100
+ print("\n" + "=" * 40)
101
+ print("Setup complete!")
102
+
booknap project/signup.html ADDED
@@ -0,0 +1,371 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Create Account - Booknap</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16
+ background: linear-gradient(180deg, #0b1020, #0b1022 30%, #0b1124);
17
+ min-height: 100vh;
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ color: white;
22
+ }
23
+
24
+ .signup-container {
25
+ width: 100%;
26
+ max-width: 520px;
27
+ padding: 20px;
28
+ }
29
+
30
+ .signup-card {
31
+ background: rgba(255,255,255,0.04);
32
+ -webkit-backdrop-filter: blur(10px);
33
+ backdrop-filter: blur(10px);
34
+ border: 1px solid rgba(255,255,255,0.08);
35
+ border-radius: 16px;
36
+ padding: 40px;
37
+ box-shadow: 0 16px 40px rgba(0,0,0,0.12);
38
+ text-align: center;
39
+ }
40
+
41
+ .signup-card h2 {
42
+ color: white;
43
+ margin-bottom: 10px;
44
+ font-size: 32px;
45
+ font-weight: 700;
46
+ }
47
+
48
+ .signup-subtitle {
49
+ color: #cbd5e1;
50
+ margin-bottom: 30px;
51
+ font-size: 16px;
52
+ font-weight: 400;
53
+ }
54
+
55
+ .input-group {
56
+ margin-bottom: 20px;
57
+ text-align: left;
58
+ }
59
+
60
+ .input-group label {
61
+ display: block;
62
+ margin-bottom: 8px;
63
+ color: white;
64
+ font-weight: 500;
65
+ font-size: 14px;
66
+ }
67
+
68
+ .input-group input {
69
+ width: 100%;
70
+ padding: 0.75rem 0.9rem;
71
+ border: 1px solid rgba(255,255,255,0.12);
72
+ border-radius: 10px;
73
+ font-size: 16px;
74
+ transition: all 0.3s ease;
75
+ background: rgba(15,23,42,0.7);
76
+ color: white;
77
+ }
78
+
79
+ .input-group input:focus {
80
+ outline: none;
81
+ border-color: rgba(59,130,246,0.55);
82
+ background: rgba(15,23,42,0.7);
83
+ box-shadow: 0 0 0 3px rgba(59,130,246,0.15);
84
+ }
85
+
86
+ .input-group input::placeholder {
87
+ color: #94a3b8;
88
+ }
89
+
90
+ .checkbox-group {
91
+ display: flex;
92
+ align-items: center;
93
+ justify-content: space-between;
94
+ margin: 20px 0;
95
+ font-size: 14px;
96
+ }
97
+
98
+ .checkbox-wrapper {
99
+ display: flex;
100
+ align-items: center;
101
+ gap: 8px;
102
+ }
103
+
104
+ .checkbox-wrapper input[type="checkbox"] {
105
+ width: 18px;
106
+ height: 18px;
107
+ accent-color: #3b82f6;
108
+ }
109
+
110
+ .checkbox-wrapper label {
111
+ color: white;
112
+ cursor: pointer;
113
+ }
114
+
115
+ .terms-link {
116
+ color: #93c5fd;
117
+ text-decoration: none;
118
+ }
119
+
120
+ .terms-link:hover {
121
+ text-decoration: underline;
122
+ }
123
+
124
+ .signup-submit-btn {
125
+ width: 100%;
126
+ padding: 0.85rem 1rem;
127
+ background: linear-gradient(90deg, #3b82f6, #6366f1);
128
+ color: white;
129
+ border: none;
130
+ border-radius: 12px;
131
+ font-size: 16px;
132
+ font-weight: 600;
133
+ cursor: pointer;
134
+ transition: all 0.3s ease;
135
+ margin: 20px 0;
136
+ }
137
+
138
+ .signup-submit-btn:hover {
139
+ transform: translateY(-2px);
140
+ box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3);
141
+ }
142
+
143
+ .divider {
144
+ display: flex;
145
+ align-items: center;
146
+ margin: 25px 0;
147
+ color: #94a3b8;
148
+ font-size: 14px;
149
+ }
150
+
151
+ .divider::before,
152
+ .divider::after {
153
+ content: '';
154
+ flex: 1;
155
+ height: 1px;
156
+ background: rgba(255,255,255,0.15);
157
+ }
158
+
159
+ .divider span {
160
+ padding: 0 15px;
161
+ }
162
+
163
+ .google-btn {
164
+ width: 100%;
165
+ padding: 0.75rem 1rem;
166
+ background: rgba(255,255,255,0.06);
167
+ color: white;
168
+ border: 1px solid rgba(255,255,255,0.12);
169
+ border-radius: 10px;
170
+ font-size: 16px;
171
+ font-weight: 500;
172
+ cursor: pointer;
173
+ transition: all 0.3s ease;
174
+ display: flex;
175
+ align-items: center;
176
+ justify-content: center;
177
+ gap: 10px;
178
+ }
179
+
180
+ .google-btn:hover {
181
+ background: rgba(255,255,255,0.08);
182
+ border-color: rgba(255,255,255,0.2);
183
+ }
184
+
185
+ .google-icon {
186
+ width: 20px;
187
+ height: 20px;
188
+ background: white;
189
+ border-radius: 50%;
190
+ display: flex;
191
+ align-items: center;
192
+ justify-content: center;
193
+ font-weight: bold;
194
+ color: #1f2937;
195
+ font-size: 14px;
196
+ }
197
+
198
+ .login-link {
199
+ margin-top: 25px;
200
+ color: #94a3b8;
201
+ font-size: 14px;
202
+ }
203
+
204
+ .login-link a {
205
+ color: #93c5fd;
206
+ text-decoration: none;
207
+ font-weight: 600;
208
+ }
209
+
210
+ .login-link a:hover {
211
+ text-decoration: underline;
212
+ }
213
+
214
+ .error-message {
215
+ background: rgba(239, 68, 68, 0.1);
216
+ color: #fca5a5;
217
+ padding: 12px;
218
+ border-radius: 8px;
219
+ margin-bottom: 20px;
220
+ font-size: 14px;
221
+ display: none;
222
+ border: 1px solid rgba(239, 68, 68, 0.2);
223
+ }
224
+
225
+ .success-message {
226
+ background: rgba(34, 197, 94, 0.1);
227
+ color: #86efac;
228
+ padding: 12px;
229
+ border-radius: 8px;
230
+ margin-bottom: 20px;
231
+ font-size: 14px;
232
+ display: none;
233
+ border: 1px solid rgba(34, 197, 94, 0.2);
234
+ }
235
+
236
+ @media (max-width: 480px) {
237
+ .signup-card {
238
+ padding: 30px 20px;
239
+ }
240
+
241
+ .signup-card h2 {
242
+ font-size: 28px;
243
+ }
244
+ }
245
+ </style>
246
+ </head>
247
+ <body>
248
+ <main class="signup-container">
249
+ <div class="signup-card">
250
+ <h2>Join Booknap</h2>
251
+ <p class="signup-subtitle">Create your account to start your reading journey</p>
252
+
253
+ <div id="errorMessage" class="error-message"></div>
254
+ <div id="successMessage" class="success-message"></div>
255
+
256
+ <form id="signupForm">
257
+ <div class="input-group">
258
+ <label for="fullName">Full Name</label>
259
+ <input type="text" id="fullName" name="fullName" placeholder="Enter your full name" required>
260
+ </div>
261
+ <div class="input-group">
262
+ <label for="email">Email</label>
263
+ <input type="email" id="email" name="email" placeholder="Enter your email address" required>
264
+ </div>
265
+ <div class="input-group">
266
+ <label for="password">Password</label>
267
+ <input type="password" id="password" name="password" placeholder="Create a strong password" required>
268
+ </div>
269
+ <div class="input-group">
270
+ <label for="confirmPassword">Confirm Password</label>
271
+ <input type="password" id="confirmPassword" name="confirmPassword" placeholder="Confirm your password" required>
272
+ </div>
273
+
274
+ <div class="checkbox-group">
275
+ <div class="checkbox-wrapper">
276
+ <input type="checkbox" id="agreeTerms" name="agreeTerms" required>
277
+ <label for="agreeTerms">I agree to the <a href="#" class="terms-link">Terms of Service</a></label>
278
+ </div>
279
+ </div>
280
+
281
+ <button type="submit" class="signup-submit-btn">Create Account</button>
282
+ </form>
283
+
284
+ <div class="divider">
285
+ <span>or</span>
286
+ </div>
287
+
288
+ <button class="google-btn">
289
+ <div class="google-icon">G</div>
290
+ Continue with Google
291
+ </button>
292
+
293
+ <p class="login-link">Already have an account? <a href="login.html">Sign in</a></p>
294
+ </div>
295
+
296
+
297
+ </main>
298
+
299
+ <script>
300
+ document.getElementById('signupForm').addEventListener('submit', async function(event) {
301
+ event.preventDefault();
302
+
303
+ const fullName = document.getElementById('fullName').value;
304
+ const email = document.getElementById('email').value;
305
+ const password = document.getElementById('password').value;
306
+ const confirmPassword = document.getElementById('confirmPassword').value;
307
+ const agreeTerms = document.getElementById('agreeTerms').checked;
308
+
309
+ // Hide previous messages
310
+ document.getElementById('errorMessage').style.display = 'none';
311
+ document.getElementById('successMessage').style.display = 'none';
312
+
313
+ // Basic validation
314
+ if (!agreeTerms) {
315
+ showMessage('Please agree to the Terms of Service', 'error');
316
+ return;
317
+ }
318
+
319
+ if (password !== confirmPassword) {
320
+ showMessage('Passwords do not match', 'error');
321
+ return;
322
+ }
323
+
324
+ if (password.length < 6) {
325
+ showMessage('Password must be at least 6 characters long', 'error');
326
+ return;
327
+ }
328
+
329
+ try {
330
+ const response = await fetch('/signup', {
331
+ method: 'POST',
332
+ headers: {
333
+ 'Content-Type': 'application/json',
334
+ },
335
+ body: JSON.stringify({ fullName, email, password }),
336
+ });
337
+
338
+ const data = await response.json();
339
+
340
+ if (response.ok) {
341
+ showMessage(data.message, 'success');
342
+ // Redirect to login page after successful signup
343
+ setTimeout(() => {
344
+ window.location.href = 'login.html';
345
+ }, 2000);
346
+ } else {
347
+ showMessage(data.error, 'error');
348
+ }
349
+ } catch (error) {
350
+ showMessage('An error occurred. Please try again.', 'error');
351
+ }
352
+ });
353
+
354
+ function showMessage(message, type) {
355
+ const errorDiv = document.getElementById('errorMessage');
356
+ const successDiv = document.getElementById('successMessage');
357
+
358
+ if (type === 'error') {
359
+ errorDiv.textContent = message;
360
+ errorDiv.style.display = 'block';
361
+ successDiv.style.display = 'none';
362
+ } else {
363
+ successDiv.textContent = message;
364
+ successDiv.style.display = 'block';
365
+ errorDiv.style.display = 'none';
366
+ }
367
+ }
368
+ </script>
369
+ </body>
370
+ </html>
371
+
booknap project/static-blog.html ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Blog with Static Dataset</title>
7
+ <style>
8
+ body {
9
+ font-family: 'Inter', sans-serif;
10
+ background: linear-gradient(180deg, #0b1020, #0b1022 30%, #0b1124);
11
+ color: #e2e8f0;
12
+ margin: 0;
13
+ padding: 20px;
14
+ }
15
+
16
+ .container {
17
+ max-width: 1200px;
18
+ margin: 0 auto;
19
+ }
20
+
21
+ .blog-grid {
22
+ display: grid;
23
+ grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
24
+ gap: 2rem;
25
+ margin-top: 2rem;
26
+ }
27
+
28
+ .blog-card {
29
+ background: rgba(255, 255, 255, 0.05);
30
+ border-radius: 16px;
31
+ overflow: hidden;
32
+ border: 1px solid rgba(255, 255, 255, 0.1);
33
+ transition: transform 0.3s ease;
34
+ }
35
+
36
+ .blog-card:hover {
37
+ transform: translateY(-8px);
38
+ }
39
+
40
+ .blog-card-image {
41
+ width: 100%;
42
+ height: 200px;
43
+ background-size: cover;
44
+ background-position: center;
45
+ }
46
+
47
+ .blog-card-content {
48
+ padding: 1.5rem;
49
+ }
50
+
51
+ .blog-card-title {
52
+ font-size: 1.25rem;
53
+ font-weight: 600;
54
+ margin-bottom: 0.5rem;
55
+ }
56
+
57
+ .blog-card-date {
58
+ color: #94a3b8;
59
+ font-size: 0.875rem;
60
+ margin-bottom: 1rem;
61
+ }
62
+
63
+ .blog-card-link {
64
+ color: #8b5cf6;
65
+ text-decoration: none;
66
+ font-weight: 600;
67
+ font-size: 0.875rem;
68
+ text-transform: uppercase;
69
+ }
70
+
71
+ .search-bar {
72
+ background: rgba(255, 255, 255, 0.1);
73
+ border: 1px solid rgba(255, 255, 255, 0.2);
74
+ border-radius: 25px;
75
+ padding: 0.75rem 1.5rem;
76
+ color: #e2e8f0;
77
+ width: 100%;
78
+ max-width: 400px;
79
+ margin: 2rem auto;
80
+ display: block;
81
+ }
82
+
83
+ .search-bar::placeholder {
84
+ color: #94a3b8;
85
+ }
86
+ </style>
87
+ </head>
88
+ <body>
89
+ <div class="container">
90
+ <h1>Blog with Dataset Integration</h1>
91
+
92
+ <input type="text" class="search-bar" placeholder="Search articles..." id="searchInput">
93
+
94
+ <div class="blog-grid" id="blogGrid">
95
+ <!-- Articles will be loaded here -->
96
+ </div>
97
+ </div>
98
+
99
+ <script>
100
+ // Static dataset - you can replace this with your own data
101
+ const newsDataset = [
102
+ {
103
+ title: "The Future of Artificial Intelligence in 2024",
104
+ description: "Exploring the latest developments in AI technology and their impact on various industries.",
105
+ date: "2024-01-15",
106
+ source: "Tech News",
107
+ category: "Technology",
108
+ image: "https://images.unsplash.com/photo-1485827404703-89b55fcc595e?w=500"
109
+ },
110
+ {
111
+ title: "Sustainable Business Practices That Drive Growth",
112
+ description: "How companies are implementing eco-friendly strategies while maintaining profitability.",
113
+ date: "2024-01-14",
114
+ source: "Business Weekly",
115
+ category: "Business",
116
+ image: "https://images.unsplash.com/photo-1554224155-6726b3ff858f?w=500"
117
+ },
118
+ {
119
+ title: "Mental Health Awareness in the Digital Age",
120
+ description: "Understanding the impact of social media and technology on mental well-being.",
121
+ date: "2024-01-13",
122
+ source: "Health Journal",
123
+ category: "Health",
124
+ image: "https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=500"
125
+ },
126
+ {
127
+ title: "Climate Change Solutions: What Works",
128
+ description: "Evidence-based approaches to addressing climate change at individual and corporate levels.",
129
+ date: "2024-01-12",
130
+ source: "Environmental Times",
131
+ category: "Environment",
132
+ image: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=500"
133
+ },
134
+ {
135
+ title: "The Rise of Remote Work Culture",
136
+ description: "How remote work is reshaping company culture and employee expectations.",
137
+ date: "2024-01-11",
138
+ source: "Workplace Insights",
139
+ category: "Work",
140
+ image: "https://images.unsplash.com/photo-1522202176988-66273c2fd55f?w=500"
141
+ },
142
+ {
143
+ title: "Digital Privacy in the Age of Big Data",
144
+ description: "Protecting personal information in an increasingly connected world.",
145
+ date: "2024-01-10",
146
+ source: "Privacy Today",
147
+ category: "Technology",
148
+ image: "https://images.unsplash.com/photo-1544716278-ca5e3f4abd8c?w=500"
149
+ }
150
+ ];
151
+
152
+ // Function to create article cards
153
+ function createArticleCard(article) {
154
+ return `
155
+ <article class="blog-card">
156
+ <div class="blog-card-image" style="background-image: url('${article.image}');"></div>
157
+ <div class="blog-card-content">
158
+ <h3 class="blog-card-title">${article.title}</h3>
159
+ <p class="blog-card-date">${article.date} β€’ ${article.source} β€’ ${article.category}</p>
160
+ <p style="color: #94a3b8; font-size: 0.875rem; margin-bottom: 1rem;">${article.description}</p>
161
+ <a href="#" class="blog-card-link">READ MORE</a>
162
+ </div>
163
+ </article>
164
+ `;
165
+ }
166
+
167
+ // Function to display articles
168
+ function displayArticles(articles) {
169
+ const blogGrid = document.getElementById('blogGrid');
170
+ blogGrid.innerHTML = articles.map(createArticleCard).join('');
171
+ }
172
+
173
+ // Function to filter articles
174
+ function filterArticles(searchTerm) {
175
+ const filtered = newsDataset.filter(article =>
176
+ article.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
177
+ article.description.toLowerCase().includes(searchTerm.toLowerCase()) ||
178
+ article.category.toLowerCase().includes(searchTerm.toLowerCase()) ||
179
+ article.source.toLowerCase().includes(searchTerm.toLowerCase())
180
+ );
181
+ displayArticles(filtered);
182
+ }
183
+
184
+ // Initialize the page
185
+ document.addEventListener('DOMContentLoaded', function() {
186
+ // Display all articles initially
187
+ displayArticles(newsDataset);
188
+
189
+ // Add search functionality
190
+ const searchInput = document.getElementById('searchInput');
191
+ searchInput.addEventListener('input', function(e) {
192
+ filterArticles(e.target.value);
193
+ });
194
+ });
195
+
196
+ // Example: Add new article to dataset
197
+ function addNewArticle(article) {
198
+ newsDataset.push(article);
199
+ displayArticles(newsDataset);
200
+ }
201
+
202
+ // Example: Get articles by category
203
+ function getArticlesByCategory(category) {
204
+ return newsDataset.filter(article => article.category === category);
205
+ }
206
+
207
+ // Example: Get latest articles
208
+ function getLatestArticles(count = 3) {
209
+ return newsDataset
210
+ .sort((a, b) => new Date(b.date) - new Date(a.date))
211
+ .slice(0, count);
212
+ }
213
+ </script>
214
+ </body>
215
+ </html>
216
+
217
+
218
+
219
+
220
+
221
+
222
+
booknap project/styles.css ADDED
@@ -0,0 +1,973 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Reset and Base Styles */
2
+ * {
3
+ margin: 0;
4
+ padding: 0;
5
+ box-sizing: border-box;
6
+ }
7
+
8
+ body {
9
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
10
+ line-height: 1.6;
11
+ color: #333;
12
+ background: linear-gradient(180deg, #3b82f6, #6366f1);
13
+ min-height: 100vh;
14
+ }
15
+
16
+ .container {
17
+ max-width: 1200px;
18
+ margin: 0 auto;
19
+ padding: 0 20px;
20
+ }
21
+
22
+ /* Header and Navigation */
23
+ .header {
24
+ background: linear-gradient(90deg, #3b82f6, #6366f1);
25
+ box-shadow: 0 2px 20px rgba(59, 130, 246, 0.3);
26
+ position: sticky;
27
+ top: 0;
28
+ z-index: 1000;
29
+ }
30
+
31
+ .nav {
32
+ padding: 1rem 0;
33
+ }
34
+
35
+ .nav-container {
36
+ display: flex;
37
+ justify-content: space-between;
38
+ align-items: center;
39
+ max-width: 1200px;
40
+ margin: 0 auto;
41
+ padding: 0 20px;
42
+ }
43
+
44
+ .nav-logo {
45
+ display: flex;
46
+ align-items: center;
47
+ gap: 0.5rem;
48
+ color: white;
49
+ font-size: 1.5rem;
50
+ font-weight: 700;
51
+ text-decoration: none;
52
+ }
53
+
54
+ .nav-logo i {
55
+ font-size: 1.8rem;
56
+ color: #ffffff;
57
+ }
58
+
59
+ .nav-menu {
60
+ display: flex;
61
+ list-style: none;
62
+ gap: 2rem;
63
+ }
64
+
65
+ .nav-link {
66
+ color: white;
67
+ text-decoration: none;
68
+ font-weight: 500;
69
+ transition: all 0.3s ease;
70
+ position: relative;
71
+ }
72
+
73
+ .nav-link:hover {
74
+ color: #ffffff;
75
+ transform: translateY(-2px);
76
+ }
77
+
78
+ .nav-link::after {
79
+ content: '';
80
+ position: absolute;
81
+ bottom: -5px;
82
+ left: 0;
83
+ width: 0;
84
+ height: 2px;
85
+ background: #ffffff;
86
+ transition: width 0.3s ease;
87
+ }
88
+
89
+ .nav-link:hover::after {
90
+ width: 100%;
91
+ }
92
+
93
+ .nav-toggle {
94
+ display: none;
95
+ flex-direction: column;
96
+ cursor: pointer;
97
+ }
98
+
99
+ .nav-toggle span {
100
+ width: 25px;
101
+ height: 3px;
102
+ background: white;
103
+ margin: 3px 0;
104
+ transition: 0.3s;
105
+ }
106
+
107
+ /* Book Details Section */
108
+ .book-details {
109
+ padding: 4rem 0;
110
+ background: linear-gradient(135deg, #3b82f6, #6366f1);
111
+ color: white;
112
+ }
113
+
114
+ .book-header {
115
+ display: grid;
116
+ grid-template-columns: 300px 1fr;
117
+ gap: 3rem;
118
+ align-items: start;
119
+ }
120
+
121
+ .book-cover-large {
122
+ position: relative;
123
+ border-radius: 15px;
124
+ overflow: hidden;
125
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
126
+ transition: transform 0.3s ease;
127
+ }
128
+
129
+ .book-cover-large:hover {
130
+ transform: translateY(-10px);
131
+ }
132
+
133
+ .book-cover-large img {
134
+ width: 100%;
135
+ height: auto;
136
+ display: block;
137
+ }
138
+
139
+ .book-info-large h1 {
140
+ font-size: 3rem;
141
+ font-weight: 700;
142
+ color: white;
143
+ margin-bottom: 0.5rem;
144
+ line-height: 1.2;
145
+ }
146
+
147
+ .book-author {
148
+ font-size: 1.25rem;
149
+ color: rgba(255, 255, 255, 0.9);
150
+ margin-bottom: 0.5rem;
151
+ font-weight: 500;
152
+ }
153
+
154
+ .book-category {
155
+ display: inline-block;
156
+ background: rgba(255, 255, 255, 0.2);
157
+ color: white;
158
+ padding: 0.5rem 1rem;
159
+ border-radius: 25px;
160
+ font-size: 0.875rem;
161
+ font-weight: 600;
162
+ margin-bottom: 2rem;
163
+ }
164
+
165
+ .book-actions {
166
+ display: flex;
167
+ gap: 1rem;
168
+ flex-wrap: wrap;
169
+ }
170
+
171
+ /* Buttons */
172
+ .btn {
173
+ display: inline-flex;
174
+ align-items: center;
175
+ gap: 0.5rem;
176
+ padding: 0.875rem 1.5rem;
177
+ border: none;
178
+ border-radius: 10px;
179
+ font-size: 1rem;
180
+ font-weight: 600;
181
+ text-decoration: none;
182
+ cursor: pointer;
183
+ transition: all 0.3s ease;
184
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
185
+ }
186
+
187
+ .btn-primary {
188
+ background: linear-gradient(90deg, #3b82f6, #6366f1);
189
+ color: white;
190
+ }
191
+
192
+ .btn-primary:hover {
193
+ transform: translateY(-2px);
194
+ box-shadow: 0 8px 25px rgba(59, 130, 246, 0.4);
195
+ }
196
+
197
+ .btn-secondary {
198
+ background: rgba(255, 255, 255, 0.2);
199
+ color: white;
200
+ border: 2px solid rgba(255, 255, 255, 0.3);
201
+ }
202
+
203
+ .btn-secondary:hover {
204
+ background: rgba(255, 255, 255, 0.3);
205
+ color: white;
206
+ transform: translateY(-2px);
207
+ }
208
+
209
+ /* Summary Section */
210
+ .summary-section {
211
+ padding: 4rem 0;
212
+ background: linear-gradient(135deg, #3b82f6, #6366f1);
213
+ color: white;
214
+ }
215
+
216
+ .summary-section h2 {
217
+ font-size: 2.5rem;
218
+ font-weight: 700;
219
+ color: white;
220
+ margin-bottom: 2rem;
221
+ text-align: center;
222
+ }
223
+
224
+ .summary-content {
225
+ max-width: 800px;
226
+ margin: 0 auto;
227
+ font-size: 1.1rem;
228
+ line-height: 1.8;
229
+ }
230
+
231
+ .summary-content h3 {
232
+ font-size: 1.5rem;
233
+ font-weight: 600;
234
+ color: white;
235
+ margin: 2rem 0 1rem 0;
236
+ }
237
+
238
+ .summary-content p {
239
+ margin-bottom: 1.5rem;
240
+ color: rgba(255, 255, 255, 0.9);
241
+ }
242
+
243
+ .summary-content ul, .summary-content ol {
244
+ margin: 1.5rem 0;
245
+ padding-left: 2rem;
246
+ }
247
+
248
+ .summary-content li {
249
+ margin-bottom: 0.75rem;
250
+ color: rgba(255, 255, 255, 0.9);
251
+ }
252
+
253
+ .summary-content strong {
254
+ color: white;
255
+ font-weight: 600;
256
+ }
257
+
258
+ /* Audio Section */
259
+ .audio-section {
260
+ padding: 4rem 0;
261
+ background: linear-gradient(135deg, #6366f1, #3b82f6);
262
+ color: white;
263
+ }
264
+
265
+ .audio-section h2 {
266
+ font-size: 2.5rem;
267
+ font-weight: 700;
268
+ margin-bottom: 2rem;
269
+ text-align: center;
270
+ }
271
+
272
+ .audio-player {
273
+ max-width: 600px;
274
+ margin: 0 auto;
275
+ background: rgba(255, 255, 255, 0.1);
276
+ backdrop-filter: blur(10px);
277
+ border-radius: 20px;
278
+ padding: 2rem;
279
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
280
+ }
281
+
282
+ .audio-info {
283
+ text-align: center;
284
+ margin-bottom: 2rem;
285
+ }
286
+
287
+ .audio-info h3 {
288
+ font-size: 1.5rem;
289
+ font-weight: 600;
290
+ margin-bottom: 0.5rem;
291
+ }
292
+
293
+ .audio-info p {
294
+ opacity: 0.9;
295
+ }
296
+
297
+ .audio-controls {
298
+ margin-bottom: 2rem;
299
+ }
300
+
301
+ .audio-controls audio {
302
+ width: 100%;
303
+ border-radius: 10px;
304
+ background: rgba(255, 255, 255, 0.1);
305
+ }
306
+
307
+ .audio-duration {
308
+ text-align: center;
309
+ margin-top: 1rem;
310
+ opacity: 0.8;
311
+ }
312
+
313
+ .audio-features {
314
+ display: flex;
315
+ justify-content: center;
316
+ gap: 1rem;
317
+ flex-wrap: wrap;
318
+ }
319
+
320
+ .feature-btn {
321
+ background: rgba(255, 255, 255, 0.2);
322
+ border: none;
323
+ color: white;
324
+ padding: 0.75rem 1rem;
325
+ border-radius: 8px;
326
+ cursor: pointer;
327
+ transition: all 0.3s ease;
328
+ font-weight: 500;
329
+ }
330
+
331
+ .feature-btn:hover {
332
+ background: rgba(255, 255, 255, 0.3);
333
+ transform: translateY(-2px);
334
+ }
335
+
336
+ /* Related Books Section */
337
+ .related-books {
338
+ padding: 4rem 0;
339
+ background: linear-gradient(135deg, #3b82f6, #6366f1);
340
+ color: white;
341
+ }
342
+
343
+ .related-books h2 {
344
+ font-size: 2.5rem;
345
+ font-weight: 700;
346
+ color: white;
347
+ margin-bottom: 2rem;
348
+ text-align: center;
349
+ }
350
+
351
+ .books-grid {
352
+ display: grid;
353
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
354
+ gap: 2rem;
355
+ margin-top: 2rem;
356
+ }
357
+
358
+ .book-card {
359
+ background: rgba(255, 255, 255, 0.1);
360
+ border-radius: 15px;
361
+ overflow: hidden;
362
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
363
+ transition: all 0.3s ease;
364
+ cursor: pointer;
365
+ backdrop-filter: blur(10px);
366
+ }
367
+
368
+ .book-card:hover {
369
+ transform: translateY(-10px);
370
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
371
+ background: rgba(255, 255, 255, 0.15);
372
+ }
373
+
374
+ .book-cover {
375
+ position: relative;
376
+ height: 200px;
377
+ overflow: hidden;
378
+ }
379
+
380
+ .book-cover img {
381
+ width: 100%;
382
+ height: 100%;
383
+ object-fit: cover;
384
+ transition: transform 0.3s ease;
385
+ }
386
+
387
+ .book-card:hover .book-cover img {
388
+ transform: scale(1.05);
389
+ }
390
+
391
+ .book-overlay {
392
+ position: absolute;
393
+ top: 0;
394
+ left: 0;
395
+ right: 0;
396
+ bottom: 0;
397
+ background: rgba(59, 130, 246, 0.8);
398
+ display: flex;
399
+ align-items: center;
400
+ justify-content: center;
401
+ opacity: 0;
402
+ transition: opacity 0.3s ease;
403
+ }
404
+
405
+ .book-overlay i {
406
+ color: white;
407
+ font-size: 2rem;
408
+ }
409
+
410
+ .book-card:hover .book-overlay {
411
+ opacity: 1;
412
+ }
413
+
414
+ .book-info {
415
+ padding: 1.5rem;
416
+ }
417
+
418
+ .book-info h3 {
419
+ font-size: 1.25rem;
420
+ font-weight: 600;
421
+ color: white;
422
+ margin-bottom: 0.5rem;
423
+ line-height: 1.3;
424
+ }
425
+
426
+ .book-info .book-author {
427
+ color: rgba(255, 255, 255, 0.8);
428
+ font-size: 0.875rem;
429
+ margin-bottom: 0.25rem;
430
+ }
431
+
432
+ .book-info .book-category {
433
+ background: rgba(255, 255, 255, 0.2);
434
+ color: white;
435
+ padding: 0.25rem 0.75rem;
436
+ border-radius: 15px;
437
+ font-size: 0.75rem;
438
+ font-weight: 600;
439
+ display: inline-block;
440
+ }
441
+
442
+ /* Footer */
443
+ .footer {
444
+ background: linear-gradient(90deg, #3b82f6, #6366f1);
445
+ color: white;
446
+ text-align: center;
447
+ padding: 2rem 0;
448
+ }
449
+
450
+ .footer p {
451
+ opacity: 0.8;
452
+ }
453
+
454
+ /* Animated Tabs Section - Blinkist Style */
455
+ .animated-tabs-section {
456
+ padding: 6rem 0;
457
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
458
+ overflow: hidden;
459
+ }
460
+
461
+ .tabs-container {
462
+ max-width: 1200px;
463
+ margin: 0 auto;
464
+ padding: 0 20px;
465
+ }
466
+
467
+ .tabs-header {
468
+ text-align: center;
469
+ margin-bottom: 4rem;
470
+ }
471
+
472
+ .tabs-header h2 {
473
+ font-size: 3rem;
474
+ font-weight: 700;
475
+ color: #2d3748;
476
+ margin-bottom: 1rem;
477
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
478
+ -webkit-background-clip: text;
479
+ -webkit-text-fill-color: transparent;
480
+ background-clip: text;
481
+ }
482
+
483
+ .tabs-header p {
484
+ font-size: 1.2rem;
485
+ color: #4a5568;
486
+ max-width: 600px;
487
+ margin: 0 auto;
488
+ }
489
+
490
+ .tabs-wrapper {
491
+ display: flex;
492
+ flex-direction: column;
493
+ align-items: center;
494
+ gap: 3rem;
495
+ }
496
+
497
+ .tabs-nav {
498
+ display: flex;
499
+ background: white;
500
+ border-radius: 50px;
501
+ padding: 0.5rem;
502
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
503
+ position: relative;
504
+ overflow: hidden;
505
+ }
506
+
507
+ .tab-button {
508
+ background: none;
509
+ border: none;
510
+ padding: 1rem 2rem;
511
+ border-radius: 40px;
512
+ font-size: 1rem;
513
+ font-weight: 600;
514
+ color: #4a5568;
515
+ cursor: pointer;
516
+ transition: all 0.3s ease;
517
+ position: relative;
518
+ z-index: 2;
519
+ white-space: nowrap;
520
+ display: flex;
521
+ align-items: center;
522
+ gap: 0.5rem;
523
+ }
524
+
525
+ .tab-button.active {
526
+ color: white;
527
+ }
528
+
529
+ .tab-button i {
530
+ font-size: 1.2rem;
531
+ }
532
+
533
+ .tab-slider {
534
+ position: absolute;
535
+ top: 0.5rem;
536
+ left: 0.5rem;
537
+ height: calc(100% - 1rem);
538
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
539
+ border-radius: 40px;
540
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
541
+ z-index: 1;
542
+ }
543
+
544
+ .tabs-content {
545
+ width: 100%;
546
+ max-width: 1000px;
547
+ position: relative;
548
+ }
549
+
550
+ .tab-panel {
551
+ display: none;
552
+ animation: fadeInUp 0.6s ease-out;
553
+ }
554
+
555
+ .tab-panel.active {
556
+ display: block;
557
+ }
558
+
559
+ .tab-panel-content {
560
+ background: white;
561
+ border-radius: 20px;
562
+ padding: 3rem;
563
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
564
+ position: relative;
565
+ overflow: hidden;
566
+ }
567
+
568
+ .tab-panel-content::before {
569
+ content: '';
570
+ position: absolute;
571
+ top: 0;
572
+ left: 0;
573
+ right: 0;
574
+ height: 4px;
575
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
576
+ }
577
+
578
+ /* Tab-specific styles */
579
+ .read-tab {
580
+ display: grid;
581
+ grid-template-columns: 1fr 1fr;
582
+ gap: 3rem;
583
+ align-items: center;
584
+ }
585
+
586
+ .read-content h3 {
587
+ font-size: 2rem;
588
+ font-weight: 700;
589
+ color: #2d3748;
590
+ margin-bottom: 1rem;
591
+ }
592
+
593
+ .read-content p {
594
+ font-size: 1.1rem;
595
+ color: #4a5568;
596
+ line-height: 1.7;
597
+ margin-bottom: 2rem;
598
+ }
599
+
600
+ .read-features {
601
+ display: flex;
602
+ flex-direction: column;
603
+ gap: 1rem;
604
+ }
605
+
606
+ .read-feature {
607
+ display: flex;
608
+ align-items: center;
609
+ gap: 1rem;
610
+ padding: 1rem;
611
+ background: #f8fafc;
612
+ border-radius: 10px;
613
+ transition: all 0.3s ease;
614
+ }
615
+
616
+ .read-feature:hover {
617
+ background: #e2e8f0;
618
+ transform: translateX(10px);
619
+ }
620
+
621
+ .read-feature i {
622
+ font-size: 1.5rem;
623
+ color: #667eea;
624
+ width: 40px;
625
+ height: 40px;
626
+ display: flex;
627
+ align-items: center;
628
+ justify-content: center;
629
+ background: white;
630
+ border-radius: 50%;
631
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.2);
632
+ }
633
+
634
+ .read-feature-text h4 {
635
+ font-weight: 600;
636
+ color: #2d3748;
637
+ margin-bottom: 0.25rem;
638
+ }
639
+
640
+ .read-feature-text p {
641
+ font-size: 0.9rem;
642
+ color: #4a5568;
643
+ margin: 0;
644
+ }
645
+
646
+ .read-visual {
647
+ position: relative;
648
+ text-align: center;
649
+ }
650
+
651
+ .read-visual img {
652
+ max-width: 100%;
653
+ height: auto;
654
+ border-radius: 15px;
655
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
656
+ }
657
+
658
+ .listen-tab {
659
+ display: grid;
660
+ grid-template-columns: 1fr 1fr;
661
+ gap: 3rem;
662
+ align-items: center;
663
+ }
664
+
665
+ .listen-content h3 {
666
+ font-size: 2rem;
667
+ font-weight: 700;
668
+ color: #2d3748;
669
+ margin-bottom: 1rem;
670
+ }
671
+
672
+ .listen-content p {
673
+ font-size: 1.1rem;
674
+ color: #4a5568;
675
+ line-height: 1.7;
676
+ margin-bottom: 2rem;
677
+ }
678
+
679
+ .listen-features {
680
+ display: flex;
681
+ flex-direction: column;
682
+ gap: 1rem;
683
+ }
684
+
685
+ .listen-feature {
686
+ display: flex;
687
+ align-items: center;
688
+ gap: 1rem;
689
+ padding: 1rem;
690
+ background: #f8fafc;
691
+ border-radius: 10px;
692
+ transition: all 0.3s ease;
693
+ }
694
+
695
+ .listen-feature:hover {
696
+ background: #e2e8f0;
697
+ transform: translateX(10px);
698
+ }
699
+
700
+ .listen-feature i {
701
+ font-size: 1.5rem;
702
+ color: #667eea;
703
+ width: 40px;
704
+ height: 40px;
705
+ display: flex;
706
+ align-items: center;
707
+ justify-content: center;
708
+ background: white;
709
+ border-radius: 50%;
710
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.2);
711
+ }
712
+
713
+ .listen-feature-text h4 {
714
+ font-weight: 600;
715
+ color: #2d3748;
716
+ margin-bottom: 0.25rem;
717
+ }
718
+
719
+ .listen-feature-text p {
720
+ font-size: 0.9rem;
721
+ color: #4a5568;
722
+ margin: 0;
723
+ }
724
+
725
+ .listen-visual {
726
+ position: relative;
727
+ text-align: center;
728
+ }
729
+
730
+ .listen-visual img {
731
+ max-width: 100%;
732
+ height: auto;
733
+ border-radius: 15px;
734
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
735
+ }
736
+
737
+ .learn-tab {
738
+ text-align: center;
739
+ }
740
+
741
+ .learn-content h3 {
742
+ font-size: 2.5rem;
743
+ font-weight: 700;
744
+ color: #2d3748;
745
+ margin-bottom: 1.5rem;
746
+ }
747
+
748
+ .learn-content p {
749
+ font-size: 1.2rem;
750
+ color: #4a5568;
751
+ line-height: 1.7;
752
+ margin-bottom: 3rem;
753
+ max-width: 600px;
754
+ margin-left: auto;
755
+ margin-right: auto;
756
+ }
757
+
758
+ .learn-grid {
759
+ display: grid;
760
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
761
+ gap: 2rem;
762
+ margin-top: 3rem;
763
+ }
764
+
765
+ .learn-card {
766
+ background: #f8fafc;
767
+ border-radius: 15px;
768
+ padding: 2rem;
769
+ transition: all 0.3s ease;
770
+ border: 2px solid transparent;
771
+ }
772
+
773
+ .learn-card:hover {
774
+ background: white;
775
+ border-color: #667eea;
776
+ transform: translateY(-10px);
777
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
778
+ }
779
+
780
+ .learn-card i {
781
+ font-size: 3rem;
782
+ color: #667eea;
783
+ margin-bottom: 1rem;
784
+ }
785
+
786
+ .learn-card h4 {
787
+ font-size: 1.25rem;
788
+ font-weight: 600;
789
+ color: #2d3748;
790
+ margin-bottom: 1rem;
791
+ }
792
+
793
+ .learn-card p {
794
+ font-size: 1rem;
795
+ color: #4a5568;
796
+ line-height: 1.6;
797
+ margin: 0;
798
+ }
799
+
800
+ /* Animations */
801
+ @keyframes fadeInUp {
802
+ from {
803
+ opacity: 0;
804
+ transform: translateY(30px);
805
+ }
806
+ to {
807
+ opacity: 1;
808
+ transform: translateY(0);
809
+ }
810
+ }
811
+
812
+ @keyframes slideIn {
813
+ from {
814
+ opacity: 0;
815
+ transform: translateX(-30px);
816
+ }
817
+ to {
818
+ opacity: 1;
819
+ transform: translateX(0);
820
+ }
821
+ }
822
+
823
+ /* Responsive Design */
824
+ @media (max-width: 768px) {
825
+ .nav-menu {
826
+ display: none;
827
+ }
828
+
829
+ .nav-toggle {
830
+ display: flex;
831
+ }
832
+
833
+ .book-header {
834
+ grid-template-columns: 1fr;
835
+ gap: 2rem;
836
+ text-align: center;
837
+ }
838
+
839
+ .book-cover-large {
840
+ max-width: 250px;
841
+ margin: 0 auto;
842
+ }
843
+
844
+ .book-info-large h1 {
845
+ font-size: 2rem;
846
+ }
847
+
848
+ .book-actions {
849
+ justify-content: center;
850
+ }
851
+
852
+ .summary-content {
853
+ font-size: 1rem;
854
+ }
855
+
856
+ .audio-player {
857
+ margin: 0 1rem;
858
+ }
859
+
860
+ .books-grid {
861
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
862
+ gap: 1.5rem;
863
+ }
864
+
865
+ /* Animated Tabs Responsive */
866
+ .tabs-header h2 {
867
+ font-size: 2rem;
868
+ }
869
+
870
+ .tabs-nav {
871
+ flex-direction: column;
872
+ border-radius: 20px;
873
+ padding: 0.25rem;
874
+ }
875
+
876
+ .tab-button {
877
+ padding: 0.75rem 1.5rem;
878
+ font-size: 0.9rem;
879
+ }
880
+
881
+ .tab-slider {
882
+ display: none;
883
+ }
884
+
885
+ .tab-button.active {
886
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
887
+ color: white;
888
+ }
889
+
890
+ .read-tab,
891
+ .listen-tab {
892
+ grid-template-columns: 1fr;
893
+ gap: 2rem;
894
+ }
895
+
896
+ .tab-panel-content {
897
+ padding: 2rem;
898
+ }
899
+
900
+ .learn-grid {
901
+ grid-template-columns: 1fr;
902
+ }
903
+ }
904
+
905
+ @media (max-width: 480px) {
906
+ .container {
907
+ padding: 0 15px;
908
+ }
909
+
910
+ .book-info-large h1 {
911
+ font-size: 1.75rem;
912
+ }
913
+
914
+ .btn {
915
+ padding: 0.75rem 1rem;
916
+ font-size: 0.875rem;
917
+ }
918
+
919
+ .summary-section h2,
920
+ .audio-section h2,
921
+ .related-books h2 {
922
+ font-size: 2rem;
923
+ }
924
+
925
+ .books-grid {
926
+ grid-template-columns: 1fr;
927
+ }
928
+
929
+ /* Animated Tabs Mobile */
930
+ .tabs-header h2 {
931
+ font-size: 1.75rem;
932
+ }
933
+
934
+ .tabs-header p {
935
+ font-size: 1rem;
936
+ }
937
+
938
+ .tab-panel-content {
939
+ padding: 1.5rem;
940
+ }
941
+
942
+ .read-content h3,
943
+ .listen-content h3 {
944
+ font-size: 1.5rem;
945
+ }
946
+
947
+ .learn-content h3 {
948
+ font-size: 2rem;
949
+ }
950
+ }
951
+
952
+ /* Smooth scrolling */
953
+ html {
954
+ scroll-behavior: smooth;
955
+ }
956
+
957
+ /* Custom scrollbar */
958
+ ::-webkit-scrollbar {
959
+ width: 8px;
960
+ }
961
+
962
+ ::-webkit-scrollbar-track {
963
+ background: #f1f1f1;
964
+ }
965
+
966
+ ::-webkit-scrollbar-thumb {
967
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
968
+ border-radius: 4px;
969
+ }
970
+
971
+ ::-webkit-scrollbar-thumb:hover {
972
+ background: linear-gradient(135deg, #5a67d8 0%, #6b46c1 100%);
973
+ }
booknap project/test_connection.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Simple database connection test
4
+ """
5
+
6
+ import os
7
+ from sqlalchemy import create_engine, text
8
+
9
+ def test_connection():
10
+ """Test database connection"""
11
+
12
+ # You need to replace YOUR_ACTUAL_PASSWORD with your real Supabase password
13
+ DATABASE_URL = "postgresql://postgres:YOUR_ACTUAL_PASSWORD@db.ckrqyjfdifjbsuuofegd.supabase.co:5432/postgres"
14
+
15
+ print("Testing database connection...")
16
+ print(f"Host: db.ckrqyjfdifjbsuuofegd.supabase.co")
17
+ print(f"Port: 5432")
18
+ print(f"Database: postgres")
19
+ print(f"User: postgres")
20
+ print()
21
+
22
+ try:
23
+ # Create engine
24
+ engine = create_engine(DATABASE_URL, pool_pre_ping=True)
25
+
26
+ # Test connection
27
+ with engine.connect() as conn:
28
+ print("βœ… Connection successful!")
29
+
30
+ # Test a simple query
31
+ result = conn.execute(text("SELECT version()"))
32
+ version = result.fetchone()[0]
33
+ print(f"βœ… Database version: {version}")
34
+
35
+ # Test if we can create a table
36
+ print("βœ… Database is accessible and ready for use!")
37
+
38
+ except Exception as e:
39
+ print(f"❌ Connection failed: {e}")
40
+ print()
41
+ print("To fix this:")
42
+ print("1. Update the password in this script (replace YOUR_ACTUAL_PASSWORD)")
43
+ print("2. Or set the environment variable:")
44
+ print(" export DATABASE_URL='postgresql://postgres:YOUR_PASSWORD@db.ckrqyjfdifjbsuuofegd.supabase.co:5432/postgres'")
45
+ print("3. Make sure your IP is whitelisted in Supabase")
46
+
47
+ if __name__ == "__main__":
48
+ test_connection()
49
+