tacel-canva 1.0.0

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.
package/README.md ADDED
@@ -0,0 +1,637 @@
1
+ # Tacel Canva Module - Premium Edition
2
+
3
+ Universal Canva integration module for Tacel Electron apps with premium UI and advanced features. A complete design management solution with OAuth authentication, inline editing, analytics, and 10+ productivity features.
4
+
5
+ ## ✨ Features
6
+
7
+ ### Core Features
8
+ - ✅ **OAuth 2.0 Authentication** with PKCE (Proof Key for Code Exchange)
9
+ - ✅ **Premium Design Gallery** with glassmorphism effects and staggered animations
10
+ - ✅ **Inline Design Editor** - Edit designs without leaving the app
11
+ - ✅ **Export/Download** designs in multiple formats (PNG, PDF, JPG)
12
+ - ✅ **Custom Collections** - Organize designs into custom collections
13
+ - ✅ **Favorites System** - Star designs for quick access
14
+ - ✅ **Advanced Search** - Search with filters and sorting
15
+ - ✅ **34 Built-in Themes** - Professional color schemes
16
+ - ✅ **Keyboard Shortcuts** - Full keyboard navigation (press `?` for help)
17
+ - ✅ **Toast Notifications** - Elegant feedback system
18
+
19
+ ### Premium Features (NEW)
20
+ 1. **🏷️ Brand Kit Access** - Quick access to brand colors, logos, and fonts
21
+ 2. **📋 Design Templates Browser** - Browse Canva templates by category
22
+ 3. **📅 Scheduled Publishing Queue** - Schedule design exports for specific dates
23
+ 4. **📝 Design Annotations & Notes** - Add notes, tags, and link to tasks
24
+ 5. **📋 Quick Insert to Documents** - Copy URLs, HTML for emails, or download
25
+ 6. **⚖️ Design Comparison View** - Compare up to 4 designs side-by-side
26
+ 7. **📦 Asset Library Sync** - Designate reusable assets for quick access
27
+ 8. **📊 Design Analytics Dashboard** - Track views, exports, and usage stats
28
+ 9. **🎯 Batch Export with Presets** - Export multiple designs with saved settings
29
+ 10. **💬 Design Request System** - Submit and track design requests
30
+
31
+ ### UI/UX Enhancements
32
+ - **Glassmorphism Effects** - Blurred backgrounds on modals and menus
33
+ - **Gradient System** - Beautiful gradients throughout the UI
34
+ - **Layered Shadows** - Depth with xs, sm, md, lg, xl shadow levels
35
+ - **Micro-interactions** - Hover effects, staggered animations, smooth transitions
36
+ - **Premium Context Menus** - Right-click anywhere for quick actions
37
+ - **Responsive Design** - Adapts to all screen sizes
38
+ - **Loading Skeletons** - Shimmer effects while content loads
39
+
40
+ ## Installation
41
+
42
+ ```bash
43
+ npm install tacel-canva
44
+ ```
45
+
46
+ ## Quick Start
47
+
48
+ ### 1. Register Canva Integration
49
+
50
+ Go to [Canva Developer Portal](https://www.canva.com/developers/) and create an integration:
51
+ - Set redirect URI: `http://localhost:3000/canva/callback`
52
+ - Enable scopes: `design:meta:read`, `design:content:read`, `folder:read`
53
+ - Save your Client ID and Client Secret
54
+
55
+ ### 2. Backend Setup (main.js)
56
+
57
+ ```javascript
58
+ const { initCanvaApi } = require('tacel-canva/canva-api');
59
+
60
+ // Initialize Canva API handlers
61
+ initCanvaApi({
62
+ clientId: process.env.CANVA_CLIENT_ID,
63
+ clientSecret: process.env.CANVA_CLIENT_SECRET,
64
+ redirectUri: 'http://localhost:3000/canva/callback',
65
+ channelPrefix: 'canva', // IPC channel prefix
66
+ });
67
+ ```
68
+
69
+ ### 3. Frontend Setup (renderer)
70
+
71
+ ```html
72
+ <!-- Include CSS -->
73
+ <link rel="stylesheet" href="node_modules/tacel-canva/canva.css">
74
+
75
+ <!-- Include JS -->
76
+ <script src="node_modules/tacel-canva/index.js"></script>
77
+ ```
78
+
79
+ ```javascript
80
+ const { TacelCanva } = require('tacel-canva');
81
+
82
+ // Initialize the module
83
+ const canva = TacelCanva.initialize(document.getElementById('canva-container'), {
84
+ // Current user context
85
+ currentUserId: 'user-123',
86
+ currentUserName: 'Pierre',
87
+
88
+ // Token storage callbacks (required)
89
+ onGetToken: async (userId) => {
90
+ // Return stored tokens from your DB
91
+ const tokens = await window.electron.invoke('get-canva-tokens', userId);
92
+ return tokens; // { access_token, refresh_token, expires_at }
93
+ },
94
+
95
+ onSaveToken: async (userId, tokens) => {
96
+ // Save tokens to your DB
97
+ await window.electron.invoke('save-canva-tokens', { userId, tokens });
98
+ },
99
+
100
+ onRevokeToken: async (userId) => {
101
+ // Delete tokens from your DB
102
+ await window.electron.invoke('delete-canva-tokens', userId);
103
+ },
104
+
105
+ // Optional features (all enabled by default)
106
+ features: {
107
+ export: true,
108
+ createNew: true,
109
+ folders: true,
110
+ search: true,
111
+ preview: true,
112
+ sorting: true,
113
+ viewToggle: true,
114
+ contextMenu: true,
115
+ dragDrop: true,
116
+ favorites: true,
117
+ recentlyViewed: true,
118
+ bulkActions: true,
119
+ collections: true,
120
+ themePicker: true,
121
+ // Premium features
122
+ brandKit: true,
123
+ templates: true,
124
+ scheduledExports: true,
125
+ annotations: true,
126
+ quickInsert: true,
127
+ compareView: true,
128
+ assetLibrary: true,
129
+ analytics: true,
130
+ batchExport: true,
131
+ designRequests: true,
132
+ },
133
+
134
+ // Optional theming
135
+ theme: 'default', // or any of 34 built-in themes
136
+ });
137
+ ```
138
+
139
+ ### 4. Handle OAuth Callback
140
+
141
+ Create a callback route in your app to handle the OAuth redirect:
142
+
143
+ ```javascript
144
+ // In your app's routing logic
145
+ if (window.location.pathname === '/canva/callback') {
146
+ const urlParams = new URLSearchParams(window.location.search);
147
+ const code = urlParams.get('code');
148
+
149
+ if (code) {
150
+ // Complete OAuth flow
151
+ await canva.completeOAuth(code);
152
+ }
153
+ }
154
+ ```
155
+
156
+ ## Configuration
157
+
158
+ ### Backend Options
159
+
160
+ ```javascript
161
+ initCanvaApi({
162
+ clientId: string, // Required: Canva client ID
163
+ clientSecret: string, // Required: Canva client secret
164
+ redirectUri: string, // Required: OAuth redirect URI
165
+ channelPrefix: string, // Optional: IPC channel prefix (default: 'canva')
166
+ });
167
+ ```
168
+
169
+ ### Frontend Options
170
+
171
+ ```javascript
172
+ TacelCanva.initialize(container, {
173
+ // Required
174
+ currentUserId: string,
175
+ onGetToken: async (userId) => tokens,
176
+ onSaveToken: async (userId, tokens) => void,
177
+ onRevokeToken: async (userId) => void,
178
+
179
+ // Optional
180
+ currentUserName: string,
181
+ features: {
182
+ export: boolean, // Default: true
183
+ createNew: boolean, // Default: true
184
+ folders: boolean, // Default: true
185
+ search: boolean, // Default: true
186
+ },
187
+ theme: string, // Default: 'default'
188
+ channelPrefix: string, // Default: 'canva'
189
+ });
190
+ ```
191
+
192
+ ## Theming
193
+
194
+ Override CSS variables to match your app's theme:
195
+
196
+ ```css
197
+ .tacel-canva {
198
+ --tc-primary: #00c4cc;
199
+ --tc-primary-hover: #00a8b0;
200
+ --tc-bg: #ffffff;
201
+ --tc-bg-secondary: #f5f5f5;
202
+ --tc-border: #e0e0e0;
203
+ --tc-text: #333333;
204
+ --tc-text-muted: #666666;
205
+ --tc-shadow: rgba(0, 0, 0, 0.1);
206
+ --tc-border-radius: 8px;
207
+ --tc-spacing: 16px;
208
+ }
209
+ ```
210
+
211
+ ### Example: Wire-Scheduler Theme
212
+
213
+ ```css
214
+ .tacel-canva {
215
+ --tc-primary: #4a90e2;
216
+ --tc-primary-hover: #357abd;
217
+ --tc-bg: #1e1e1e;
218
+ --tc-bg-secondary: #2a2a2a;
219
+ --tc-border: #3a3a3a;
220
+ --tc-text: #ffffff;
221
+ --tc-text-muted: #b0b0b0;
222
+ }
223
+ ```
224
+
225
+ ## API Reference
226
+
227
+ ### Frontend Methods
228
+
229
+ #### `TacelCanva.initialize(container, config)`
230
+ Initialize the Canva module in a container element.
231
+
232
+ #### `canva.completeOAuth(code)`
233
+ Complete the OAuth flow with the authorization code from the callback.
234
+
235
+ #### `canva.destroy()`
236
+ Clean up the module and remove all event listeners.
237
+
238
+ ### IPC Channels
239
+
240
+ All channels are prefixed with your configured `channelPrefix` (default: `canva`):
241
+
242
+ - `canva:get-auth-url` - Get OAuth authorization URL
243
+ - `canva:exchange-token` - Exchange authorization code for tokens
244
+ - `canva:refresh-token` - Refresh access token
245
+ - `canva:list-designs` - List user's designs
246
+ - `canva:get-design` - Get design details
247
+ - `canva:export-design` - Export design to file
248
+ - `canva:get-export` - Get export job status
249
+ - `canva:list-folders` - List user's folders
250
+ - `canva:revoke-token` - Revoke access token
251
+
252
+ ## Token Storage
253
+
254
+ The module does NOT store tokens itself. You must implement token storage in your app's database.
255
+
256
+ ### Example Token Schema
257
+
258
+ ```sql
259
+ CREATE TABLE canva_tokens (
260
+ user_id VARCHAR(255) PRIMARY KEY,
261
+ access_token TEXT NOT NULL,
262
+ refresh_token TEXT NOT NULL,
263
+ expires_at BIGINT NOT NULL,
264
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
265
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
266
+ );
267
+ ```
268
+
269
+ ### Example IPC Handlers
270
+
271
+ ```javascript
272
+ // In your app's main.js
273
+ ipcMain.handle('get-canva-tokens', async (event, userId) => {
274
+ const row = await db.query('SELECT * FROM canva_tokens WHERE user_id = ?', [userId]);
275
+ return row ? {
276
+ access_token: row.access_token,
277
+ refresh_token: row.refresh_token,
278
+ expires_at: row.expires_at
279
+ } : null;
280
+ });
281
+
282
+ ipcMain.handle('save-canva-tokens', async (event, { userId, tokens }) => {
283
+ await db.query(
284
+ 'INSERT INTO canva_tokens (user_id, access_token, refresh_token, expires_at) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE access_token = ?, refresh_token = ?, expires_at = ?',
285
+ [userId, tokens.access_token, tokens.refresh_token, tokens.expires_at, tokens.access_token, tokens.refresh_token, tokens.expires_at]
286
+ );
287
+ });
288
+
289
+ ipcMain.handle('delete-canva-tokens', async (event, userId) => {
290
+ await db.query('DELETE FROM canva_tokens WHERE user_id = ?', [userId]);
291
+ });
292
+ ```
293
+
294
+ ## OAuth Flow
295
+
296
+ 1. User clicks "Connect Canva Account"
297
+ 2. Module generates PKCE challenge
298
+ 3. Module requests auth URL from backend
299
+ 4. Backend returns Canva authorization URL
300
+ 5. Module opens URL in browser
301
+ 6. User authorizes in Canva
302
+ 7. Canva redirects to your callback URL with code
303
+ 8. Your app calls `canva.completeOAuth(code)`
304
+ 9. Module exchanges code for tokens via backend
305
+ 10. Module saves tokens via `onSaveToken` callback
306
+ 11. Module loads designs and renders gallery
307
+
308
+ ## Canva API Limits
309
+
310
+ - **List designs**: 100 requests/minute per user
311
+ - **Export design**: 20 requests/minute per user
312
+ - **Thumbnails**: Expire after 15 minutes
313
+ - **Edit/View URLs**: Expire after 30 days
314
+
315
+ ## Troubleshooting
316
+
317
+ ### "No tokens found" error
318
+ Make sure your `onGetToken` callback returns tokens in the correct format:
319
+ ```javascript
320
+ { access_token: string, refresh_token: string, expires_at: number }
321
+ ```
322
+
323
+ ### OAuth redirect not working
324
+ Verify your redirect URI in Canva Developer Portal matches exactly:
325
+ ```
326
+ http://localhost:3000/canva/callback
327
+ ```
328
+
329
+ ### CORS errors
330
+ Token exchange must happen on the backend (Electron main process), not in the renderer. The module handles this automatically via IPC.
331
+
332
+ ### Designs not loading
333
+ Check that you enabled the correct scopes in Canva Developer Portal:
334
+ - `design:meta:read`
335
+ - `design:content:read`
336
+ - `folder:read`
337
+
338
+ ## License
339
+
340
+ UNLICENSED - Internal use only
341
+
342
+ ## Keyboard Shortcuts
343
+
344
+ Press `?` to view the keyboard shortcuts help modal in the app.
345
+
346
+ | Key | Action |
347
+ |-----|--------|
348
+ | `1` | Navigate to My Designs |
349
+ | `2` | Navigate to Favorites |
350
+ | `3` | Navigate to Brand Kit |
351
+ | `4` | Navigate to Templates |
352
+ | `5` | Navigate to Asset Library |
353
+ | `6` | Navigate to Compare View |
354
+ | `7` | Navigate to Scheduled Exports |
355
+ | `8` | Navigate to Analytics |
356
+ | `9` | Navigate to Design Requests |
357
+ | `/` or `Ctrl+F` | Focus search input |
358
+ | `V` | Toggle grid/list view |
359
+ | `Ctrl+A` | Select all designs |
360
+ | `Esc` | Deselect all / Close modals |
361
+ | `?` | Show keyboard shortcuts help |
362
+
363
+ ## Premium Features Guide
364
+
365
+ ### 1. Brand Kit Access
366
+ Access your brand colors, logos, and fonts quickly.
367
+ - Navigate via sidebar or press `3`
368
+ - Add custom brand colors with color picker
369
+ - Copy hex codes with one click
370
+ - Persistent storage per user
371
+
372
+ ### 2. Design Templates Browser
373
+ Browse Canva's template library by category.
374
+ - Navigate via sidebar or press `4`
375
+ - Click any category to open in Canva
376
+ - Categories: Social Media, Presentations, Marketing, Documents, and more
377
+
378
+ ### 3. Scheduled Publishing Queue
379
+ Schedule design exports for specific dates and times.
380
+ - Navigate via sidebar or press `7`
381
+ - Click "+ Schedule Export" to add new
382
+ - Set date, time, format, and quality
383
+ - Cancel scheduled exports anytime
384
+ - Persistent queue per user
385
+
386
+ ### 4. Design Annotations & Notes
387
+ Add notes, tags, and link designs to tasks.
388
+ - Right-click any design → "Notes & Tags"
389
+ - Add markdown-formatted notes
390
+ - Tag designs for organization
391
+ - Link to task IDs for tracking
392
+ - All annotations persist per user
393
+
394
+ ### 5. Quick Insert to Documents
395
+ Quickly insert designs into emails and documents.
396
+ - Right-click any design → "Quick Insert"
397
+ - Copy image URL for embedding
398
+ - Copy HTML snippet for emails
399
+ - Download directly to clipboard
400
+
401
+ ### 6. Design Comparison View
402
+ Compare up to 4 designs side-by-side.
403
+ - Navigate via sidebar or press `6`
404
+ - Right-click designs → "Add to Compare"
405
+ - View designs in grid layout
406
+ - Remove individual designs or clear all
407
+
408
+ ### 7. Asset Library Sync
409
+ Designate frequently-used designs as reusable assets.
410
+ - Navigate via sidebar or press `5`
411
+ - Right-click designs → "Add to Asset Library"
412
+ - Quick access to logos, icons, templates
413
+ - Copy URLs or download assets
414
+ - Persistent library per user
415
+
416
+ ### 8. Design Analytics Dashboard
417
+ Track design usage, views, and exports.
418
+ - Navigate via sidebar or press `8`
419
+ - View total designs, favorites, assets
420
+ - See recently viewed designs
421
+ - Track most viewed designs
422
+ - Export history and trends
423
+
424
+ ### 9. Batch Export with Presets
425
+ Export multiple designs with saved settings.
426
+ - Select multiple designs (Ctrl+Click)
427
+ - Click "Export" in toolbar
428
+ - Choose format, quality, naming pattern
429
+ - Save presets for future use
430
+ - Exports all selected designs
431
+
432
+ ### 10. Design Request System
433
+ Submit and track design requests.
434
+ - Navigate via sidebar or press `9`
435
+ - Click "+ New Request" to submit
436
+ - Track pending and completed requests
437
+ - Add title, description, dimensions, deadline
438
+ - Team collaboration feature
439
+
440
+ ## Built-in Themes
441
+
442
+ The module includes 34 professionally designed themes:
443
+
444
+ **Light Themes:** Default, Ocean, Forest, Sunset, Lavender, Rose, Mint, Peach, Sky, Coral
445
+
446
+ **Dark Themes:** Dark, Midnight, Forest Dark, Ocean Dark, Purple Dark, Red Dark, Teal Dark, Amber Dark, Blue Dark, Green Dark
447
+
448
+ **Vibrant Themes:** Neon, Cyberpunk, Retro, Pastel, Monochrome, High Contrast
449
+
450
+ **App-Specific:** Wire Scheduler, Office HQ, Tech Portal, ShipWorks
451
+
452
+ ### Applying Themes
453
+
454
+ ```javascript
455
+ // Via config
456
+ const canva = TacelCanva.initialize(container, {
457
+ theme: 'ocean',
458
+ // ... other config
459
+ });
460
+
461
+ // Programmatically
462
+ canva.setTheme('midnight');
463
+ ```
464
+
465
+ ### Custom Theme
466
+
467
+ ```css
468
+ .tacel-canva {
469
+ --tc-primary: #your-color;
470
+ --tc-primary-hover: #your-hover-color;
471
+ --tc-primary-light: rgba(your-color, 0.12);
472
+ --tc-bg: #ffffff;
473
+ --tc-bg-secondary: #f8fafc;
474
+ --tc-border: #e2e8f0;
475
+ --tc-text: #0f172a;
476
+ --tc-text-muted: #64748b;
477
+ /* ... see canva.css for all variables */
478
+ }
479
+ ```
480
+
481
+ ## Advanced Configuration
482
+
483
+ ### Feature Data Storage
484
+
485
+ The module requires IPC handlers for storing feature data:
486
+
487
+ ```javascript
488
+ // In main.js
489
+ const fs = require('fs');
490
+ const path = require('path');
491
+
492
+ const DATA_DIR = path.join(app.getPath('userData'), 'canva-data');
493
+
494
+ function ensureDataDir() {
495
+ if (!fs.existsSync(DATA_DIR)) {
496
+ fs.mkdirSync(DATA_DIR, { recursive: true });
497
+ }
498
+ }
499
+
500
+ function createFeatureStorage(filename) {
501
+ const filePath = path.join(DATA_DIR, filename);
502
+ return {
503
+ get: async (userId) => {
504
+ ensureDataDir();
505
+ if (fs.existsSync(filePath)) {
506
+ const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
507
+ return data[userId] || null;
508
+ }
509
+ return null;
510
+ },
511
+ save: async (userId, data) => {
512
+ ensureDataDir();
513
+ let cache = {};
514
+ if (fs.existsSync(filePath)) {
515
+ cache = JSON.parse(fs.readFileSync(filePath, 'utf8'));
516
+ }
517
+ cache[userId] = data;
518
+ fs.writeFileSync(filePath, JSON.stringify(cache, null, 2));
519
+ }
520
+ };
521
+ }
522
+
523
+ // Create storages
524
+ const brandKitStorage = createFeatureStorage('brand-kit.json');
525
+ const annotationsStorage = createFeatureStorage('annotations.json');
526
+ const assetLibraryStorage = createFeatureStorage('asset-library.json');
527
+ const analyticsStorage = createFeatureStorage('analytics.json');
528
+ const scheduledExportsStorage = createFeatureStorage('scheduled-exports.json');
529
+ const designRequestsStorage = createFeatureStorage('design-requests.json');
530
+
531
+ // Register handlers
532
+ ipcMain.handle('get-canva-brand-kit', async (event, userId) => {
533
+ return await brandKitStorage.get(userId);
534
+ });
535
+
536
+ ipcMain.handle('save-canva-brand-kit', async (event, { userId, brandKit }) => {
537
+ await brandKitStorage.save(userId, brandKit);
538
+ });
539
+
540
+ // Repeat for all feature storages...
541
+ ```
542
+
543
+ ### Design Cache Storage
544
+
545
+ For faster loading, implement design caching:
546
+
547
+ ```javascript
548
+ const designsCacheStorage = createFeatureStorage('designs-cache.json');
549
+
550
+ ipcMain.handle('get-canva-designs-cache', async (event, userId) => {
551
+ return await designsCacheStorage.get(userId);
552
+ });
553
+
554
+ ipcMain.handle('save-canva-designs-cache', async (event, { userId, designs, lastSync }) => {
555
+ await designsCacheStorage.save(userId, { designs, lastSync, count: designs.length });
556
+ });
557
+ ```
558
+
559
+ ## Complete IPC Channel Reference
560
+
561
+ ### Authentication Channels
562
+ - `canva:get-auth-url` - Get OAuth authorization URL
563
+ - `canva:exchange-token` - Exchange authorization code for tokens
564
+ - `canva:refresh-token` - Refresh access token
565
+ - `canva:revoke-token` - Revoke access token
566
+
567
+ ### Design Channels
568
+ - `canva:list-designs` - List user's designs with pagination
569
+ - `canva:get-design` - Get design details by ID
570
+ - `canva:export-design` - Export design to file
571
+ - `canva:get-export` - Get export job status
572
+
573
+ ### Storage Channels (App-Implemented)
574
+ - `get-canva-tokens` - Retrieve stored tokens
575
+ - `save-canva-tokens` - Save tokens to storage
576
+ - `delete-canva-tokens` - Delete tokens from storage
577
+ - `get-canva-collections` - Get user's collections
578
+ - `save-canva-collections` - Save collections
579
+ - `get-canva-designs-cache` - Get cached designs
580
+ - `save-canva-designs-cache` - Save designs cache
581
+ - `get-canva-brand-kit` - Get brand kit data
582
+ - `save-canva-brand-kit` - Save brand kit data
583
+ - `get-canva-annotations` - Get design annotations
584
+ - `save-canva-annotations` - Save annotations
585
+ - `get-canva-asset-library` - Get asset library
586
+ - `save-canva-asset-library` - Save asset library
587
+ - `get-canva-analytics` - Get analytics data
588
+ - `save-canva-analytics` - Save analytics data
589
+ - `get-canva-scheduled-exports` - Get scheduled exports
590
+ - `save-canva-scheduled-exports` - Save scheduled exports
591
+ - `get-canva-design-requests` - Get design requests
592
+ - `save-canva-design-requests` - Save design requests
593
+ - `download-canva-design` - Download design to file system
594
+
595
+ ## Performance Optimization
596
+
597
+ ### Design Caching
598
+ The module implements cache-first loading:
599
+ 1. Loads cached designs immediately for instant display
600
+ 2. Syncs with Canva API in background
601
+ 3. Updates UI when new designs are found
602
+ 4. Reduces API calls and improves perceived performance
603
+
604
+ ### Lazy Loading
605
+ - Thumbnails load with `loading="lazy"` attribute
606
+ - Pagination with continuation tokens
607
+ - Load more designs on demand
608
+
609
+ ### Debounced Search
610
+ Search input is debounced to reduce API calls while typing.
611
+
612
+ ## Browser Compatibility
613
+
614
+ - Chrome/Edge 90+
615
+ - Firefox 88+
616
+ - Safari 14+
617
+ - Electron 13+
618
+
619
+ ## Version History
620
+
621
+ ### v1.0.0 (Current)
622
+ - Initial release with all premium features
623
+ - 34 built-in themes
624
+ - 10 productivity features
625
+ - Keyboard shortcuts
626
+ - Inline design editor
627
+ - Toast notification system
628
+ - Glassmorphism UI
629
+ - Complete documentation
630
+
631
+ ## Support
632
+
633
+ For issues or questions, contact the Tacel development team.
634
+
635
+ ## License
636
+
637
+ UNLICENSED - Internal use only