@deckio/deck-engine 1.7.4

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.
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: deck-validate-project
3
+ description: Validate and audit a deck project for correctness. Use this when asked to validate, audit, polish, review, check, or verify slides.
4
+ ---
5
+
6
+ # Validate & Audit a Deck Project
7
+
8
+ ## Step 1: Audit deck.config.js
9
+
10
+ Open `deck.config.js` and verify:
11
+
12
+ ### 1a. All imports resolve
13
+
14
+ For each slide import at the top of the file, verify the target file exists in `src/slides/`.
15
+
16
+ ### 1b. slides array matches imports
17
+
18
+ - Every imported slide should appear in the `slides` array.
19
+ - No unused imports (imported but not in the array).
20
+ - No undefined entries in the array (in array but not imported).
21
+
22
+ ---
23
+
24
+ ## Step 2: Verify slide structure
25
+
26
+ For each slide `.jsx` file in `src/slides/`, verify:
27
+
28
+ - [ ] Imports `{ Slide }` and `{ BottomBar }` from `'@deckio/deck-engine'`
29
+ - [ ] Wrapped in `<Slide index={index} className={styles.xxx}>` (accepts `index` as prop)
30
+ - [ ] Contains `<div className="accent-bar" />` as first child
31
+ - [ ] Contains at least one decorative orb
32
+ - [ ] Content is inside `<div className="content-frame content-gutter">`
33
+ - [ ] `<BottomBar />` is the **last child** inside `<Slide>`
34
+ - [ ] `BottomBar text` is consistent across all slides in the project
35
+
36
+ For each `.module.css` file, verify the root class has:
37
+ - [ ] `background: var(--bg-deep)`
38
+ - [ ] `flex-direction: column`
39
+ - [ ] `padding: 0 0 44px 0`
40
+
41
+ ---
42
+
43
+ ## Step 3: Check companion files
44
+
45
+ - Every `.jsx` slide in `src/slides/` should have a matching `.module.css` file
46
+ - No orphaned `.module.css` files without a matching `.jsx`
47
+
48
+ ---
49
+
50
+ ## Step 4: Verify metadata
51
+
52
+ Check `deck.config.js` exports these fields:
53
+ - [ ] `id` — string, matches the project folder name convention
54
+ - [ ] `title` — display name
55
+ - [ ] `subtitle` — tagline
56
+ - [ ] `icon` — emoji
57
+ - [ ] `accent` — CSS color value
58
+ - [ ] `slides` — non-empty array
59
+
60
+ ---
61
+
62
+ ## Step 5: Report results
63
+
64
+ Summarize findings:
65
+
66
+ - Number of slides validated
67
+ - Any issues found and fixed (missing files, broken imports, structural issues)
68
+ - Overall project health: **pass** or **issues found**
69
+
70
+ ---
71
+
72
+ ## Quick checklist
73
+
74
+ - [ ] All imports in `deck.config.js` resolve to existing files
75
+ - [ ] `slides` array matches imports (no unused, no missing)
76
+ - [ ] Every `.jsx` slide has a companion `.module.css`
77
+ - [ ] All slides have accent-bar, content-frame, BottomBar
78
+ - [ ] BottomBar text is consistent across the project
79
+ - [ ] CSS root classes have required properties
80
+ - [ ] Project metadata (id, title, subtitle, icon, accent) is present
@@ -0,0 +1,31 @@
1
+ import Slide from '../components/Slide.jsx'
2
+ import BottomBar from '../components/BottomBar.jsx'
3
+
4
+ export default function GenericThankYouSlide({ index = 10, subtitle, tagline, footerText }) {
5
+ return (
6
+ <Slide index={index} className="deck-ty">
7
+ <div className="accent-bar" />
8
+
9
+ <div className="deck-ty-glow deck-ty-glow1" />
10
+ <div className="deck-ty-glow deck-ty-glow2" />
11
+ <div className="deck-ty-glow deck-ty-glow3" />
12
+
13
+ {[1, 2, 3, 4, 5, 6, 7, 8].map(i => (
14
+ <div key={i} className={`deck-ty-streak deck-ty-streak${i}`} />
15
+ ))}
16
+
17
+ <div className="content-frame content-gutter">
18
+ <div className="deck-ty-content">
19
+ <h2 className="deck-ty-title">Thank You</h2>
20
+ <p className="deck-ty-subtitle">
21
+ {subtitle || <>Let&rsquo;s build something great &mdash; together.</>}
22
+ </p>
23
+ <div className="deck-ty-divider" />
24
+ {tagline && <p className="deck-ty-tagline">{tagline}</p>}
25
+ </div>
26
+ </div>
27
+
28
+ <BottomBar text={footerText} />
29
+ </Slide>
30
+ )
31
+ }
@@ -0,0 +1,131 @@
1
+ .thankYou {
2
+ background: var(--bg-deep);
3
+ flex-direction: column;
4
+ align-items: stretch;
5
+ justify-content: center;
6
+ overflow: hidden;
7
+ position: relative;
8
+ }
9
+
10
+ /* ── Ambient glow orbs ── */
11
+ .glow {
12
+ position: absolute;
13
+ border-radius: 50%;
14
+ filter: blur(80px);
15
+ pointer-events: none;
16
+ animation: tyPulse 6s ease-in-out infinite;
17
+ }
18
+ .glow1 { width: 300px; height: 300px; background: rgba(88,166,255,0.10); top: -80px; left: -60px; }
19
+ .glow2 { width: 250px; height: 250px; background: rgba(188,140,255,0.10); bottom: -40px; right: -40px; animation-delay: -2s; }
20
+ .glow3 { width: 200px; height: 200px; background: rgba(86,212,221,0.08); top: 50%; left: 60%; transform: translate(-50%,-50%); animation-delay: -4s; }
21
+
22
+ @keyframes tyPulse {
23
+ 0%, 100% { transform: scale(1); opacity: 0.7; }
24
+ 50% { transform: scale(1.15); opacity: 1; }
25
+ }
26
+
27
+ /* ── Speed streaks ── */
28
+ .streak {
29
+ position: absolute;
30
+ height: 1px;
31
+ border-radius: 1px;
32
+ opacity: 0;
33
+ animation: streakMove 4s ease-in-out infinite;
34
+ }
35
+ .streak1 { width: 120px; top: 15%; left: -120px; background: linear-gradient(90deg, transparent, var(--accent)); animation-delay: 0s; }
36
+ .streak2 { width: 80px; top: 30%; left: -80px; background: linear-gradient(90deg, transparent, var(--purple)); animation-delay: 0.6s; }
37
+ .streak3 { width: 100px; top: 45%; left: -100px; background: linear-gradient(90deg, transparent, var(--cyan)); animation-delay: 1.2s; }
38
+ .streak4 { width: 60px; top: 60%; left: -60px; background: linear-gradient(90deg, transparent, var(--green)); animation-delay: 1.8s; }
39
+ .streak5 { width: 90px; top: 75%; left: -90px; background: linear-gradient(90deg, transparent, var(--pink)); animation-delay: 2.4s; }
40
+ .streak6 { width: 70px; top: 20%; right: -70px; background: linear-gradient(270deg, transparent, var(--accent)); animation-delay: 0.3s; }
41
+ .streak7 { width: 110px; top: 50%; right: -110px; background: linear-gradient(270deg, transparent, var(--purple)); animation-delay: 1.5s; }
42
+ .streak8 { width: 85px; top: 80%; right: -85px; background: linear-gradient(270deg, transparent, var(--cyan)); animation-delay: 2.1s; }
43
+
44
+ @keyframes streakMove {
45
+ 0% { transform: translateX(0); opacity: 0; }
46
+ 10% { opacity: 0.6; }
47
+ 50% { opacity: 0.3; }
48
+ 100% { transform: translateX(calc(100vw + 200px)); opacity: 0; }
49
+ }
50
+
51
+ /* ── Logos ── */
52
+ .logos {
53
+ display: flex;
54
+ align-items: center;
55
+ justify-content: flex-start;
56
+ gap: 24px;
57
+ margin-bottom: 40px;
58
+ position: relative;
59
+ z-index: 2;
60
+ }
61
+ .logoGithub {
62
+ width: 80px; height: 80px;
63
+ background: rgba(255,255,255,0.05);
64
+ border: 1px solid rgba(255,255,255,0.1);
65
+ border-radius: 20px;
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: center;
69
+ backdrop-filter: blur(10px);
70
+ }
71
+ .plus {
72
+ font-size: 28px;
73
+ color: var(--text-muted);
74
+ font-weight: 300;
75
+ }
76
+ .logoMs {
77
+ width: 80px; height: 80px;
78
+ background: rgba(255,255,255,0.05);
79
+ border: 1px solid rgba(255,255,255,0.1);
80
+ border-radius: 20px;
81
+ display: flex;
82
+ align-items: center;
83
+ justify-content: center;
84
+ backdrop-filter: blur(10px);
85
+ }
86
+
87
+ /* ── Content ── */
88
+ .content {
89
+ text-align: left;
90
+ position: relative;
91
+ z-index: 2;
92
+ }
93
+ .title {
94
+ font-size: clamp(40px, 6vw, 64px);
95
+ font-weight: 800;
96
+ letter-spacing: -2px;
97
+ background: linear-gradient(135deg, var(--accent), var(--purple), var(--cyan), var(--accent));
98
+ background-size: 300% 300%;
99
+ -webkit-background-clip: text;
100
+ -webkit-text-fill-color: transparent;
101
+ background-clip: text;
102
+ animation: gradShift 6s ease infinite;
103
+ margin-bottom: 16px;
104
+ }
105
+
106
+ @keyframes gradShift {
107
+ 0% { background-position: 0% 50%; }
108
+ 50% { background-position: 100% 50%; }
109
+ 100% { background-position: 0% 50%; }
110
+ }
111
+
112
+ .subtitle {
113
+ font-size: 20px;
114
+ font-weight: 400;
115
+ color: var(--text-muted);
116
+ letter-spacing: 0.5px;
117
+ }
118
+ .divider {
119
+ width: 60px;
120
+ height: 2px;
121
+ background: linear-gradient(90deg, var(--accent), var(--purple));
122
+ margin: 24px auto;
123
+ border-radius: 1px;
124
+ }
125
+ .tagline {
126
+ font-size: 13px;
127
+ text-transform: uppercase;
128
+ letter-spacing: 3px;
129
+ color: var(--text-muted);
130
+ opacity: 0.5;
131
+ }
@@ -0,0 +1,191 @@
1
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap');
2
+
3
+ :root {
4
+ --bg: #0d1117;
5
+ --bg-deep: #080b10;
6
+ --surface: #161b22;
7
+ --border: #30363d;
8
+ --text: #e6edf3;
9
+ --text-muted: #8b949e;
10
+ --accent: #58a6ff;
11
+ --blue-bright: #79c0ff;
12
+ --blue-glow: #1f6feb;
13
+ --purple: #bc8cff;
14
+ --purple-deep: #6e40c9;
15
+ --pink: #f778ba;
16
+ --cyan: #56d4dd;
17
+ --green: #3fb950;
18
+ --orange: #d29922;
19
+ --content-max-width: 1280px;
20
+ --content-gutter: 72px;
21
+ }
22
+
23
+ * { margin: 0; padding: 0; box-sizing: border-box; }
24
+
25
+ html, body, #root {
26
+ width: 100%; height: 100%;
27
+ overflow: hidden;
28
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
29
+ background: var(--bg-deep);
30
+ color: var(--text);
31
+ }
32
+
33
+ /* ── Slide Engine ── */
34
+ .deck {
35
+ width: 100%; height: 100%;
36
+ position: relative;
37
+ }
38
+
39
+ .slide {
40
+ position: absolute;
41
+ inset: 0;
42
+ display: flex;
43
+ opacity: 0;
44
+ pointer-events: none;
45
+ transition: opacity 0.6s cubic-bezier(0.4, 0, 0.2, 1),
46
+ transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
47
+ transform: translateX(60px);
48
+ overflow: hidden;
49
+ }
50
+ .slide.active {
51
+ opacity: 1;
52
+ pointer-events: auto;
53
+ transform: translateX(0);
54
+ }
55
+ .slide.exit-left {
56
+ opacity: 0;
57
+ transform: translateX(-60px);
58
+ }
59
+
60
+ /* ── Shared Decorations ── */
61
+ .orb {
62
+ position: absolute;
63
+ border-radius: 50%;
64
+ filter: blur(2px);
65
+ opacity: 0.7;
66
+ }
67
+ .grid-dots {
68
+ position: absolute;
69
+ width: 200px; height: 200px;
70
+ background-image: radial-gradient(circle, rgba(139,148,158,0.25) 1px, transparent 1px);
71
+ background-size: 18px 18px;
72
+ opacity: 0.5;
73
+ }
74
+
75
+ /* Accent bar left */
76
+ .accent-bar {
77
+ position: absolute;
78
+ left: 48px; top: 15%; bottom: 15%;
79
+ width: 4px;
80
+ border-radius: 2px;
81
+ background: linear-gradient(to bottom, var(--purple), var(--accent), var(--cyan));
82
+ }
83
+
84
+ /* ── Shared Layout ── */
85
+ .content-frame {
86
+ width: min(100%, var(--content-max-width));
87
+ margin-left: auto;
88
+ margin-right: auto;
89
+ }
90
+
91
+ .content-gutter {
92
+ padding-left: var(--content-gutter);
93
+ padding-right: var(--content-gutter);
94
+ }
95
+
96
+ /* ══════════════════════════════════════════════════
97
+ Generic Thank-You Slide (deck-ty-* namespace)
98
+ ══════════════════════════════════════════════════ */
99
+ .deck-ty {
100
+ background: var(--bg-deep);
101
+ flex-direction: column;
102
+ align-items: stretch;
103
+ justify-content: center;
104
+ padding: 0 0 44px 0;
105
+ overflow: hidden;
106
+ }
107
+
108
+ /* Ambient glow orbs */
109
+ .deck-ty-glow {
110
+ position: absolute;
111
+ border-radius: 50%;
112
+ filter: blur(80px);
113
+ pointer-events: none;
114
+ animation: deck-ty-pulse 6s ease-in-out infinite;
115
+ }
116
+ .deck-ty-glow1 { width: 300px; height: 300px; background: rgba(88,166,255,0.10); top: -80px; left: -60px; }
117
+ .deck-ty-glow2 { width: 250px; height: 250px; background: rgba(188,140,255,0.10); bottom: -40px; right: -40px; animation-delay: -2s; }
118
+ .deck-ty-glow3 { width: 200px; height: 200px; background: rgba(86,212,221,0.08); top: 50%; left: 60%; transform: translate(-50%,-50%); animation-delay: -4s; }
119
+
120
+ @keyframes deck-ty-pulse {
121
+ 0%, 100% { transform: scale(1); opacity: 0.7; }
122
+ 50% { transform: scale(1.15); opacity: 1; }
123
+ }
124
+
125
+ /* Speed streaks */
126
+ .deck-ty-streak {
127
+ position: absolute;
128
+ height: 1px;
129
+ border-radius: 1px;
130
+ opacity: 0;
131
+ animation: deck-ty-streak-move 4s ease-in-out infinite;
132
+ }
133
+ .deck-ty-streak1 { width: 120px; top: 15%; left: -120px; background: linear-gradient(90deg, transparent, var(--accent)); animation-delay: 0s; }
134
+ .deck-ty-streak2 { width: 80px; top: 30%; left: -80px; background: linear-gradient(90deg, transparent, var(--purple)); animation-delay: 0.6s; }
135
+ .deck-ty-streak3 { width: 100px; top: 45%; left: -100px; background: linear-gradient(90deg, transparent, var(--cyan)); animation-delay: 1.2s; }
136
+ .deck-ty-streak4 { width: 60px; top: 60%; left: -60px; background: linear-gradient(90deg, transparent, var(--green)); animation-delay: 1.8s; }
137
+ .deck-ty-streak5 { width: 90px; top: 75%; left: -90px; background: linear-gradient(90deg, transparent, var(--pink)); animation-delay: 2.4s; }
138
+ .deck-ty-streak6 { width: 70px; top: 20%; right: -70px; background: linear-gradient(270deg, transparent, var(--accent)); animation-delay: 0.3s; }
139
+ .deck-ty-streak7 { width: 110px; top: 50%; right: -110px; background: linear-gradient(270deg, transparent, var(--purple)); animation-delay: 1.5s; }
140
+ .deck-ty-streak8 { width: 85px; top: 80%; right: -85px; background: linear-gradient(270deg, transparent, var(--cyan)); animation-delay: 2.1s; }
141
+
142
+ @keyframes deck-ty-streak-move {
143
+ 0% { transform: translateX(0); opacity: 0; }
144
+ 10% { opacity: 0.6; }
145
+ 50% { opacity: 0.3; }
146
+ 100% { transform: translateX(calc(100vw + 200px)); opacity: 0; }
147
+ }
148
+
149
+ /* Content */
150
+ .deck-ty-content {
151
+ text-align: left;
152
+ position: relative;
153
+ z-index: 2;
154
+ }
155
+ .deck-ty-title {
156
+ font-size: clamp(40px, 6vw, 64px);
157
+ font-weight: 800;
158
+ letter-spacing: -2px;
159
+ background: linear-gradient(135deg, var(--accent), var(--purple), var(--cyan), var(--accent));
160
+ background-size: 300% 300%;
161
+ -webkit-background-clip: text;
162
+ -webkit-text-fill-color: transparent;
163
+ background-clip: text;
164
+ animation: deck-ty-grad-shift 6s ease infinite;
165
+ margin-bottom: 16px;
166
+ }
167
+ @keyframes deck-ty-grad-shift {
168
+ 0% { background-position: 0% 50%; }
169
+ 50% { background-position: 100% 50%; }
170
+ 100% { background-position: 0% 50%; }
171
+ }
172
+ .deck-ty-subtitle {
173
+ font-size: 20px;
174
+ font-weight: 400;
175
+ color: var(--text-muted);
176
+ letter-spacing: 0.5px;
177
+ }
178
+ .deck-ty-divider {
179
+ width: 60px;
180
+ height: 2px;
181
+ background: linear-gradient(90deg, var(--accent), var(--purple));
182
+ margin: 24px 0;
183
+ border-radius: 1px;
184
+ }
185
+ .deck-ty-tagline {
186
+ font-size: 13px;
187
+ text-transform: uppercase;
188
+ letter-spacing: 3px;
189
+ color: var(--text-muted);
190
+ opacity: 0.5;
191
+ }
package/vite.js ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Vite plugin for deck-engine projects.
3
+ *
4
+ * The main entry (@deckio/deck-engine) is pre-bundled by Vite
5
+ * into a single module so SlideContext, SlideProvider, useSlides, Slide,
6
+ * Navigation, and BottomBar all share one React context instance.
7
+ *
8
+ * Sub-path exports (e.g. slides/GenericThankYouSlide) are served as raw
9
+ * source and import from the package name (not relative paths) so they
10
+ * also resolve to the pre-bundled context singleton.
11
+ */
12
+ export function deckPlugin() {
13
+ return {
14
+ name: 'deck-engine',
15
+ enforce: 'pre',
16
+ config() {
17
+ return {
18
+ resolve: {
19
+ dedupe: ['react', 'react-dom'],
20
+ },
21
+ }
22
+ },
23
+ }
24
+ }
25
+
26
+ export default deckPlugin