@cyber-dash-tech/revela 0.1.1 → 0.1.3

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.
@@ -1,1100 +0,0 @@
1
- ---
2
- name: default
3
- description: Clean modern dark theme — works for any topic
4
- author: slides-it
5
- version: 1.0.0
6
- preview: https://raw.githubusercontent.com/slides-it/slides-it/main/slides_it/designs/default/preview.png
7
- ---
8
-
9
- ## Visual Style — Aurora Theme
10
-
11
- Apply this visual style when generating all slides in this session.
12
-
13
- <!-- @section:global:start -->
14
-
15
- ### Color Palette
16
-
17
- ```css
18
- :root {
19
- --bg-primary: #030712; /* deep night sky */
20
- --bg-secondary: #0f172a; /* slightly lighter */
21
- --bg-card: rgba(30, 41, 59, 0.6); /* translucent card */
22
- --text-primary: #f8fafc;
23
- --text-secondary:#94a3b8;
24
- --accent: #22d3ee; /* cyan aurora */
25
- --accent-2: #a78bfa; /* violet aurora */
26
- --accent-3: #34d399; /* emerald highlight */
27
- --border: rgba(34, 211, 238, 0.15);
28
- --glow: rgba(34, 211, 238, 0.25);
29
- }
30
- ```
31
-
32
- ### Typography
33
-
34
- - **Display font**: `Clash Display` (headings) — load from Fontshare
35
- - **Body font**: `Satoshi` (body, captions) — load from Fontshare
36
- - Font link tag:
37
- ```html
38
- <link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=clash-display@600,700&f[]=satoshi@400,500&display=swap">
39
- ```
40
- - Title size (h1): `80px`, weight 700
41
- - Section heading (h2): `38px`, weight 600
42
- - Subtitle size: `24px`
43
- - Body size: `18px`
44
- - Label: `13px`, letter-spacing `0.12em`, uppercase
45
- - Card title: `22px`, weight 600
46
- - Card body: `17px`
47
- - Stat number: `64px`, weight 700
48
- - Stat label: `15px`, uppercase
49
- - Text shadow on titles: `0 0 40px rgba(34, 211, 238, 0.3)` (subtle glow)
50
- - Line-height: `1.1` (h1), `1.2` (h2), `1.6` (subtitle, body-text), `1.7` (card-body, evidence-list)
51
- - Letter-spacing: `-0.02em` (h1), `-0.01em` (h2), `0.12em` (label), `0.06em` (stat-label)
52
- - Subtitle: weight 400
53
- - Body / card-body: weight 400
54
- - Stat label: weight 500
55
-
56
- All sizes are fixed `px` — designed for the 1920×1080 canvas. JS `transform: scale()`
57
- handles viewport adaptation. **Never use `clamp()` or viewport-relative units.**
58
-
59
- ### Background Layers (Order: back to front)
60
-
61
- **Layer 1 — Base gradient:**
62
- ```css
63
- body::before {
64
- content: '';
65
- position: fixed;
66
- inset: 0;
67
- background: radial-gradient(ellipse 120% 80% at 50% 0%, #1e1b4b 0%, #030712 60%);
68
- z-index: -3;
69
- }
70
- ```
71
-
72
- **Layer 2 — Noise texture:**
73
- ```css
74
- body::after {
75
- content: '';
76
- position: fixed;
77
- inset: 0;
78
- background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
79
- opacity: 0.03;
80
- z-index: -2;
81
- pointer-events: none;
82
- }
83
- ```
84
-
85
- **Layer 3 — Aurora ribbons (3 layers, different colors/speeds):**
86
- ```css
87
- .aurora-1, .aurora-2, .aurora-3 {
88
- position: fixed;
89
- width: 150%;
90
- height: 60%;
91
- filter: blur(80px);
92
- opacity: 0.6;
93
- animation: aurora-drift 25s ease-in-out infinite alternate;
94
- z-index: -1;
95
- pointer-events: none;
96
- }
97
- .aurora-1 {
98
- top: -10%;
99
- left: -25%;
100
- background: linear-gradient(135deg, #22d3ee 0%, transparent 60%);
101
- animation-duration: 28s;
102
- }
103
- .aurora-2 {
104
- top: 20%;
105
- right: -30%;
106
- background: linear-gradient(225deg, #a78bfa 0%, transparent 50%);
107
- animation-duration: 35s;
108
- animation-delay: -10s;
109
- }
110
- .aurora-3 {
111
- top: 40%;
112
- left: 10%;
113
- background: linear-gradient(90deg, #34d399 0%, transparent 40%);
114
- animation-duration: 22s;
115
- animation-delay: -5s;
116
- opacity: 0.4;
117
- }
118
- @keyframes aurora-drift {
119
- 0% { transform: translate(0, 0) scale(1); }
120
- 50% { transform: translate(30px, -20px) scale(1.1); }
121
- 100% { transform: translate(-20px, 20px) scale(0.95); }
122
- }
123
- ```
124
-
125
- **Layer 4 — Stars (optional, sparse):**
126
- ```css
127
- .stars {
128
- position: fixed;
129
- inset: 0;
130
- background-image: radial-gradient(1px 1px at 20% 30%, white 50%, transparent),
131
- radial-gradient(1px 1px at 40% 70%, white 50%, transparent),
132
- radial-gradient(1.5px 1.5px at 60% 20%, white 50%, transparent),
133
- radial-gradient(1px 1px at 80% 60%, white 50%, transparent);
134
- opacity: 0.7;
135
- z-index: -1;
136
- pointer-events: none;
137
- }
138
- ```
139
-
140
- ### Slide Layout
141
-
142
- - **1920×1080 fixed canvas** — each slide uses a `.slide-canvas` (1920×1080px),
143
- scaled to fit the viewport via JS `transform: scale()`.
144
- - Content width tiers (inside canvas, via `max-width` + `margin: 0 auto`):
145
- - Default (`1200px`): Cover, Quote, Closing
146
- - Wide (`1600px`): content-heavy slides (grids, multi-column, process flows)
147
- - Canvas padding: `60px 80px`
148
- - **No `clamp()` — use fixed `px` for all sizes.** The canvas is always
149
- 1920×1080 and JS handles scaling, so all typography and spacing must be fixed `px`.
150
- - **Canvas utilization** — Elements should fill approximately 70–80% of the
151
- 1920×1080 canvas area. Avoid large empty zones. Use taller cards (`min-height`),
152
- larger stat numbers, wider grids, and generous card padding to occupy available
153
- space. Content should feel comfortably placed, not floating in emptiness — but
154
- preserve enough breathing room to maintain elegance.
155
- - **Content slides** (Feature Cards, Stats, Two-Column, Step Flow): grid/flex
156
- containers should stretch toward the canvas edges. Cards should have ample
157
- internal padding and body text so they feel substantial.
158
- - **Sparse slides** (Cover, Quote, Closing): add decorative fills — aurora-colored
159
- gradient circles (`position: absolute`, low opacity), extra accent lines,
160
- corner geometric shapes, or large background `"` marks for quotes. These
161
- anchor the composition without overcrowding the message.
162
- - **Never** leave more than ~20% of the canvas visually empty on any slide.
163
- - Title slide: large centered heading + glowing accent line beneath
164
- - Content slides: heading top-left, content below with glassmorphism cards
165
-
166
- ### HTML Structure
167
-
168
- Every generated presentation must use this exact HTML skeleton:
169
-
170
- ```html
171
- <!DOCTYPE html>
172
- <html lang="{language}">
173
- <head>
174
- <meta charset="UTF-8">
175
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
176
- <title>{Presentation Title}</title>
177
- <link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=clash-display@600,700&f[]=satoshi@400,500&display=swap">
178
- <script src="https://cdn.jsdelivr.net/npm/lucide@latest/dist/umd/lucide.js"></script>
179
- <!-- <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script> ← only if charts needed -->
180
- <style>/* all CSS here */</style>
181
- </head>
182
- <body>
183
- <!-- Aurora background layers -->
184
- <div class="aurora-1"></div>
185
- <div class="aurora-2"></div>
186
- <div class="aurora-3"></div>
187
- <div class="stars"></div>
188
-
189
- <!-- Navigation -->
190
- <div class="progress-bar" id="progressBar"></div>
191
- <nav class="nav-dots" id="navDots" aria-label="Slide navigation"></nav>
192
-
193
- <!-- Slides -->
194
- <section class="slide title-slide" data-slide-type="cover" data-index="0">
195
- <div class="slide-canvas"> ... </div>
196
- </section>
197
- <section class="slide" data-slide-type="content" data-index="1">
198
- <div class="slide-canvas"> ... </div>
199
- </section>
200
- <!-- every <section class="slide"> must have data-slide-type — see SKILL.md for valid values -->
201
-
202
- <script>/* all JS here */</script>
203
- </body>
204
- </html>
205
- ```
206
-
207
- ### Core CSS
208
-
209
- ```css
210
- * { box-sizing: border-box; margin: 0; padding: 0; }
211
-
212
- html {
213
- scroll-snap-type: y mandatory;
214
- overflow-y: scroll;
215
- height: 100%;
216
- }
217
-
218
- body {
219
- background: var(--bg-primary);
220
- color: var(--text-primary);
221
- font-family: 'Satoshi', ui-sans-serif, sans-serif;
222
- -webkit-font-smoothing: antialiased;
223
- height: 100%;
224
- }
225
-
226
- .slide {
227
- height: 100dvh;
228
- scroll-snap-align: start;
229
- overflow: hidden;
230
- display: flex;
231
- align-items: center;
232
- justify-content: center;
233
- background: transparent;
234
- }
235
-
236
- .slide-canvas {
237
- width: 1920px;
238
- height: 1080px;
239
- flex-shrink: 0;
240
- transform-origin: center center;
241
- /* scale set by JS setupScaling() */
242
- overflow: hidden;
243
- position: relative;
244
- display: flex;
245
- flex-direction: column;
246
- justify-content: center;
247
- padding: 60px 80px;
248
- }
249
- ```
250
-
251
- ### Navigation & Progress
252
-
253
- #### Progress Bar
254
-
255
- ```css
256
- .progress-bar {
257
- position: fixed;
258
- top: 0;
259
- left: 0;
260
- height: 3px;
261
- background: linear-gradient(90deg, var(--accent), var(--accent-2));
262
- width: 0%;
263
- z-index: 100;
264
- transition: width 0.2s ease;
265
- box-shadow: 0 0 8px var(--glow);
266
- }
267
- ```
268
-
269
- #### Nav Dots
270
-
271
- ```css
272
- .nav-dots {
273
- position: fixed;
274
- right: 20px;
275
- top: 50%;
276
- transform: translateY(-50%);
277
- display: flex;
278
- flex-direction: column;
279
- gap: 8px;
280
- z-index: 100;
281
- }
282
- .nav-dots button {
283
- width: 6px;
284
- height: 6px;
285
- border-radius: 50%;
286
- border: 1px solid rgba(34, 211, 238, 0.4);
287
- background: transparent;
288
- cursor: pointer;
289
- padding: 0;
290
- transition: background 0.2s, border-color 0.2s;
291
- }
292
- .nav-dots button.active {
293
- background: var(--accent);
294
- border-color: var(--accent);
295
- box-shadow: 0 0 6px var(--glow);
296
- }
297
- ```
298
-
299
- #### Reduced Motion
300
-
301
- ```css
302
- @media (prefers-reduced-motion: reduce) {
303
- .aurora-1, .aurora-2, .aurora-3 {
304
- animation: none;
305
- opacity: 0.3;
306
- }
307
- .reveal {
308
- transition: opacity 0.4s ease;
309
- transform: none !important;
310
- }
311
- }
312
- ```
313
-
314
- ### SlidePresentation Class (Complete JavaScript)
315
-
316
- All presentations must include this complete `SlidePresentation` class. Every
317
- method is fully implemented — copy this exactly and include it in the `<script>`
318
- block.
319
-
320
- ```javascript
321
- class SlidePresentation {
322
- constructor() {
323
- this.slides = document.querySelectorAll('.slide');
324
- this.currentSlide = 0;
325
- this.setupScaling();
326
- this.setupProgressBar();
327
- this.setupNavDots();
328
- this.setupIntersectionObserver();
329
- this.setupKeyboardNav();
330
- this.setupTouchNav();
331
- this.setupMouseWheel();
332
- }
333
-
334
- /* Scale 1920×1080 canvases to fit viewport */
335
- setupScaling() {
336
- const canvases = document.querySelectorAll('.slide-canvas');
337
- const BASE_W = 1920, BASE_H = 1080;
338
- const update = () => {
339
- const vw = window.innerWidth;
340
- const vh = window.innerHeight;
341
- const scale = Math.min(vw / BASE_W, vh / BASE_H);
342
- canvases.forEach(c => { c.style.transform = `scale(${scale})`; });
343
- };
344
- window.addEventListener('resize', update);
345
- update();
346
- }
347
-
348
- /* Horizontal progress bar at top */
349
- setupProgressBar() {
350
- const bar = document.getElementById('progressBar');
351
- const update = () => {
352
- const scrolled = window.scrollY;
353
- const total = document.body.scrollHeight - window.innerHeight;
354
- bar.style.width = total > 0 ? (scrolled / total * 100) + '%' : '0%';
355
- };
356
- window.addEventListener('scroll', update, { passive: true });
357
- update();
358
- }
359
-
360
- /* Vertical dot navigation on right side */
361
- setupNavDots() {
362
- const nav = document.getElementById('navDots');
363
- this.slides.forEach((_, i) => {
364
- const btn = document.createElement('button');
365
- btn.setAttribute('aria-label', `Go to slide ${i + 1}`);
366
- if (i === 0) btn.classList.add('active');
367
- btn.addEventListener('click', () => this.goTo(i));
368
- nav.appendChild(btn);
369
- });
370
- this.dots = nav.querySelectorAll('button');
371
-
372
- const obs = new IntersectionObserver((entries) => {
373
- entries.forEach(e => {
374
- if (e.isIntersecting) {
375
- const idx = parseInt(e.target.dataset.index);
376
- this.dots.forEach((d, i) => d.classList.toggle('active', i === idx));
377
- this.currentSlide = idx;
378
- }
379
- });
380
- }, { threshold: 0.5 });
381
- this.slides.forEach(s => obs.observe(s));
382
- }
383
-
384
- /* Reveal animations on scroll */
385
- setupIntersectionObserver() {
386
- const obs = new IntersectionObserver((entries) => {
387
- entries.forEach(e => {
388
- if (e.isIntersecting) {
389
- e.target.querySelectorAll('.reveal, .title-reveal').forEach(el => el.classList.add('visible'));
390
- /* If animateCounters is defined, call it for stat cards */
391
- if (typeof animateCounters === 'function') animateCounters(e.target);
392
- }
393
- });
394
- }, { threshold: 0.15 });
395
- this.slides.forEach(s => obs.observe(s));
396
- }
397
-
398
- /* Arrow keys, Space, PageUp/PageDown */
399
- setupKeyboardNav() {
400
- document.addEventListener('keydown', e => {
401
- if (['ArrowDown', 'ArrowRight', ' ', 'PageDown'].includes(e.key)) {
402
- e.preventDefault();
403
- this.goTo(this.currentSlide + 1);
404
- } else if (['ArrowUp', 'ArrowLeft', 'PageUp'].includes(e.key)) {
405
- e.preventDefault();
406
- this.goTo(this.currentSlide - 1);
407
- }
408
- });
409
- }
410
-
411
- /* Swipe support for touch devices */
412
- setupTouchNav() {
413
- let startY = 0;
414
- document.addEventListener('touchstart', e => { startY = e.touches[0].clientY; }, { passive: true });
415
- document.addEventListener('touchend', e => {
416
- const dy = startY - e.changedTouches[0].clientY;
417
- if (Math.abs(dy) > 40) this.goTo(this.currentSlide + (dy > 0 ? 1 : -1));
418
- }, { passive: true });
419
- }
420
-
421
- /* Debounced mouse wheel navigation (800ms) */
422
- setupMouseWheel() {
423
- let last = 0;
424
- document.addEventListener('wheel', e => {
425
- const now = Date.now();
426
- if (now - last < 800) return;
427
- last = now;
428
- this.goTo(this.currentSlide + (e.deltaY > 0 ? 1 : -1));
429
- }, { passive: true });
430
- }
431
-
432
- /* Scroll to slide by index */
433
- goTo(idx) {
434
- const clamped = Math.max(0, Math.min(this.slides.length - 1, idx));
435
- this.slides[clamped].scrollIntoView({ behavior: 'smooth' });
436
- this.currentSlide = clamped;
437
- }
438
- }
439
-
440
- new SlidePresentation();
441
- ```
442
-
443
- After the `SlidePresentation` class, include:
444
- 1. `lucide.createIcons();` to render Lucide icons
445
- 2. Counter animation function (if stat cards with `data-target` are present)
446
- 3. ECharts initialization (if charts are present)
447
- 4. Inline editing code (see SKILL.md)
448
-
449
- <!-- @section:global:end -->
450
-
451
- <!-- @section:components:start -->
452
-
453
- ### Component Library
454
-
455
- These are independent, composable building blocks. Mix them freely on any slide —
456
- they are not locked to specific layouts.
457
-
458
- <!-- @component:reveal:start -->
459
- #### Reveal Animation (.reveal)
460
-
461
- Add `.reveal` to any element that should animate on scroll. JS adds `.visible`
462
- via IntersectionObserver. Use `.title-reveal` for cover/closing slide headings.
463
-
464
- ```css
465
- .reveal {
466
- opacity: 0;
467
- transform: translateY(24px);
468
- transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1),
469
- transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
470
- }
471
- .reveal.visible {
472
- opacity: 1;
473
- transform: translateY(0);
474
- }
475
- /* Stagger children */
476
- .reveal:nth-child(1) { transition-delay: 0s; }
477
- .reveal:nth-child(2) { transition-delay: 0.1s; }
478
- .reveal:nth-child(3) { transition-delay: 0.1s; }
479
- .reveal:nth-child(4) { transition-delay: 0.2s; }
480
- .reveal:nth-child(5) { transition-delay: 0.3s; }
481
- .reveal:nth-child(6) { transition-delay: 0.4s; }
482
-
483
- .title-reveal {
484
- opacity: 0;
485
- transform: translateY(24px) scale(0.97);
486
- transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1),
487
- transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
488
- }
489
- .title-reveal.visible {
490
- opacity: 1;
491
- transform: translateY(0) scale(1);
492
- }
493
- ```
494
-
495
- <!-- @component:reveal:end -->
496
-
497
- <!-- @component:showcase:start -->
498
- #### Showcase (.showcase)
499
-
500
- Semi-transparent container that frames a component or image with padding and
501
- visual depth. Use inside `.two-col-aside`, `.two-col-main`, or as a standalone
502
- wrapper when a component needs a "stage" rather than sitting directly on the
503
- slide background. Vertically and horizontally centers its content.
504
-
505
- ```css
506
- .showcase {
507
- padding: 32px;
508
- border: 1px solid var(--border);
509
- background: var(--bg-card);
510
- backdrop-filter: blur(12px);
511
- -webkit-backdrop-filter: blur(12px);
512
- border-radius: 16px;
513
- display: flex;
514
- align-items: center;
515
- justify-content: center;
516
- flex: 1;
517
- }
518
- ```
519
-
520
- <!-- @component:showcase:end -->
521
-
522
- <!-- @component:card:start -->
523
- #### Card (.card)
524
-
525
- Glassmorphism container for any grouped content — features, evidence, info blocks.
526
-
527
- ```html
528
- <div class="card">
529
- <i data-lucide="sparkles" class="card-icon"></i>
530
- <p class="card-label">Label</p>
531
- <p class="card-title">Title</p>
532
- <p class="card-body">Body text describing the item.</p>
533
- </div>
534
- ```
535
-
536
- All inner elements are optional — use only what the content needs.
537
-
538
- ```css
539
- .card {
540
- background: var(--bg-card);
541
- backdrop-filter: blur(12px);
542
- -webkit-backdrop-filter: blur(12px);
543
- border: 1px solid var(--border);
544
- border-radius: 16px;
545
- padding: 36px;
546
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
547
- display: flex;
548
- flex-direction: column;
549
- justify-content: flex-start;
550
- transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
551
- }
552
- .card:hover {
553
- transform: translateY(-4px);
554
- box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4), 0 0 0 1px var(--glow);
555
- border-color: var(--glow);
556
- }
557
- .card-icon { width: 32px; height: 32px; color: var(--accent); margin-bottom: 16px; transition: transform 0.2s ease; }
558
- .card:hover .card-icon { transform: scale(1.15); }
559
- .card-label { font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent); margin-bottom: 10px; font-weight: 500; }
560
- .card-title { font-family: 'Clash Display', sans-serif; font-size: 22px; margin-bottom: 12px; font-weight: 600; }
561
- .card-body { font-size: 17px; color: var(--text-secondary); line-height: 1.7; flex: 1; }
562
- ```
563
-
564
- <!-- @component:card:end -->
565
-
566
- <!-- @component:image-card:start -->
567
- #### Image Card (.image-card)
568
-
569
- Standalone image with rounded corners and optional caption. Use for product shots,
570
- screenshots, team photos, or any visual that deserves its own space.
571
-
572
- ```html
573
- <div class="image-card">
574
- <img src="photo.jpg" alt="Description">
575
- <p class="image-card-caption">Optional caption text</p>
576
- </div>
577
- ```
578
-
579
- Caption is optional — omit when the image is self-explanatory.
580
-
581
- ```css
582
- .image-card {
583
- border-radius: 16px;
584
- overflow: hidden;
585
- border: 1px solid var(--border);
586
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
587
- display: flex;
588
- flex-direction: column;
589
- }
590
- .image-card img {
591
- width: 100%;
592
- height: 100%;
593
- object-fit: cover;
594
- display: block;
595
- }
596
- .image-card-caption {
597
- padding: 16px 20px;
598
- font-size: 14px;
599
- color: var(--text-secondary);
600
- background: var(--bg-card);
601
- backdrop-filter: blur(12px);
602
- }
603
- ```
604
-
605
- Sizing: set `width` and `height` on `.image-card` via inline style to control
606
- aspect ratio. Typical: `width:100%; height:400px` in a column, or
607
- `width:480px; height:320px` standalone.
608
-
609
- <!-- @component:image-card:end -->
610
-
611
- <!-- @component:card-img:start -->
612
- #### Card with Image Header (.card-img)
613
-
614
- Card variant with an image at the top and text content below. Use for team
615
- members, portfolio items, or any card where a visual header adds context.
616
-
617
- ```html
618
- <div class="card card-img">
619
- <div class="card-img-top">
620
- <img src="photo.jpg" alt="Description">
621
- </div>
622
- <p class="card-title">Title</p>
623
- <p class="card-body">Description text goes here.</p>
624
- </div>
625
- ```
626
-
627
- ```css
628
- .card-img {
629
- padding: 0;
630
- overflow: hidden;
631
- }
632
- .card-img-top {
633
- width: 100%;
634
- aspect-ratio: 16 / 10;
635
- overflow: hidden;
636
- }
637
- .card-img-top img {
638
- width: 100%;
639
- height: 100%;
640
- object-fit: cover;
641
- display: block;
642
- }
643
- .card-img .card-title,
644
- .card-img .card-body,
645
- .card-img .card-label {
646
- padding-left: 36px;
647
- padding-right: 36px;
648
- }
649
- .card-img .card-title { padding-top: 24px; }
650
- .card-img .card-body { padding-bottom: 36px; }
651
- ```
652
-
653
- <!-- @component:card-img:end -->
654
-
655
- <!-- @component:avatar:start -->
656
- #### Avatar (.avatar)
657
-
658
- Circular cropped image for people, team members, or profile pictures.
659
-
660
- ```html
661
- <img src="person.jpg" alt="Name" class="avatar avatar-lg">
662
- ```
663
-
664
- ```css
665
- .avatar {
666
- width: 64px;
667
- height: 64px;
668
- border-radius: 50%;
669
- object-fit: cover;
670
- border: 2px solid var(--border);
671
- box-shadow: 0 0 12px var(--glow);
672
- flex-shrink: 0;
673
- }
674
- .avatar-sm { width: 48px; height: 48px; }
675
- .avatar-lg { width: 96px; height: 96px; }
676
- ```
677
-
678
- Pair with card text for team slides: avatar left, name + role right. Or use
679
- in a horizontal row for a team overview.
680
-
681
- <!-- @component:avatar:end -->
682
-
683
- <!-- @component:stat-card:start -->
684
- #### Stat Card (.stat-card)
685
-
686
- Large metric display. Use `data-target` for counter animation, `.gradient-text` on numbers.
687
-
688
- ```html
689
- <div class="stat-card">
690
- <div class="stat-number gradient-text" data-target="85" data-suffix="%">0</div>
691
- <div class="stat-label">Growth Rate</div>
692
- <div class="stat-desc">Year over year revenue increase</div>
693
- </div>
694
- ```
695
-
696
- ```css
697
- .stat-card {
698
- background: var(--bg-card);
699
- backdrop-filter: blur(12px);
700
- border: 1px solid var(--border);
701
- border-radius: 16px;
702
- padding: 48px 40px;
703
- text-align: center;
704
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
705
- display: flex;
706
- flex-direction: column;
707
- align-items: center;
708
- justify-content: center;
709
- }
710
- .stat-number { font-family: 'Clash Display', sans-serif; font-size: 64px; font-weight: 700; line-height: 1; letter-spacing: -0.03em; margin-bottom: 12px; }
711
- .stat-label { font-size: 15px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 500; margin-bottom: 12px; }
712
- .stat-desc { font-size: 15px; color: var(--text-secondary); line-height: 1.5; opacity: 0.7; }
713
- ```
714
-
715
- Counter animation JS: iterate elements with `data-target`, count from 0 to target on `.visible`.
716
-
717
- <!-- @component:stat-card:end -->
718
-
719
- <!-- @component:quote-block:start -->
720
- #### Quote Block (.quote-block)
721
-
722
- ```html
723
- <div class="quote-deco">&ldquo;</div>
724
- <div class="quote-block">
725
- <blockquote>&ldquo;The quote text goes here.&rdquo;</blockquote>
726
- <cite>Attribution</cite>
727
- </div>
728
- ```
729
-
730
- ```css
731
- .quote-block { display: flex; flex-direction: column; justify-content: center; border-left: 3px solid var(--accent); padding: 24px 32px; background: rgba(34,211,238,0.06); border-radius: 0 8px 8px 0; }
732
- .quote-block blockquote { font-size: 36px; font-style: italic; line-height: 1.5; margin-bottom: 16px; text-shadow: 0 0 30px rgba(34,211,238,0.15); }
733
- .quote-block cite { font-size: 14px; color: var(--accent); letter-spacing: 0.08em; text-transform: uppercase; font-style: normal; }
734
- .quote-deco { position: absolute; font-family: 'Clash Display', sans-serif; font-size: 300px; line-height: 1; color: var(--accent); opacity: 0.06; pointer-events: none; z-index: 0; }
735
- ```
736
-
737
- <!-- @component:quote-block:end -->
738
-
739
- <!-- @component:step-flow:start -->
740
- #### Step Flow (.step-flow)
741
-
742
- Horizontal process with numbered circles and connectors. Alternate `.step`
743
- and `.step-connector` as siblings inside `.step-flow`.
744
-
745
- ```html
746
- <div class="step-flow">
747
- <div class="step">
748
- <div class="step-circle">1</div>
749
- <div class="step-title">Describe</div>
750
- <div class="step-desc">Tell us your topic and audience.</div>
751
- </div>
752
- <div class="step-connector"></div>
753
- <div class="step">
754
- <div class="step-circle">2</div>
755
- <div class="step-title">Generate</div>
756
- <div class="step-desc">AI creates your slides.</div>
757
- </div>
758
- <!-- more steps + connectors as needed -->
759
- </div>
760
- ```
761
-
762
- ```css
763
- .step-flow { display: flex; align-items: flex-start; max-width: 1600px; margin: 0 auto; }
764
- .step { flex: 1; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 16px; }
765
- .step-circle { width: 64px; height: 64px; border-radius: 50%; background: linear-gradient(135deg, var(--accent), var(--accent-2)); color: #fff; font-family: 'Clash Display', sans-serif; font-size: 24px; font-weight: 700; display: flex; align-items: center; justify-content: center; box-shadow: 0 8px 20px -8px rgba(34,211,238,0.5); flex-shrink: 0; }
766
- .step-connector { flex: 0 0 32px; height: 2px; background: var(--border); margin-top: 32px; align-self: flex-start; box-shadow: 0 0 6px rgba(34,211,238,0.1); }
767
- .step-title { font-size: 20px; font-weight: 600; }
768
- .step-desc { font-size: 16px; color: var(--text-secondary); line-height: 1.6; max-width: 200px; }
769
- ```
770
-
771
- <!-- @component:step-flow:end -->
772
-
773
- <!-- @component:evidence-list:start -->
774
- #### Evidence List (.evidence-list)
775
-
776
- Styled bullet list. Use inside `.card`, `.two-col-main`, or any container.
777
-
778
- ```html
779
- <ul class="evidence-list">
780
- <li>First piece of evidence or supporting point</li>
781
- <li>Second supporting point</li>
782
- </ul>
783
- ```
784
-
785
- ```css
786
- .evidence-list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 12px; }
787
- .evidence-list li { padding-left: 18px; position: relative; font-size: 18px; color: var(--text-primary); line-height: 1.5; }
788
- .evidence-list li::before { content: ''; position: absolute; left: 0; top: 0.55em; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }
789
- ```
790
-
791
- <!-- @component:evidence-list:end -->
792
-
793
- <!-- @component:chart-container:start -->
794
- #### Chart Container (.chart-container)
795
-
796
- Wrapper for any ECharts visualization. Can appear on any slide, in any layout.
797
- See §Data Visualization for chart type selection and theme-specific styling.
798
-
799
- ```html
800
- <div class="chart-container" id="chart-{purpose}"
801
- style="width:{w}px; height:{h}px"></div>
802
- ```
803
-
804
- ```css
805
- .chart-container { position: relative; flex-shrink: 0; }
806
- ```
807
-
808
- Common sizing by context:
809
- - Inside a column (`.two-col-main`, `.two-col-aside`): `width:100%; height:320–400px`
810
- - Full-width standalone: `max-width:1400px; height:500px; margin:0 auto`
811
- - Inside a `.card` (sparkline/mini): `width:100%; height:140–200px`
812
- - Below a stats row: `max-width:1200px; height:300px; margin:24px auto 0`
813
-
814
- JS init pattern (inside `window.addEventListener('load', ...)`):
815
- ```javascript
816
- if (typeof echarts !== 'undefined') {
817
- const el = document.getElementById('chart-{purpose}');
818
- if (el) {
819
- const chart = echarts.init(el, null, { renderer: 'canvas' });
820
- chart.setOption({ /* see §Data Visualization for theme options */ });
821
- }
822
- }
823
- ```
824
-
825
- <!-- @component:chart-container:end -->
826
-
827
- <!-- @component:text-helpers:start -->
828
- #### Text Helpers
829
-
830
- ```css
831
- h1 { font-family: 'Clash Display', sans-serif; font-size: 80px; font-weight: 700; line-height: 1.1; letter-spacing: -0.02em; text-shadow: 0 0 40px rgba(34,211,238,0.3); }
832
- h2 { font-family: 'Clash Display', sans-serif; font-size: 38px; font-weight: 600; line-height: 1.2; }
833
- .label { font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); font-weight: 500; }
834
- .subtitle { font-size: 24px; color: var(--text-secondary); line-height: 1.6; font-weight: 400; }
835
- .body-text { font-size: 18px; color: var(--text-secondary); line-height: 1.6; }
836
- .gradient-text { background: linear-gradient(135deg, var(--accent), var(--accent-2)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
837
- ```
838
-
839
- Use `.gradient-text` on 1–3 key words in a heading — never entire sentences. Max one per slide.
840
-
841
- <!-- @component:text-helpers:end -->
842
-
843
- <!-- @component:accent-lines:start -->
844
- #### Accent Lines
845
-
846
- ```css
847
- .accent-line { width: 48px; height: 3px; background: linear-gradient(90deg, var(--accent), var(--accent-2)); border-radius: 2px; margin: 20px 0; }
848
- .accent-line-wide { width: 200px; height: 2px; background: linear-gradient(90deg, var(--accent), transparent); border-radius: 2px; }
849
- ```
850
-
851
- - `.accent-line` (short, gradient): decorative — place after headings to anchor the eye
852
- - `.accent-line-wide` (long, fade-out): decorative — sparse slide bottoms
853
-
854
- Use plain CSS `border-bottom` or `<hr>` for structural separation — not accent lines.
855
-
856
- <!-- @component:accent-lines:end -->
857
-
858
- <!-- @component:icons:start -->
859
- #### Icons (Lucide)
860
-
861
- Load via CDN: `<script src="https://cdn.jsdelivr.net/npm/lucide@latest/dist/umd/lucide.js"></script>`
862
- Use `<i data-lucide="icon-name" class="card-icon"></i>` and call `lucide.createIcons()` in JS.
863
-
864
- - Icon color: `var(--accent)`, size: `2rem`, hover: `scale(1.15)` transition
865
- - Choose abstractly: `sparkles` → innovation, `shield` → security, `zap` → performance,
866
- `layers` → architecture, `globe` → global, `bar-chart` → data
867
- - Cards benefit most from icons. Stats and quotes: icons optional.
868
-
869
- <!-- @component:icons:end -->
870
-
871
- <!-- @component:deco-fills:start -->
872
- #### Decorative Fills (.deco-blob, .deco-line)
873
-
874
- Positioned-absolute background elements behind content.
875
-
876
- ```css
877
- .deco-blob { position: absolute; border-radius: 50%; filter: blur(60px); pointer-events: none; z-index: 0; }
878
- .deco-line { position: absolute; pointer-events: none; z-index: 0; }
879
-
880
- /* Ensure content stacks above decorative fills */
881
- .slide-canvas > *:not(.deco-blob):not(.deco-line) { position: relative; z-index: 1; }
882
- ```
883
-
884
- Set size, color, opacity, and position via inline styles:
885
- - Typical `.deco-blob`: `width:300–500px; height:same; background:radial-gradient(circle, var(--accent) 0%, transparent 70%); opacity:0.06–0.10`
886
- - Typical `.deco-line`: `width:120–200px; height:2px; background:linear-gradient(90deg, var(--accent-2), transparent); opacity:0.3–0.5`
887
- - Sparse slides (cover, quote, closing): 2–3 deco elements
888
- - Dense slides (grids, multi-column): 0–1 deco elements
889
- - Never exceed 3 per slide
890
-
891
- <!-- @component:deco-fills:end -->
892
-
893
- <!-- @section:components:end -->
894
-
895
- <!-- @section:layouts:start -->
896
- ### Layout Primitives
897
-
898
- Components can be placed in any of these layout arrangements.
899
- Mix layouts and components freely — these are tools, not templates.
900
-
901
- #### Centered Stack
902
-
903
- `.slide-canvas` default behavior — `flex-direction: column; justify-content: center`.
904
- Use for: cover, closing, quote-focused, single-statement slides.
905
-
906
- #### Top-Aligned Stack
907
-
908
- Override `.slide-canvas` with `style="justify-content: flex-start; padding-top: 80px"`.
909
- Use for: content-heavy slides where vertical space matters.
910
-
911
- #### Two-Column Grid (.two-col)
912
-
913
- ```html
914
- <div class="two-col">
915
- <div class="two-col-main"><!-- primary content --></div>
916
- <div class="two-col-aside"><!-- secondary content --></div>
917
- </div>
918
- ```
919
-
920
- ```css
921
- .two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: stretch; max-width: 1600px; margin: 0 auto; flex: 1; }
922
- .two-col-main { display: flex; flex-direction: column; justify-content: center; }
923
- .two-col-main h2 { font-size: 36px; margin-bottom: 16px; }
924
- .two-col-main p { font-size: 18px; color: var(--text-secondary); line-height: 1.7; }
925
- .two-col-aside { display: flex; flex-direction: column; justify-content: center; }
926
- .two-col-aside .card { flex: 1; }
927
- ```
928
-
929
- Either side can contain any components — cards, charts, text, evidence lists, stat cards.
930
-
931
- #### Three-Column Grid
932
-
933
- ```css
934
- .card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; max-width: 1600px; margin: 0 auto; flex: 1; align-content: stretch; }
935
- .stats-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; max-width: 1600px; margin: 0 auto; }
936
- ```
937
-
938
- Use `.card-grid` for cards, `.stats-row` for stat cards, or create a custom grid.
939
- For 2 items: `repeat(2, 1fr)`. For 4: `repeat(2, 1fr)` (2×2 grid).
940
- The grid container can hold any mix of components.
941
-
942
- #### Horizontal Flow
943
-
944
- Used by `.step-flow` — `display: flex; align-items: flex-start; max-width: 1600px`.
945
- Also works for timelines, comparison strips, or any horizontal sequence.
946
-
947
- <!-- @section:layouts:end -->
948
-
949
- <!-- @section:charts:start -->
950
- ### Data Visualization (ECharts)
951
-
952
- When a slide includes charts or data visualization, use [ECharts](https://echarts.apache.org/)
953
- loaded via CDN:
954
-
955
- ```html
956
- <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
957
- ```
958
-
959
- #### Chart Type Selection
960
-
961
- Choose the chart type based on the data, not by habit. Different data patterns
962
- demand different visualizations:
963
-
964
- | Data Pattern | Chart Type | Common Placements |
965
- |---|---|---|
966
- | Proportions / composition (parts of a whole) | Pie / Donut | Any layout — pair with narrative or standalone |
967
- | Trends over time (growth, decline, cycles) | Line or Area | Full-width for detail, two-col for trend + commentary |
968
- | Category comparisons (A vs B vs C) | Vertical Bar | Full-width or two-col |
969
- | Rankings / sorted magnitudes | Horizontal Bar | Full-width (labels need room) |
970
- | Distribution / histogram | Vertical Bar (binned) | Full-width |
971
- | KPIs with sparkline context | Stats Row + small Line chart below | Custom composite |
972
-
973
- Layout is not fixed — pick the layout that serves the narrative. A chart can
974
- occupy one column of Two-Column, span full-width on its own slide, or sit
975
- inside a Feature Card as a small sparkline. Let the data and story decide.
976
-
977
- #### Shared Aurora chart styles
978
-
979
- All chart types share these aurora theme defaults:
980
-
981
- - **Color palette**: `['#22d3ee', '#a78bfa', '#34d399']` (aurora accent triad).
982
- For >3 series, extend with `#f472b6` (pink) and `#fbbf24` (amber).
983
- - **Background**: `'transparent'`
984
- - **Axis labels / legend text**: `var(--text-secondary)` (`#94a3b8`), `14px` Satoshi font
985
- - **Grid lines**: `var(--surface-2)` (`rgba(148,163,184,0.08)`) — barely visible
986
- - **Animation**: enabled, `800ms`, `cubicOut` (consistent with aurora's motion philosophy)
987
- - **Tooltip**: dark background (`var(--bg-card)`), `var(--text-primary)` text, subtle border
988
-
989
- #### Pie / Donut
990
-
991
- - Inner radius `55-65%` for donut; `0` for full pie
992
- - `borderRadius: 6`, `borderColor: var(--bg-primary)`, `borderWidth: 3` for segment gaps
993
- - Center label: large number/text in `var(--text-primary)`, Clash Display font
994
- - Legend: bottom-aligned, `itemWidth: 12`, `itemGap: 20`
995
- - Container: `280–360px` square is typical
996
-
997
- #### Bar (vertical & horizontal)
998
-
999
- - `borderRadius: [4, 4, 0, 0]` (rounded top caps for vertical; `[0, 4, 4, 0]` for horizontal)
1000
- - Bar width: `40-60%` of category gap — never touch adjacent bars
1001
- - Optional gradient fill: `linearGradient` from accent color at 80% opacity to 40% opacity
1002
- - For ≤5 categories: one color per bar from the aurora triad. For single-series: solid `var(--accent)`
1003
- - Axis line: `1px` `var(--surface-2)`. Tick marks: hidden
1004
-
1005
- #### Line / Area
1006
-
1007
- - Line width: `2-3px`, smooth curves (`smooth: true`)
1008
- - Optional glow: `shadowBlur: 8`, `shadowColor` matching line color at 40% opacity
1009
- - Area fill: `linearGradient` from line color at 20% opacity (top) to transparent (bottom)
1010
- - Data points: show on hover only (`symbol: 'none'`, `emphasis: { symbol: 'circle' }`)
1011
- - For multiple series: one color per series from aurora triad, distinguish with solid vs dashed
1012
-
1013
- #### Integration rules
1014
-
1015
- - Initialize charts inside a `window.addEventListener('load', ...)` or after DOM ready
1016
- - Use `echarts.init(container, null, { renderer: 'canvas' })` — canvas renderer for performance
1017
- - Charts must use the aurora color palette — never default ECharts colors
1018
- - Responsive: charts are inside the 1920×1080 canvas, scaled by JS `transform: scale()` —
1019
- no need for ECharts `resize()` handling
1020
-
1021
- <!-- @section:charts:end -->
1022
-
1023
- <!-- @section:guide:start -->
1024
- ### Composition Guide
1025
-
1026
- #### Common Recipes
1027
-
1028
- These are starting points — not constraints. Combine any components with any
1029
- layout primitive as the content demands.
1030
-
1031
- | Content Pattern | Suggested Recipe | Aurora Notes |
1032
- |---|---|---|
1033
- | 3–4 parallel features | 3-col grid + card ×3 | Each card: Lucide icon + label + title + body |
1034
- | Key metrics (2–4 KPIs) | 3-col grid + stat-card ×3 | Counter animation, `.gradient-text` on numbers |
1035
- | Narrative + evidence | two-col + text in main, card with evidence-list in aside | Glassmorphism evidence card |
1036
- | Sequential process (3–5 steps) | horizontal flow + step-flow | Gradient circles, glowing connectors |
1037
- | Memorable quote | centered stack + quote-block + quote-deco | `border-left: 3px`, text glow |
1038
- | Single powerful statement / CTA | centered stack + large heading + deco fills | `.gradient-text`. Max once per deck. |
1039
- | Data visualization | any layout + chart-container | Chart type per data — see §Data Visualization |
1040
- | KPIs with trend context | 3-col grid + stat-cards, then chart below | Headline numbers + supporting chart |
1041
- | Team / people (3–4) | 3-col grid + card ×3 (no icons) | card-title → name, card-body → role |
1042
- | Before vs After | two-col + content per side | Heading + evidence-list each column |
1043
- | 6+ items on one topic | Split across 2 slides | Max 5 items per slide |
1044
-
1045
- #### Element Usage Rules
1046
-
1047
- **Gradient-text:** Apply to 1–3 key words in a heading — never entire sentences.
1048
- Typical: key metric (`$4.2B`), core concept (`actually impress`), CTA (`Get Started`).
1049
- Max one `.gradient-text` per slide.
1050
-
1051
- **Accent lines:** `.accent-line` (short, after headings) and `.accent-line-wide`
1052
- (long, bottom of sparse slides) are decorative. Use plain `border-bottom` or
1053
- `<hr>` for structural separation.
1054
-
1055
- **Icons (Lucide):** Choose abstractly: `sparkles` → innovation, `shield` → security,
1056
- `zap` → performance, `layers` → architecture, `globe` → global, `bar-chart` → data.
1057
- Cards benefit most from icons. Stats and quotes: icons optional.
1058
- When unsure, omit — a strong heading beats a generic icon.
1059
-
1060
- **Card labels:** Short category words (`Visual`, `Motion`) for thematic grouping.
1061
- Sequential numbers (`01`, `02`, `03`) for ordered items. Omit when the title is clear.
1062
-
1063
- **Decorative fills:** Sparse slides: 2–3 deco elements. Dense slides: 0–1. Never >3.
1064
-
1065
- #### Common Mistakes
1066
-
1067
- - Using stat cards for non-numeric content → use cards instead.
1068
- - Using bullet lists when cards or step-flow would be clearer.
1069
- - Putting a chart AND stat cards on the same slide without clear hierarchy → pick a primary.
1070
- - Always using donut charts for data → match chart type to data pattern (see §Data Visualization).
1071
- - Applying `.gradient-text` to entire sentences → limit to 1–3 key words.
1072
- - Adding Lucide icons to every element → reserve for cards and key callouts.
1073
- - Using the single-statement/CTA layout more than once per deck → it loses impact.
1074
- - Leaving more than ~20% of canvas visually empty → add deco fills or expand content.
1075
-
1076
- ### Code Blocks (if any)
1077
-
1078
- ```css
1079
- pre, code {
1080
- background: rgba(0, 0, 0, 0.4);
1081
- border: 1px solid var(--border);
1082
- border-radius: 8px;
1083
- font-family: 'JetBrains Mono', 'Fira Code', monospace;
1084
- font-size: 14px;
1085
- color: var(--accent);
1086
- }
1087
- ```
1088
-
1089
- ### Do & Don't
1090
-
1091
- - **Do** use the layered aurora background — it creates depth and atmosphere
1092
- - **Do** use glassmorphism cards with `backdrop-filter`
1093
- - **Do** keep accent colors to cyan/violet/emerald — stay in the aurora palette
1094
- - **Do** add subtle glow effects to titles and key elements
1095
- - **Don't** use bright white or pure black backgrounds
1096
- - **Don't** use more than 3 accent colors on a single slide
1097
- - **Don't** clutter slides — max 5 bullet points per slide
1098
- - **Don't** disable `prefers-reduced-motion` — provide smoother alternatives
1099
-
1100
- <!-- @section:guide:end -->