craft-native 0.0.37 → 0.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/android/src/index.js +268 -0
  2. package/dist/android/src/index.js.map +10 -0
  3. package/dist/android/templates/AndroidManifest.xml.template +69 -0
  4. package/dist/android/templates/CraftBridge.kt.template +3748 -0
  5. package/dist/android/templates/CraftBridgeExtensions.kt.template +383 -0
  6. package/dist/android/templates/CraftWidgetProvider.kt.template +246 -0
  7. package/dist/android/templates/MainActivity.kt.template +109 -0
  8. package/dist/android/templates/build.gradle.kts.app.template +80 -0
  9. package/dist/android/templates/build.gradle.kts.project.template +5 -0
  10. package/dist/android/templates/fastlane/Appfile +25 -0
  11. package/dist/android/templates/fastlane/Fastfile +192 -0
  12. package/dist/android/templates/fastlane/Gemfile +7 -0
  13. package/dist/android/templates/github-workflow-android.yml +248 -0
  14. package/dist/android/templates/github-workflow-test.yml +329 -0
  15. package/dist/android/templates/settings.gradle.kts.template +18 -0
  16. package/dist/android/templates/test-bridges.html +1463 -0
  17. package/dist/api/window.d.ts +18 -0
  18. package/dist/api/window.d.ts.map +1 -1
  19. package/dist/assets/index.d.ts.map +1 -1
  20. package/dist/bridge/core.d.ts +2 -0
  21. package/dist/bridge/core.d.ts.map +1 -1
  22. package/dist/cli.js +4168 -0
  23. package/dist/components/sidebar.d.ts +5 -1
  24. package/dist/components/sidebar.d.ts.map +1 -1
  25. package/dist/dev/devtools.d.ts +1 -1
  26. package/dist/dev/devtools.d.ts.map +1 -1
  27. package/dist/dev/hot-reload.d.ts +12 -3
  28. package/dist/dev/hot-reload.d.ts.map +1 -1
  29. package/dist/index.cjs +573 -208
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +585 -216
  32. package/dist/index.js.map +45 -0
  33. package/dist/ios/src/index.js +186 -0
  34. package/dist/ios/src/index.js.map +10 -0
  35. package/dist/ios/templates/CraftApp.swift +4241 -0
  36. package/dist/ios/templates/CraftAppExtensions.swift +361 -0
  37. package/dist/ios/templates/CraftWidget.swift +247 -0
  38. package/dist/ios/templates/Info.plist.template +65 -0
  39. package/dist/ios/templates/fastlane/Appfile +45 -0
  40. package/dist/ios/templates/fastlane/Fastfile +189 -0
  41. package/dist/ios/templates/fastlane/Gemfile +7 -0
  42. package/dist/ios/templates/fastlane/Matchfile +58 -0
  43. package/dist/ios/templates/github-workflow-ios.yml +192 -0
  44. package/dist/ios/templates/github-workflow-release.yml +175 -0
  45. package/dist/ios/templates/github-workflow-test.yml +272 -0
  46. package/dist/ios/templates/project.yml.template +25 -0
  47. package/dist/ios/templates/test-bridges.html +1463 -0
  48. package/dist/package.d.ts +106 -2
  49. package/dist/package.d.ts.map +1 -1
  50. package/dist/package.test.d.ts +2 -0
  51. package/dist/package.test.d.ts.map +1 -0
  52. package/dist/styles/sidebar-templates.d.ts.map +1 -1
  53. package/dist/styles/sidebars.d.ts +12 -8
  54. package/dist/styles/sidebars.d.ts.map +1 -1
  55. package/dist/templates/projects/blank/craft.config.ts +19 -0
  56. package/dist/templates/projects/blank/index.html +27 -0
  57. package/dist/templates/projects/blank/package.json +19 -0
  58. package/dist/templates/projects/blank/src/main.ts +26 -0
  59. package/dist/templates/projects/dashboard/craft.config.ts +42 -0
  60. package/dist/templates/projects/dashboard/index.html +13 -0
  61. package/dist/templates/projects/dashboard/package.json +20 -0
  62. package/dist/templates/projects/dashboard/src/main.ts +163 -0
  63. package/dist/templates/projects/dashboard/src/styles.css +280 -0
  64. package/dist/templates/projects/drawer/craft.config.ts +47 -0
  65. package/dist/templates/projects/drawer/index.html +13 -0
  66. package/dist/templates/projects/drawer/package.json +21 -0
  67. package/dist/templates/projects/drawer/src/main.ts +406 -0
  68. package/dist/templates/projects/drawer/src/styles.css +468 -0
  69. package/dist/templates/projects/ecommerce/craft.config.ts +32 -0
  70. package/dist/templates/projects/ecommerce/index.html +13 -0
  71. package/dist/templates/projects/ecommerce/package.json +19 -0
  72. package/dist/templates/projects/ecommerce/src/main.ts +194 -0
  73. package/dist/templates/projects/ecommerce/src/styles.css +169 -0
  74. package/dist/templates/projects/social/craft.config.ts +32 -0
  75. package/dist/templates/projects/social/index.html +13 -0
  76. package/dist/templates/projects/social/package.json +19 -0
  77. package/dist/templates/projects/social/src/main.ts +270 -0
  78. package/dist/templates/projects/social/src/styles.css +216 -0
  79. package/dist/templates/projects/tabs/craft.config.ts +47 -0
  80. package/dist/templates/projects/tabs/index.html +13 -0
  81. package/dist/templates/projects/tabs/package.json +21 -0
  82. package/dist/templates/projects/tabs/src/main.ts +177 -0
  83. package/dist/templates/projects/tabs/src/styles.css +163 -0
  84. package/dist/types.d.ts +29 -0
  85. package/dist/types.d.ts.map +1 -1
  86. package/dist/updater/index.d.ts +1 -0
  87. package/dist/updater/index.d.ts.map +1 -1
  88. package/package.json +5 -12
  89. package/bin/cli.ts +0 -937
@@ -0,0 +1,169 @@
1
+ /* E-commerce Template Styles */
2
+ :root {
3
+ --bg: #ffffff;
4
+ --text: #1a1a1a;
5
+ --accent: #0071e3;
6
+ --border: #e5e5e5;
7
+ --secondary: #f5f5f7;
8
+ }
9
+
10
+ @media (prefers-color-scheme: dark) {
11
+ :root {
12
+ --bg: #000000;
13
+ --text: #f5f5f7;
14
+ --border: #333;
15
+ --secondary: #1c1c1e;
16
+ }
17
+ }
18
+
19
+ * { margin: 0; padding: 0; box-sizing: border-box; }
20
+
21
+ body {
22
+ font-family: system-ui, -apple-system, sans-serif;
23
+ background: var(--bg);
24
+ color: var(--text);
25
+ }
26
+
27
+ .app {
28
+ min-height: 100vh;
29
+ display: flex;
30
+ flex-direction: column;
31
+ }
32
+
33
+ .header {
34
+ display: flex;
35
+ justify-content: space-between;
36
+ align-items: center;
37
+ padding: 16px;
38
+ border-bottom: 1px solid var(--border);
39
+ position: sticky;
40
+ top: 0;
41
+ background: var(--bg);
42
+ }
43
+
44
+ .header h1 { font-size: 20px; }
45
+
46
+ .cart-btn {
47
+ background: var(--secondary);
48
+ border: none;
49
+ padding: 8px 16px;
50
+ border-radius: 20px;
51
+ cursor: pointer;
52
+ }
53
+
54
+ main {
55
+ flex: 1;
56
+ padding: 16px;
57
+ padding-bottom: 80px;
58
+ }
59
+
60
+ .products-grid {
61
+ display: grid;
62
+ grid-template-columns: repeat(2, 1fr);
63
+ gap: 16px;
64
+ }
65
+
66
+ .product-card {
67
+ background: var(--secondary);
68
+ border-radius: 12px;
69
+ padding: 12px;
70
+ cursor: pointer;
71
+ }
72
+
73
+ .product-image {
74
+ aspect-ratio: 1;
75
+ background: linear-gradient(135deg, #667eea, #764ba2);
76
+ border-radius: 8px;
77
+ margin-bottom: 8px;
78
+ }
79
+
80
+ .product-image.large {
81
+ aspect-ratio: 4/3;
82
+ }
83
+
84
+ .product-card h3 { font-size: 14px; margin-bottom: 4px; }
85
+
86
+ .price {
87
+ font-weight: 600;
88
+ color: var(--accent);
89
+ margin-bottom: 8px;
90
+ }
91
+
92
+ button {
93
+ background: var(--accent);
94
+ color: white;
95
+ border: none;
96
+ padding: 10px 16px;
97
+ border-radius: 8px;
98
+ width: 100%;
99
+ cursor: pointer;
100
+ font-weight: 600;
101
+ }
102
+
103
+ button:disabled {
104
+ opacity: 0.5;
105
+ cursor: not-allowed;
106
+ }
107
+
108
+ .cart-item {
109
+ display: flex;
110
+ justify-content: space-between;
111
+ align-items: center;
112
+ padding: 12px;
113
+ background: var(--secondary);
114
+ border-radius: 8px;
115
+ margin-bottom: 8px;
116
+ }
117
+
118
+ .cart-item button {
119
+ width: auto;
120
+ background: #ff3b30;
121
+ }
122
+
123
+ .cart-total {
124
+ text-align: right;
125
+ padding: 16px 0;
126
+ font-size: 18px;
127
+ }
128
+
129
+ .checkout-btn {
130
+ background: #34c759;
131
+ }
132
+
133
+ .product-detail { padding: 16px; }
134
+
135
+ .product-detail button:first-child {
136
+ background: transparent;
137
+ color: var(--accent);
138
+ width: auto;
139
+ padding: 8px 0;
140
+ margin-bottom: 16px;
141
+ }
142
+
143
+ .empty-state {
144
+ text-align: center;
145
+ padding: 48px;
146
+ color: var(--text);
147
+ opacity: 0.6;
148
+ }
149
+
150
+ .bottom-nav {
151
+ position: fixed;
152
+ bottom: 0;
153
+ left: 0;
154
+ right: 0;
155
+ display: flex;
156
+ background: var(--bg);
157
+ border-top: 1px solid var(--border);
158
+ padding: 8px;
159
+ }
160
+
161
+ .bottom-nav button {
162
+ flex: 1;
163
+ background: transparent;
164
+ color: var(--text);
165
+ }
166
+
167
+ .bottom-nav button.active {
168
+ color: var(--accent);
169
+ }
@@ -0,0 +1,32 @@
1
+ import type { CraftConfig } from 'craft-native'
2
+
3
+ export default {
4
+ name: '{{appName}}',
5
+ version: '0.1.0',
6
+
7
+ platforms: {
8
+ ios: {
9
+ bundleId: '{{bundleId}}',
10
+ minimumVersion: '15.0',
11
+ capabilities: ['push-notifications', 'camera', 'photo-library'],
12
+ },
13
+ android: {
14
+ packageName: '{{packageName}}',
15
+ minSdk: 24,
16
+ permissions: ['INTERNET', 'CAMERA', 'READ_MEDIA_IMAGES', 'POST_NOTIFICATIONS'],
17
+ },
18
+ macos: {
19
+ bundleId: '{{bundleId}}',
20
+ category: 'social-networking',
21
+ },
22
+ windows: {
23
+ packageName: '{{packageName}}',
24
+ },
25
+ },
26
+
27
+ build: {
28
+ outDir: 'dist',
29
+ minify: true,
30
+ sourcemap: true,
31
+ },
32
+ } satisfies CraftConfig
@@ -0,0 +1,13 @@
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, viewport-fit=cover">
6
+ <title>{{appName}}</title>
7
+ <link rel="stylesheet" href="src/styles.css">
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="src/main.ts"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.1.0",
4
+ "description": "Social media app built with Craft",
5
+ "main": "src/main.ts",
6
+ "scripts": {
7
+ "dev": "craft dev",
8
+ "build": "craft build",
9
+ "build:ios": "craft build --platform ios",
10
+ "build:android": "craft build --platform android",
11
+ "build:all": "craft build --platform ios,android,macos,windows"
12
+ },
13
+ "dependencies": {
14
+ "craft-native": "workspace:*"
15
+ },
16
+ "devDependencies": {
17
+ "typescript": "^5.0.0"
18
+ }
19
+ }
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Social Template - {{appName}}
3
+ * A cross-platform social app built with Craft
4
+ */
5
+
6
+ import { db, win, isMobile, haptics, share } from 'craft-native'
7
+
8
+ // Types
9
+ interface Post {
10
+ id: string
11
+ userId: string
12
+ userName: string
13
+ content: string
14
+ likes: number
15
+ comments: number
16
+ isLiked: boolean
17
+ createdAt: string
18
+ }
19
+
20
+ interface User {
21
+ id: string
22
+ name: string
23
+ username: string
24
+ followers: number
25
+ following: number
26
+ }
27
+
28
+ // State
29
+ let posts: Post[] = []
30
+ let currentUser: User | null = null
31
+ let currentView: 'feed' | 'create' | 'profile' | 'notifications' = 'feed'
32
+
33
+ // Initialize
34
+ async function init(): Promise<void> {
35
+ await initDatabase()
36
+ loadMockData()
37
+
38
+ win.setTitle('{{appName}}')
39
+ win.setSize(400, 800)
40
+
41
+ render()
42
+ }
43
+
44
+ async function initDatabase(): Promise<void> {
45
+ await db.execute(`
46
+ CREATE TABLE IF NOT EXISTS posts (
47
+ id TEXT PRIMARY KEY,
48
+ content TEXT NOT NULL,
49
+ createdAt TEXT NOT NULL
50
+ )
51
+ `)
52
+ }
53
+
54
+ function loadMockData(): void {
55
+ currentUser = {
56
+ id: 'user-1',
57
+ name: 'You',
58
+ username: 'you',
59
+ followers: 100,
60
+ following: 50,
61
+ }
62
+
63
+ posts = [
64
+ { id: '1', userId: 'user-2', userName: 'John', content: 'Hello world! 👋', likes: 42, comments: 5, isLiked: false, createdAt: new Date(Date.now() - 3600000).toISOString() },
65
+ { id: '2', userId: 'user-3', userName: 'Jane', content: 'Building something cool with Craft! 🚀', likes: 128, comments: 12, isLiked: true, createdAt: new Date(Date.now() - 7200000).toISOString() },
66
+ { id: '3', userId: 'user-4', userName: 'Bob', content: 'Great day for coding ☀️', likes: 23, comments: 2, isLiked: false, createdAt: new Date(Date.now() - 86400000).toISOString() },
67
+ ]
68
+ }
69
+
70
+ // Actions
71
+ function toggleLike(postId: string): void {
72
+ const post = posts.find(p => p.id === postId)
73
+ if (post) {
74
+ post.isLiked = !post.isLiked
75
+ post.likes += post.isLiked ? 1 : -1
76
+
77
+ if (isMobile()) {
78
+ haptics.impact('light')
79
+ }
80
+
81
+ render()
82
+ }
83
+ }
84
+
85
+ async function sharePost(postId: string): Promise<void> {
86
+ const post = posts.find(p => p.id === postId)
87
+ if (post) {
88
+ await share.share({
89
+ text: post.content,
90
+ url: `https://example.com/post/${postId}`,
91
+ })
92
+ }
93
+ }
94
+
95
+ async function createPost(content: string): Promise<void> {
96
+ const post: Post = {
97
+ id: Date.now().toString(),
98
+ userId: currentUser!.id,
99
+ userName: currentUser!.name,
100
+ content,
101
+ likes: 0,
102
+ comments: 0,
103
+ isLiked: false,
104
+ createdAt: new Date().toISOString(),
105
+ }
106
+
107
+ posts.unshift(post)
108
+ await db.execute('INSERT INTO posts (id, content, createdAt) VALUES (?, ?, ?)', [post.id, post.content, post.createdAt])
109
+
110
+ if (isMobile()) {
111
+ haptics.notification('success')
112
+ }
113
+
114
+ navigate('feed')
115
+ }
116
+
117
+ // Navigation
118
+ function navigate(view: typeof currentView): void {
119
+ currentView = view
120
+ render()
121
+ }
122
+
123
+ // Utilities
124
+ function formatTime(timestamp: string): string {
125
+ const diff = Date.now() - new Date(timestamp).getTime()
126
+ if (diff < 60000) return 'now'
127
+ if (diff < 3600000) return `${Math.floor(diff / 60000)}m`
128
+ if (diff < 86400000) return `${Math.floor(diff / 3600000)}h`
129
+ return `${Math.floor(diff / 86400000)}d`
130
+ }
131
+
132
+ // Render
133
+ function render(): void {
134
+ const app = document.getElementById('app')
135
+ if (!app) return
136
+
137
+ let content = ''
138
+ switch (currentView) {
139
+ case 'feed':
140
+ content = renderFeed()
141
+ break
142
+ case 'create':
143
+ content = renderCreate()
144
+ break
145
+ case 'profile':
146
+ content = renderProfile()
147
+ break
148
+ case 'notifications':
149
+ content = renderNotifications()
150
+ break
151
+ }
152
+
153
+ app.innerHTML = `
154
+ <div class="app">
155
+ <header class="header">
156
+ <h1>{{appName}}</h1>
157
+ </header>
158
+ <main>${content}</main>
159
+ <nav class="bottom-nav">
160
+ <button onclick="navigate('feed')" class="${currentView === 'feed' ? 'active' : ''}">🏠</button>
161
+ <button onclick="navigate('create')" class="${currentView === 'create' ? 'active' : ''}">➕</button>
162
+ <button onclick="navigate('notifications')" class="${currentView === 'notifications' ? 'active' : ''}">🔔</button>
163
+ <button onclick="navigate('profile')" class="${currentView === 'profile' ? 'active' : ''}">👤</button>
164
+ </nav>
165
+ </div>
166
+ `
167
+ }
168
+
169
+ function renderFeed(): string {
170
+ return `
171
+ <div class="feed">
172
+ ${posts.map(post => `
173
+ <article class="post">
174
+ <header class="post-header">
175
+ <div class="avatar">${post.userName.charAt(0)}</div>
176
+ <div class="post-meta">
177
+ <strong>${post.userName}</strong>
178
+ <span class="time">${formatTime(post.createdAt)}</span>
179
+ </div>
180
+ </header>
181
+ <p class="post-content">${post.content}</p>
182
+ <footer class="post-actions">
183
+ <button onclick="toggleLike('${post.id}')" class="${post.isLiked ? 'liked' : ''}">
184
+ ${post.isLiked ? '❤️' : '🤍'} ${post.likes}
185
+ </button>
186
+ <button>💬 ${post.comments}</button>
187
+ <button onclick="sharePost('${post.id}')">🔄</button>
188
+ </footer>
189
+ </article>
190
+ `).join('')}
191
+ </div>
192
+ `
193
+ }
194
+
195
+ function renderCreate(): string {
196
+ return `
197
+ <div class="create-post">
198
+ <div class="create-header">
199
+ <div class="avatar">${currentUser?.name.charAt(0)}</div>
200
+ <span>@${currentUser?.username}</span>
201
+ </div>
202
+ <textarea id="post-content" placeholder="What's on your mind?" rows="5"></textarea>
203
+ <button onclick="submitPost()">Post</button>
204
+ </div>
205
+ `
206
+ }
207
+
208
+ function renderProfile(): string {
209
+ return `
210
+ <div class="profile">
211
+ <div class="profile-header">
212
+ <div class="avatar large">${currentUser?.name.charAt(0)}</div>
213
+ <h2>${currentUser?.name}</h2>
214
+ <p>@${currentUser?.username}</p>
215
+ <div class="stats">
216
+ <div class="stat"><strong>${currentUser?.followers}</strong><span>Followers</span></div>
217
+ <div class="stat"><strong>${currentUser?.following}</strong><span>Following</span></div>
218
+ </div>
219
+ </div>
220
+ <h3>Your Posts</h3>
221
+ <div class="user-posts">
222
+ ${posts.filter(p => p.userId === currentUser?.id).map(post => `
223
+ <article class="post">
224
+ <p>${post.content}</p>
225
+ <span class="time">${formatTime(post.createdAt)}</span>
226
+ </article>
227
+ `).join('') || '<p class="empty">No posts yet</p>'}
228
+ </div>
229
+ </div>
230
+ `
231
+ }
232
+
233
+ function renderNotifications(): string {
234
+ return `
235
+ <div class="notifications">
236
+ <div class="notification">
237
+ <span class="notif-icon">❤️</span>
238
+ <p><strong>John</strong> liked your post</p>
239
+ <span class="time">2h</span>
240
+ </div>
241
+ <div class="notification">
242
+ <span class="notif-icon">👤</span>
243
+ <p><strong>Jane</strong> started following you</p>
244
+ <span class="time">5h</span>
245
+ </div>
246
+ <div class="notification">
247
+ <span class="notif-icon">💬</span>
248
+ <p><strong>Bob</strong> commented on your post</p>
249
+ <span class="time">1d</span>
250
+ </div>
251
+ </div>
252
+ `
253
+ }
254
+
255
+ function submitPost(): void {
256
+ const textarea = document.getElementById('post-content') as HTMLTextAreaElement
257
+ const content = textarea?.value.trim()
258
+ if (content) {
259
+ createPost(content)
260
+ }
261
+ }
262
+
263
+ // Expose functions globally
264
+ (window as any).navigate = navigate
265
+ ;(window as any).toggleLike = toggleLike
266
+ ;(window as any).sharePost = sharePost
267
+ ;(window as any).submitPost = submitPost
268
+
269
+ // Start app
270
+ init()
@@ -0,0 +1,216 @@
1
+ /* Social Template Styles */
2
+ :root {
3
+ --bg: #ffffff;
4
+ --text: #0f1419;
5
+ --secondary: #536471;
6
+ --accent: #1d9bf0;
7
+ --border: #eff3f4;
8
+ --like: #f91880;
9
+ }
10
+
11
+ @media (prefers-color-scheme: dark) {
12
+ :root {
13
+ --bg: #000000;
14
+ --text: #e7e9ea;
15
+ --secondary: #71767b;
16
+ --border: #2f3336;
17
+ }
18
+ }
19
+
20
+ * { margin: 0; padding: 0; box-sizing: border-box; }
21
+
22
+ body {
23
+ font-family: system-ui, -apple-system, sans-serif;
24
+ background: var(--bg);
25
+ color: var(--text);
26
+ }
27
+
28
+ .app {
29
+ min-height: 100vh;
30
+ display: flex;
31
+ flex-direction: column;
32
+ }
33
+
34
+ .header {
35
+ padding: 16px;
36
+ border-bottom: 1px solid var(--border);
37
+ position: sticky;
38
+ top: 0;
39
+ background: var(--bg);
40
+ z-index: 100;
41
+ }
42
+
43
+ .header h1 { font-size: 20px; }
44
+
45
+ main {
46
+ flex: 1;
47
+ padding-bottom: 60px;
48
+ }
49
+
50
+ /* Feed */
51
+ .feed { display: flex; flex-direction: column; }
52
+
53
+ .post {
54
+ padding: 16px;
55
+ border-bottom: 1px solid var(--border);
56
+ }
57
+
58
+ .post-header {
59
+ display: flex;
60
+ gap: 12px;
61
+ margin-bottom: 8px;
62
+ }
63
+
64
+ .avatar {
65
+ width: 40px;
66
+ height: 40px;
67
+ border-radius: 50%;
68
+ background: linear-gradient(135deg, #667eea, #764ba2);
69
+ display: flex;
70
+ align-items: center;
71
+ justify-content: center;
72
+ color: white;
73
+ font-weight: 600;
74
+ }
75
+
76
+ .avatar.large {
77
+ width: 80px;
78
+ height: 80px;
79
+ font-size: 32px;
80
+ }
81
+
82
+ .post-meta { display: flex; flex-direction: column; }
83
+ .post-meta strong { font-size: 15px; }
84
+ .time { font-size: 13px; color: var(--secondary); }
85
+
86
+ .post-content {
87
+ font-size: 15px;
88
+ line-height: 1.4;
89
+ margin-bottom: 12px;
90
+ }
91
+
92
+ .post-actions {
93
+ display: flex;
94
+ gap: 32px;
95
+ }
96
+
97
+ .post-actions button {
98
+ background: none;
99
+ border: none;
100
+ color: var(--secondary);
101
+ font-size: 14px;
102
+ cursor: pointer;
103
+ display: flex;
104
+ align-items: center;
105
+ gap: 4px;
106
+ }
107
+
108
+ .post-actions button.liked { color: var(--like); }
109
+
110
+ /* Create */
111
+ .create-post { padding: 16px; }
112
+
113
+ .create-header {
114
+ display: flex;
115
+ align-items: center;
116
+ gap: 12px;
117
+ margin-bottom: 16px;
118
+ }
119
+
120
+ .create-post textarea {
121
+ width: 100%;
122
+ padding: 12px;
123
+ border: 1px solid var(--border);
124
+ border-radius: 8px;
125
+ font-size: 16px;
126
+ resize: none;
127
+ background: var(--bg);
128
+ color: var(--text);
129
+ margin-bottom: 16px;
130
+ }
131
+
132
+ .create-post button {
133
+ background: var(--accent);
134
+ color: white;
135
+ border: none;
136
+ padding: 12px 24px;
137
+ border-radius: 24px;
138
+ font-weight: 600;
139
+ cursor: pointer;
140
+ float: right;
141
+ }
142
+
143
+ /* Profile */
144
+ .profile { padding: 16px; }
145
+
146
+ .profile-header {
147
+ text-align: center;
148
+ padding: 24px 0;
149
+ border-bottom: 1px solid var(--border);
150
+ margin-bottom: 16px;
151
+ }
152
+
153
+ .profile-header h2 { margin: 12px 0 4px; }
154
+ .profile-header p { color: var(--secondary); margin-bottom: 16px; }
155
+
156
+ .stats {
157
+ display: flex;
158
+ justify-content: center;
159
+ gap: 32px;
160
+ }
161
+
162
+ .stat {
163
+ display: flex;
164
+ flex-direction: column;
165
+ align-items: center;
166
+ }
167
+
168
+ .stat strong { font-size: 18px; }
169
+ .stat span { font-size: 13px; color: var(--secondary); }
170
+
171
+ .user-posts h3 { margin: 16px 0; }
172
+ .user-posts .post { padding: 12px 0; }
173
+
174
+ .empty {
175
+ text-align: center;
176
+ color: var(--secondary);
177
+ padding: 24px;
178
+ }
179
+
180
+ /* Notifications */
181
+ .notifications { padding: 16px; }
182
+
183
+ .notification {
184
+ display: flex;
185
+ align-items: center;
186
+ gap: 12px;
187
+ padding: 12px 0;
188
+ border-bottom: 1px solid var(--border);
189
+ }
190
+
191
+ .notif-icon { font-size: 20px; }
192
+ .notification p { flex: 1; font-size: 14px; }
193
+
194
+ /* Bottom Nav */
195
+ .bottom-nav {
196
+ position: fixed;
197
+ bottom: 0;
198
+ left: 0;
199
+ right: 0;
200
+ display: flex;
201
+ background: var(--bg);
202
+ border-top: 1px solid var(--border);
203
+ padding: 8px;
204
+ }
205
+
206
+ .bottom-nav button {
207
+ flex: 1;
208
+ background: none;
209
+ border: none;
210
+ font-size: 24px;
211
+ padding: 8px;
212
+ cursor: pointer;
213
+ opacity: 0.5;
214
+ }
215
+
216
+ .bottom-nav button.active { opacity: 1; }