@codellyson/framely-cli 0.1.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.
Files changed (40) hide show
  1. package/commands/compositions.js +135 -0
  2. package/commands/preview.js +889 -0
  3. package/commands/render.js +295 -0
  4. package/commands/still.js +165 -0
  5. package/index.js +93 -0
  6. package/package.json +60 -0
  7. package/studio/App.css +605 -0
  8. package/studio/App.jsx +185 -0
  9. package/studio/CompositionsView.css +399 -0
  10. package/studio/CompositionsView.jsx +327 -0
  11. package/studio/PropsEditor.css +195 -0
  12. package/studio/PropsEditor.tsx +176 -0
  13. package/studio/RenderDialog.tsx +476 -0
  14. package/studio/ShareDialog.tsx +200 -0
  15. package/studio/index.ts +19 -0
  16. package/studio/player/Player.css +199 -0
  17. package/studio/player/Player.jsx +355 -0
  18. package/studio/styles/design-system.css +592 -0
  19. package/studio/styles/dialogs.css +420 -0
  20. package/studio/templates/AnimatedGradient.jsx +99 -0
  21. package/studio/templates/InstagramStory.jsx +172 -0
  22. package/studio/templates/LowerThird.jsx +139 -0
  23. package/studio/templates/ProductShowcase.jsx +162 -0
  24. package/studio/templates/SlideTransition.jsx +211 -0
  25. package/studio/templates/SocialIntro.jsx +122 -0
  26. package/studio/templates/SubscribeAnimation.jsx +186 -0
  27. package/studio/templates/TemplateCard.tsx +58 -0
  28. package/studio/templates/TemplateFilters.tsx +97 -0
  29. package/studio/templates/TemplatePreviewDialog.tsx +196 -0
  30. package/studio/templates/TemplatesMarketplace.css +686 -0
  31. package/studio/templates/TemplatesMarketplace.tsx +172 -0
  32. package/studio/templates/TextReveal.jsx +134 -0
  33. package/studio/templates/UseTemplateDialog.tsx +154 -0
  34. package/studio/templates/index.ts +45 -0
  35. package/utils/browser.js +188 -0
  36. package/utils/codecs.js +200 -0
  37. package/utils/logger.js +35 -0
  38. package/utils/props.js +42 -0
  39. package/utils/render.js +447 -0
  40. package/utils/validate.js +148 -0
@@ -0,0 +1,592 @@
1
+ /* ═══════════════════════════════════════════════════════════════════════════
2
+ Framely Design System
3
+ Inspired by envii.dev - Modern dark theme with purple/indigo accents
4
+ ═══════════════════════════════════════════════════════════════════════════ */
5
+
6
+ /* ─── Font Imports ─── */
7
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap');
8
+
9
+ /* ─── Extended Design Tokens ─── */
10
+ :root {
11
+ /* Color Palette - Zinc scale (dark neutrals) */
12
+ --zinc-50: #fafafa;
13
+ --zinc-100: #f4f4f5;
14
+ --zinc-200: #e4e4e7;
15
+ --zinc-300: #d4d4d8;
16
+ --zinc-400: #a1a1aa;
17
+ --zinc-500: #71717a;
18
+ --zinc-600: #52525b;
19
+ --zinc-700: #3f3f46;
20
+ --zinc-800: #27272a;
21
+ --zinc-900: #18181b;
22
+ --zinc-950: #09090b;
23
+
24
+ /* Primary - Indigo/Purple */
25
+ --indigo-400: #818cf8;
26
+ --indigo-500: #6366f1;
27
+ --indigo-600: #4f46e5;
28
+ --purple-400: #c084fc;
29
+ --purple-500: #a855f7;
30
+ --purple-600: #9333ea;
31
+
32
+ /* Secondary - Cyan (for code highlights) */
33
+ --cyan-400: #22d3ee;
34
+ --cyan-500: #06b6d4;
35
+
36
+ /* Accent - Amber/Yellow */
37
+ --amber-400: #fbbf24;
38
+ --amber-500: #f59e0b;
39
+
40
+ /* Semantic */
41
+ --success: #10b981;
42
+ --error: #ef4444;
43
+ --warning: #f59e0b;
44
+
45
+ /* Typography */
46
+ --font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
47
+ --font-mono: 'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, monospace;
48
+ --font-display: 'Inter', ui-sans-serif, system-ui, sans-serif;
49
+
50
+ /* Font Sizes */
51
+ --text-xs: 0.75rem;
52
+ --text-sm: 0.875rem;
53
+ --text-base: 1rem;
54
+ --text-lg: 1.125rem;
55
+ --text-xl: 1.25rem;
56
+ --text-2xl: 1.5rem;
57
+ --text-3xl: 1.875rem;
58
+ --text-4xl: 2.25rem;
59
+ --text-5xl: 3rem;
60
+ --text-6xl: 3.75rem;
61
+ --text-7xl: 4.5rem;
62
+
63
+ /* Spacing */
64
+ --space-1: 0.25rem;
65
+ --space-2: 0.5rem;
66
+ --space-3: 0.75rem;
67
+ --space-4: 1rem;
68
+ --space-5: 1.25rem;
69
+ --space-6: 1.5rem;
70
+ --space-8: 2rem;
71
+ --space-10: 2.5rem;
72
+ --space-12: 3rem;
73
+ --space-16: 4rem;
74
+ --space-20: 5rem;
75
+ --space-24: 6rem;
76
+
77
+ /* Borders */
78
+ --radius-sm: 0.25rem;
79
+ --radius-md: 0.5rem;
80
+ --radius-lg: 0.75rem;
81
+ --radius-xl: 1rem;
82
+ --radius-2xl: 1.5rem;
83
+ --radius-full: 9999px;
84
+
85
+ /* Shadows */
86
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
87
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
88
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
89
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1);
90
+ --shadow-glow: 0 0 40px -10px var(--indigo-500);
91
+
92
+ /* Transitions */
93
+ --transition-fast: 150ms ease;
94
+ --transition-base: 200ms ease;
95
+ --transition-slow: 300ms ease;
96
+
97
+ /* Layout */
98
+ --max-width-sm: 640px;
99
+ --max-width-md: 768px;
100
+ --max-width-lg: 1024px;
101
+ --max-width-xl: 1280px;
102
+ --max-width-2xl: 1536px;
103
+ }
104
+
105
+ /* ─── Base Styles ─── */
106
+ *, *::before, *::after {
107
+ box-sizing: border-box;
108
+ margin: 0;
109
+ padding: 0;
110
+ }
111
+
112
+ html {
113
+ font-size: 16px;
114
+ -webkit-font-smoothing: antialiased;
115
+ -moz-osx-font-smoothing: grayscale;
116
+ text-rendering: optimizeLegibility;
117
+ }
118
+
119
+ body {
120
+ font-family: var(--font-sans);
121
+ font-size: var(--text-base);
122
+ line-height: 1.6;
123
+ color: var(--zinc-100);
124
+ background: var(--zinc-950);
125
+ }
126
+
127
+ /* Technical/Monospace elements */
128
+ code, pre, kbd, samp {
129
+ font-family: var(--font-mono);
130
+ font-size: 0.9em;
131
+ font-feature-settings: 'liga' 1, 'calt' 1;
132
+ }
133
+
134
+ /* Headings - slightly tighter tracking */
135
+ h1, h2, h3, h4, h5, h6 {
136
+ font-family: var(--font-display);
137
+ font-weight: 600;
138
+ line-height: 1.25;
139
+ letter-spacing: -0.02em;
140
+ color: var(--zinc-100);
141
+ }
142
+
143
+ h1 { font-size: var(--text-4xl); font-weight: 700; }
144
+ h2 { font-size: var(--text-3xl); }
145
+ h3 { font-size: var(--text-2xl); }
146
+ h4 { font-size: var(--text-xl); }
147
+ h5 { font-size: var(--text-lg); }
148
+ h6 { font-size: var(--text-base); }
149
+
150
+ /* Links */
151
+ a {
152
+ color: var(--indigo-400);
153
+ text-decoration: none;
154
+ transition: color var(--transition-fast);
155
+ }
156
+
157
+ a:hover {
158
+ color: var(--indigo-300, #a5b4fc);
159
+ }
160
+
161
+ /* Selection */
162
+ ::selection {
163
+ background: var(--indigo-500);
164
+ color: white;
165
+ }
166
+
167
+ /* Focus styles */
168
+ :focus-visible {
169
+ outline: 2px solid var(--indigo-500);
170
+ outline-offset: 2px;
171
+ }
172
+
173
+ /* Scrollbar styling */
174
+ ::-webkit-scrollbar {
175
+ width: 8px;
176
+ height: 8px;
177
+ }
178
+
179
+ ::-webkit-scrollbar-track {
180
+ background: var(--zinc-900);
181
+ }
182
+
183
+ ::-webkit-scrollbar-thumb {
184
+ background: var(--zinc-700);
185
+ border-radius: 4px;
186
+ }
187
+
188
+ ::-webkit-scrollbar-thumb:hover {
189
+ background: var(--zinc-600);
190
+ }
191
+
192
+ /* ─── Animations ─── */
193
+ @keyframes shimmer {
194
+ 0% { background-position: -200% 0; }
195
+ 100% { background-position: 200% 0; }
196
+ }
197
+
198
+ @keyframes pulse-glow {
199
+ 0%, 100% { opacity: 0.5; }
200
+ 50% { opacity: 1; }
201
+ }
202
+
203
+ @keyframes fade-in {
204
+ from { opacity: 0; transform: translateY(10px); }
205
+ to { opacity: 1; transform: translateY(0); }
206
+ }
207
+
208
+ @keyframes fade-in-up {
209
+ from { opacity: 0; transform: translateY(20px); }
210
+ to { opacity: 1; transform: translateY(0); }
211
+ }
212
+
213
+ @keyframes slide-in-right {
214
+ from { opacity: 0; transform: translateX(-20px); }
215
+ to { opacity: 1; transform: translateX(0); }
216
+ }
217
+
218
+ @keyframes float {
219
+ 0%, 100% { transform: translateY(0); }
220
+ 50% { transform: translateY(-10px); }
221
+ }
222
+
223
+ /* ─── Gradient Text ─── */
224
+ .gradient-text {
225
+ background: linear-gradient(135deg, var(--indigo-400), var(--purple-400));
226
+ -webkit-background-clip: text;
227
+ -webkit-text-fill-color: transparent;
228
+ background-clip: text;
229
+ }
230
+
231
+ .gradient-text-shimmer {
232
+ background: linear-gradient(
233
+ 90deg,
234
+ var(--indigo-400) 0%,
235
+ var(--purple-400) 25%,
236
+ var(--cyan-400) 50%,
237
+ var(--purple-400) 75%,
238
+ var(--indigo-400) 100%
239
+ );
240
+ background-size: 200% auto;
241
+ -webkit-background-clip: text;
242
+ -webkit-text-fill-color: transparent;
243
+ background-clip: text;
244
+ animation: shimmer 3s linear infinite;
245
+ }
246
+
247
+ /* ─── Glassmorphism ─── */
248
+ .glass {
249
+ background: rgba(24, 24, 27, 0.8);
250
+ backdrop-filter: blur(12px);
251
+ -webkit-backdrop-filter: blur(12px);
252
+ border: 1px solid rgba(255, 255, 255, 0.06);
253
+ }
254
+
255
+ .glass-subtle {
256
+ background: rgba(24, 24, 27, 0.6);
257
+ backdrop-filter: blur(8px);
258
+ -webkit-backdrop-filter: blur(8px);
259
+ border: 1px solid rgba(255, 255, 255, 0.04);
260
+ }
261
+
262
+ /* ─── Grid Pattern Background ─── */
263
+ .grid-pattern {
264
+ background-image:
265
+ linear-gradient(rgba(255, 255, 255, 0.02) 1px, transparent 1px),
266
+ linear-gradient(90deg, rgba(255, 255, 255, 0.02) 1px, transparent 1px);
267
+ background-size: 60px 60px;
268
+ }
269
+
270
+ .dot-pattern {
271
+ background-image: radial-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 1px);
272
+ background-size: 24px 24px;
273
+ }
274
+
275
+ /* ─── Glow Effects ─── */
276
+ .glow-indigo {
277
+ box-shadow: 0 0 60px -15px var(--indigo-500);
278
+ }
279
+
280
+ .glow-purple {
281
+ box-shadow: 0 0 60px -15px var(--purple-500);
282
+ }
283
+
284
+ .glow-border {
285
+ position: relative;
286
+ }
287
+
288
+ .glow-border::before {
289
+ content: '';
290
+ position: absolute;
291
+ inset: -1px;
292
+ border-radius: inherit;
293
+ padding: 1px;
294
+ background: linear-gradient(135deg, var(--indigo-500), var(--purple-500));
295
+ -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
296
+ -webkit-mask-composite: xor;
297
+ mask-composite: exclude;
298
+ opacity: 0.5;
299
+ transition: opacity var(--transition-base);
300
+ }
301
+
302
+ .glow-border:hover::before {
303
+ opacity: 1;
304
+ }
305
+
306
+ /* ─── Buttons ─── */
307
+ .btn {
308
+ display: inline-flex;
309
+ align-items: center;
310
+ justify-content: center;
311
+ gap: var(--space-2);
312
+ padding: var(--space-3) var(--space-5);
313
+ font-family: var(--font-sans);
314
+ font-size: var(--text-sm);
315
+ font-weight: 500;
316
+ line-height: 1;
317
+ border-radius: var(--radius-lg);
318
+ border: none;
319
+ cursor: pointer;
320
+ transition: all var(--transition-fast);
321
+ text-decoration: none;
322
+ }
323
+
324
+ .btn-primary {
325
+ background: linear-gradient(135deg, var(--indigo-500), var(--purple-600));
326
+ color: white;
327
+ box-shadow: 0 0 20px -5px var(--indigo-500);
328
+ }
329
+
330
+ .btn-primary:hover {
331
+ transform: translateY(-2px);
332
+ box-shadow: 0 0 30px -5px var(--indigo-500);
333
+ filter: brightness(1.1);
334
+ }
335
+
336
+ .btn-secondary {
337
+ background: rgba(255, 255, 255, 0.06);
338
+ color: var(--zinc-100);
339
+ border: 1px solid rgba(255, 255, 255, 0.1);
340
+ }
341
+
342
+ .btn-secondary:hover {
343
+ background: rgba(255, 255, 255, 0.1);
344
+ border-color: rgba(255, 255, 255, 0.2);
345
+ }
346
+
347
+ .btn-ghost {
348
+ background: transparent;
349
+ color: var(--zinc-400);
350
+ }
351
+
352
+ .btn-ghost:hover {
353
+ color: var(--zinc-100);
354
+ background: rgba(255, 255, 255, 0.06);
355
+ }
356
+
357
+ .btn-lg {
358
+ padding: var(--space-4) var(--space-8);
359
+ font-size: var(--text-base);
360
+ border-radius: var(--radius-xl);
361
+ }
362
+
363
+ .btn-sm {
364
+ padding: var(--space-2) var(--space-4);
365
+ font-size: var(--text-xs);
366
+ }
367
+
368
+ /* ─── Cards ─── */
369
+ .card {
370
+ background: var(--zinc-900);
371
+ border: 1px solid rgba(255, 255, 255, 0.06);
372
+ border-radius: var(--radius-xl);
373
+ padding: var(--space-6);
374
+ transition: all var(--transition-base);
375
+ }
376
+
377
+ .card:hover {
378
+ border-color: rgba(255, 255, 255, 0.1);
379
+ transform: translateY(-2px);
380
+ }
381
+
382
+ .card-glass {
383
+ background: rgba(24, 24, 27, 0.6);
384
+ backdrop-filter: blur(12px);
385
+ -webkit-backdrop-filter: blur(12px);
386
+ border: 1px solid rgba(255, 255, 255, 0.06);
387
+ border-radius: var(--radius-xl);
388
+ padding: var(--space-6);
389
+ }
390
+
391
+ /* ─── Code Blocks ─── */
392
+ .code-block {
393
+ background: var(--zinc-900);
394
+ border: 1px solid rgba(255, 255, 255, 0.06);
395
+ border-radius: var(--radius-lg);
396
+ padding: var(--space-4);
397
+ font-family: var(--font-mono);
398
+ font-size: var(--text-sm);
399
+ line-height: 1.7;
400
+ overflow-x: auto;
401
+ }
402
+
403
+ .code-block .keyword { color: var(--purple-400); }
404
+ .code-block .string { color: var(--amber-400); }
405
+ .code-block .function { color: var(--cyan-400); }
406
+ .code-block .comment { color: var(--zinc-500); }
407
+ .code-block .property { color: var(--indigo-400); }
408
+ .code-block .number { color: var(--indigo-400); }
409
+
410
+ /* ─── Terminal Window ─── */
411
+ .terminal {
412
+ background: var(--zinc-950);
413
+ border: 1px solid rgba(255, 255, 255, 0.08);
414
+ border-radius: var(--radius-xl);
415
+ overflow: hidden;
416
+ box-shadow: var(--shadow-xl);
417
+ }
418
+
419
+ .terminal-header {
420
+ display: flex;
421
+ align-items: center;
422
+ gap: var(--space-2);
423
+ padding: var(--space-3) var(--space-4);
424
+ background: rgba(255, 255, 255, 0.03);
425
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06);
426
+ }
427
+
428
+ .terminal-dot {
429
+ width: 12px;
430
+ height: 12px;
431
+ border-radius: 50%;
432
+ }
433
+
434
+ .terminal-dot.red { background: #ff5f57; }
435
+ .terminal-dot.yellow { background: #febc2e; }
436
+ .terminal-dot.green { background: #28c840; }
437
+
438
+ .terminal-title {
439
+ flex: 1;
440
+ text-align: center;
441
+ font-size: var(--text-xs);
442
+ color: var(--zinc-500);
443
+ font-family: var(--font-mono);
444
+ }
445
+
446
+ .terminal-body {
447
+ padding: var(--space-4);
448
+ font-family: var(--font-mono);
449
+ font-size: var(--text-sm);
450
+ line-height: 1.7;
451
+ color: var(--zinc-300);
452
+ }
453
+
454
+ .terminal-body .prompt {
455
+ color: var(--cyan-400);
456
+ }
457
+
458
+ .terminal-body .command {
459
+ color: var(--zinc-100);
460
+ }
461
+
462
+ .terminal-body .output {
463
+ color: var(--zinc-400);
464
+ }
465
+
466
+ .terminal-body .success {
467
+ color: var(--success);
468
+ }
469
+
470
+ /* ─── Badges/Pills ─── */
471
+ .badge {
472
+ display: inline-flex;
473
+ align-items: center;
474
+ gap: var(--space-1);
475
+ padding: var(--space-1) var(--space-3);
476
+ font-size: var(--text-xs);
477
+ font-weight: 500;
478
+ border-radius: var(--radius-full);
479
+ background: rgba(255, 255, 255, 0.06);
480
+ color: var(--zinc-400);
481
+ border: 1px solid rgba(255, 255, 255, 0.08);
482
+ }
483
+
484
+ .badge-primary {
485
+ background: rgba(99, 102, 241, 0.15);
486
+ color: var(--indigo-400);
487
+ border-color: rgba(99, 102, 241, 0.3);
488
+ }
489
+
490
+ .badge-success {
491
+ background: rgba(16, 185, 129, 0.15);
492
+ color: var(--success);
493
+ border-color: rgba(16, 185, 129, 0.3);
494
+ }
495
+
496
+ /* ─── Section Headings ─── */
497
+ .section-label {
498
+ display: inline-flex;
499
+ align-items: center;
500
+ gap: var(--space-2);
501
+ font-size: var(--text-xs);
502
+ font-weight: 600;
503
+ text-transform: uppercase;
504
+ letter-spacing: 0.1em;
505
+ color: var(--indigo-400);
506
+ margin-bottom: var(--space-4);
507
+ }
508
+
509
+ .section-title {
510
+ font-size: var(--text-4xl);
511
+ font-weight: 700;
512
+ color: var(--zinc-100);
513
+ line-height: 1.2;
514
+ letter-spacing: -0.02em;
515
+ }
516
+
517
+ .section-subtitle {
518
+ font-size: var(--text-lg);
519
+ color: var(--zinc-400);
520
+ line-height: 1.6;
521
+ max-width: 600px;
522
+ }
523
+
524
+ /* ─── Navigation ─── */
525
+ .nav {
526
+ display: flex;
527
+ align-items: center;
528
+ gap: var(--space-8);
529
+ }
530
+
531
+ .nav-link {
532
+ font-size: var(--text-sm);
533
+ font-weight: 500;
534
+ color: var(--zinc-400);
535
+ text-decoration: none;
536
+ transition: color var(--transition-fast);
537
+ }
538
+
539
+ .nav-link:hover {
540
+ color: var(--zinc-100);
541
+ }
542
+
543
+ .nav-link.active {
544
+ color: var(--zinc-100);
545
+ }
546
+
547
+ /* ─── Utility Classes ─── */
548
+ .container {
549
+ width: 100%;
550
+ max-width: var(--max-width-xl);
551
+ margin: 0 auto;
552
+ padding: 0 var(--space-6);
553
+ }
554
+
555
+ .container-lg {
556
+ max-width: var(--max-width-lg);
557
+ }
558
+
559
+ .container-sm {
560
+ max-width: var(--max-width-sm);
561
+ }
562
+
563
+ .flex { display: flex; }
564
+ .flex-col { flex-direction: column; }
565
+ .items-center { align-items: center; }
566
+ .items-start { align-items: flex-start; }
567
+ .justify-center { justify-content: center; }
568
+ .justify-between { justify-content: space-between; }
569
+ .gap-1 { gap: var(--space-1); }
570
+ .gap-2 { gap: var(--space-2); }
571
+ .gap-3 { gap: var(--space-3); }
572
+ .gap-4 { gap: var(--space-4); }
573
+ .gap-6 { gap: var(--space-6); }
574
+ .gap-8 { gap: var(--space-8); }
575
+
576
+ .text-center { text-align: center; }
577
+ .text-left { text-align: left; }
578
+
579
+ .w-full { width: 100%; }
580
+ .h-full { height: 100%; }
581
+
582
+ .mt-auto { margin-top: auto; }
583
+ .mx-auto { margin-left: auto; margin-right: auto; }
584
+
585
+ /* ─── Responsive Visibility ─── */
586
+ @media (max-width: 768px) {
587
+ .hide-mobile { display: none !important; }
588
+ }
589
+
590
+ @media (min-width: 769px) {
591
+ .show-mobile { display: none !important; }
592
+ }