-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
2268 lines (2089 loc) · 175 KB
/
Copy pathindex.html
File metadata and controls
2268 lines (2089 loc) · 175 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Frontend Slides: Under the Hood</title>
<!-- Google Fonts: Bricolage Grotesque · DM Sans · JetBrains Mono -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,400;12..96,600;12..96,700;12..96,800&family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400;1,9..40,500&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="styles.css">
<!--
CUSTOMIZE PER COURSE — change only the three accent variables below.
Options:
vermillion #D94F30 / #C4432A / #FDEEE9 / #E8836C (default)
coral #E06B56 / #C85A47 / #FDECEA / #E89585
teal #2A7B9B / #1F6280 / #E4F2F7 / #5A9DB8
amber #D4A843 / #BF9530 / #FDF5E0 / #E0C070
forest #2D8B55 / #226B41 / #E8F5EE / #5AAD7A
-->
<style>
:root {
--color-accent: #D94F30;
--color-accent-hover: #C4432A;
--color-accent-light: #FDEEE9;
--color-accent-muted: #E8836C;
}
</style>
<script src="main.js" defer></script>
</head>
<body>
<nav class="nav" id="nav">
<div class="progress-bar" id="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
<div class="nav-inner">
<a class="nav-title" href="../" style="text-decoration: none;">← Code Course Atlas</a>
<div class="nav-dots" id="nav-dots" role="tablist">
<button class="nav-dot" data-target="module-1" data-tooltip="The User Journey" role="tab" aria-label="Module 1: The User Journey"></button>
<button class="nav-dot" data-target="module-2" data-tooltip="Meet the Cast" role="tab" aria-label="Module 2: Meet the Cast"></button>
<button class="nav-dot" data-target="module-3" data-tooltip="Progressive Disclosure" role="tab" aria-label="Module 3: Progressive Disclosure"></button>
<button class="nav-dot" data-target="module-4" data-tooltip="The Fixed Stage" role="tab" aria-label="Module 4: The Fixed Stage"></button>
<button class="nav-dot" data-target="module-5" data-tooltip="Show, Don't Tell" role="tab" aria-label="Module 5: Show, Don't Tell"></button>
<button class="nav-dot" data-target="module-6" data-tooltip="When It Breaks" role="tab" aria-label="Module 6: When It Breaks"></button>
</div>
<a class="language-switch" href="../frontend-slides-course-zh/index.html">中文</a>
</div>
</nav>
<main id="main">
<!-- modules/*.html content is assembled here by build.sh -->
<section class="module" id="module-1" style="background: var(--color-bg-warm)">
<div class="module-content">
<header class="module-header animate-in">
<span class="module-number">01</span>
<h1 class="module-title">The User Journey</h1>
<p class="module-subtitle">From one sentence to a polished deck — the six-phase production line the AI follows.</p>
</header>
<div class="module-body">
<!-- SCREEN 1: The hook + the reframe -->
<section class="screen animate-in">
<h2 class="screen-heading">Type one sentence. Get a presentation.</h2>
<p class="text-lg">You type <em>make me a pitch deck for my AI startup</em> and minutes later a polished, animated <span class="term" data-definition="HTML (HyperText Markup Language) is the skeleton of every web page — it defines the structure: headings, paragraphs, images, buttons. Every site you visit starts as HTML.">HTML</span> presentation opens in your browser. Here is the production line that just ran.</p>
<div class="flow-steps" style="margin: var(--space-8) 0;">
<div class="flow-step">
<div class="flow-step-num">1</div>
<p>You type one sentence</p>
</div>
<div class="flow-arrow">→</div>
<div class="flow-step">
<div class="flow-step-num">2</div>
<p>AI <span class="term" data-definition="An agent is a conversational AI that can read instructions, write code, and run commands on your behalf — like a junior developer who never sleeps and follows a recipe book.">agent</span> runs the <span class="term" data-definition="A skill is a folder of instructions that teaches an AI agent how to do a specific job — like a recipe book the AI reads and follows step by step. This repo is a skill, not an app.">skill</span></p>
</div>
<div class="flow-arrow">→</div>
<div class="flow-step">
<div class="flow-step-num">3</div>
<p>A live deck opens in your browser</p>
</div>
</div>
<div class="callout callout-accent">
<div class="callout-icon">💡</div>
<div class="callout-content">
<strong class="callout-title">Aha — this is not an app.</strong>
<p>This whole repo is a <em>skill</em>: a set of instructions that teaches an AI agent how to build presentations. The AI agent is the engine; <code>SKILL.md</code> is the recipe it follows. Nothing runs by itself — the agent reads the recipe and does the work.</p>
</div>
</div>
</section>
<!-- SCREEN 2: The 6-phase map -->
<section class="screen animate-in">
<h2 class="screen-heading">The production line at a glance</h2>
<p>The recipe has six <span class="term" data-definition="A phase is a numbered step in the skill workflow — Phase 0, Phase 1, and so on. Each phase has one job and hands off to the next, like stations on an assembly line.">phases</span>. Each does one job and passes the baton.</p>
<div class="step-cards" style="margin-top: var(--space-6);">
<div class="step-card">
<div class="step-num">1</div>
<div class="step-body">
<strong>Detect — Phase 0</strong>
<p>Figure out what the user wants: a new deck, a <span class="term" data-definition="A .pptx file is a Microsoft PowerPoint presentation — the binary format PowerPoint saves to. Converting it means turning each slide into HTML.">.pptx</span> conversion, or an enhancement.</p>
</div>
</div>
<div class="step-card">
<div class="step-num">2</div>
<div class="step-body">
<strong>Content — Phase 1</strong>
<p>Ask four questions at once: purpose, length, content, density.</p>
</div>
</div>
<div class="step-card">
<div class="step-num">3</div>
<div class="step-body">
<strong>Style — Phase 2</strong>
<p>Generate three visual previews. The user picks by looking, not describing.</p>
</div>
</div>
<div class="step-card">
<div class="step-num">4</div>
<div class="step-body">
<strong>Generate — Phase 3</strong>
<p>Write ONE self-contained <code>.html</code> file with all <span class="term" data-definition="CSS (Cascading Style Sheets) is the language that controls how things look — colors, fonts, sizes, layout. If HTML is the skeleton, CSS is the outfit.">CSS</span> and <span class="term" data-definition="JS (JavaScript) is the language that makes things interactive — clicking, animating, responding. If HTML is the skeleton and CSS is the outfit, JS is the muscles.">JS</span> <span class="term" data-definition="Inline means written directly inside the same file, not loaded from elsewhere. Inline CSS/JS lives inside the HTML so there is nothing else to download.">inline</span>.</p>
</div>
</div>
<div class="step-card">
<div class="step-num">5</div>
<div class="step-body">
<strong>Deliver — Phase 5</strong>
<p>Open it in the browser. Tell the user how to navigate and customize.</p>
</div>
</div>
<div class="step-card">
<div class="step-num">6</div>
<div class="step-body">
<strong>Share — Phase 6</strong>
<p>Optional: <span class="term" data-definition="Deploy means to publish your files to a web server so anyone with the URL can view them in their browser — like hanging a painting in a public gallery instead of your studio.">deploy</span> to a URL or export a <span class="term" data-definition="PDF (Portable Document Format) is a fixed-layout file — what you see is exactly what prints. Good for sharing presentations as read-only documents that look identical everywhere.">PDF</span>.</p>
</div>
</div>
</div>
</section>
<!-- SCREEN 3: The hero flow animation -->
<section class="screen animate-in">
<h2 class="screen-heading">Watch the journey, step by step</h2>
<p>Click <em>Next Step</em> to follow a single sentence as it travels through the production line.</p>
<div class="flow-animation" data-steps='[
{"highlight":"flow-actor-1","label":"You type: make me a pitch deck for my AI startup"},
{"highlight":"flow-actor-2","label":"AI figures out: new deck (Mode A)","packet":true,"from":"actor-1","to":"actor-2"},
{"highlight":"flow-actor-3","label":"Asks 4 questions at once: purpose, length, content, density","packet":true,"from":"actor-2","to":"actor-3"},
{"highlight":"flow-actor-4","label":"Generates 3 visual previews to compare","packet":true,"from":"actor-3","to":"actor-4"},
{"highlight":"flow-actor-4","label":"You pick the one you like by looking, not describing"},
{"highlight":"flow-actor-5","label":"Reads the full design recipe for the chosen style","packet":true,"from":"actor-4","to":"actor-5"},
{"highlight":"flow-actor-5","label":"Writes ONE self-contained .html file, all CSS/JS inline"},
{"highlight":"flow-actor-6","label":"Opens it in your browser","packet":true,"from":"actor-5","to":"actor-6"},
{"highlight":"flow-actor-7","label":"Optional: deploy to a URL or export PDF","packet":true,"from":"actor-6","to":"actor-7"}
]'>
<div class="flow-actors">
<div class="flow-actor" id="flow-actor-1">
<div class="flow-actor-icon" style="background: var(--color-actor-1)">U</div>
<span>You</span>
</div>
<div class="flow-actor" id="flow-actor-2">
<div class="flow-actor-icon" style="background: var(--color-actor-2)">0</div>
<span>Detect</span>
</div>
<div class="flow-actor" id="flow-actor-3">
<div class="flow-actor-icon" style="background: var(--color-actor-3)">1</div>
<span>Content</span>
</div>
<div class="flow-actor" id="flow-actor-4">
<div class="flow-actor-icon" style="background: var(--color-actor-4)">2</div>
<span>Style</span>
</div>
<div class="flow-actor" id="flow-actor-5">
<div class="flow-actor-icon" style="background: var(--color-actor-5)">3</div>
<span>Generate</span>
</div>
<div class="flow-actor" id="flow-actor-6">
<div class="flow-actor-icon" style="background: var(--color-actor-2)">5</div>
<span>Deliver</span>
</div>
<div class="flow-actor" id="flow-actor-7">
<div class="flow-actor-icon" style="background: var(--color-actor-3)">6</div>
<span>Share</span>
</div>
</div>
<div class="flow-packet" id="flow-packet"></div>
<div class="flow-step-label" id="flow-label">Click Next Step to begin</div>
<div class="flow-controls">
<button class="btn flow-next-btn">Next Step</button>
<button class="btn flow-reset-btn">Restart</button>
<span class="flow-progress"></span>
</div>
</div>
<div class="callout callout-info" style="margin-top: var(--space-8);">
<div class="callout-icon">🧭</div>
<div class="callout-content">
<strong class="callout-title">Why this matters</strong>
<p>Knowing the phases lets you <em>steer</em> the AI at the right moment (skip style discovery, I want Bold Signal) and <em>diagnose</em> when it gets stuck (it is looping in Phase 2 — it never asked about density).</p>
</div>
</div>
</section>
<!-- SCREEN 4: Phase 0 routing -->
<section class="screen animate-in">
<h2 class="screen-heading">Phase 0 picks a lane</h2>
<p>Before anything else, the AI detects which of three modes you want — and that choice decides where the journey goes next.</p>
<div class="pattern-cards" style="margin-top: var(--space-6);">
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-2)">
<div class="pattern-icon" style="background: var(--color-actor-2)">A</div>
<h4 class="pattern-title">Mode A — New Presentation</h4>
<p class="pattern-desc">Create from scratch. Go to Phase 1 (content questions).</p>
</div>
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-4)">
<div class="pattern-icon" style="background: var(--color-actor-4)">B</div>
<h4 class="pattern-title">Mode B — PPT Conversion</h4>
<p class="pattern-desc">Convert a .pptx file. Jump straight to Phase 4.</p>
</div>
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-5)">
<div class="pattern-icon" style="background: var(--color-actor-5)">C</div>
<h4 class="pattern-title">Mode C — Enhancement</h4>
<p class="pattern-desc">Improve an existing HTML presentation. Read it, understand it, enhance it.</p>
</div>
</div>
<p class="text-sm" style="margin-top: var(--space-4); color: var(--color-text-secondary);">Notice how Mode B skips Phases 1–3 entirely — the content and style already exist inside the PowerPoint.</p>
</section>
<!-- SCREEN 5: Phase 3 — the stage that scales -->
<section class="screen animate-in">
<h2 class="screen-heading">The <span class="term" data-definition="16:9 is the standard widescreen aspect ratio used by TVs, YouTube, and PowerPoint — 16 units wide for every 9 units tall. This skill locks every deck to that shape.">16:9</span> stage trick</h2>
<p>Every deck uses a fixed 1920×1080 canvas that shrinks as a whole to fit your <span class="term" data-definition="The viewport is the visible rectangle of a web page inside your browser window — the area where the page actually shows. Resize the window and the viewport changes.">viewport</span>. Here is the real code that does it.</p>
<div class="translation-block animate-in">
<div class="translation-code">
<span class="translation-label">CODE</span>
<pre><code><span class="code-line"><span class="code-function">setupStageScale</span>() {</span>
<span class="code-line"> <span class="code-keyword">const</span> scale = () <span class="code-operator">=></span> {</span>
<span class="code-line"> <span class="code-keyword">const</span> factor = <span class="code-function">Math.min</span>(window.innerWidth / <span class="code-number">1920</span>, window.innerHeight / <span class="code-number">1080</span>);</span>
<span class="code-line"> <span class="code-keyword">const</span> x = (window.innerWidth - <span class="code-number">1920</span> * factor) / <span class="code-number">2</span>;</span>
<span class="code-line"> <span class="code-keyword">const</span> y = (window.innerHeight - <span class="code-number">1080</span> * factor) / <span class="code-number">2</span>;</span>
<span class="code-line"> <span class="code-keyword">this</span>.stage.style.<span class="code-property">transform</span> = <span class="code-string">`translate(${x}px, ${y}px) scale(${factor})`</span>;</span>
<span class="code-line"> };</span>
<span class="code-line"> <span class="code-function">scale</span>();</span>
<span class="code-line"> window.<span class="code-function">addEventListener</span>(<span class="code-string">'resize'</span>, scale);</span>
<span class="code-line">}</span>
</code></pre>
</div>
<div class="translation-english">
<span class="translation-label">PLAIN ENGLISH</span>
<div class="translation-lines">
<p class="tl">A function that sets up the auto-scaling for the slide stage.</p>
<p class="tl">Define a helper called <code>scale</code> we can call whenever we need to re-fit.</p>
<p class="tl">Pick the smaller of width-fit or height-fit, so the 1920×1080 canvas never overflows.</p>
<p class="tl">Center horizontally — leftover width split evenly left and right (the pillarbox bars).</p>
<p class="tl">Center vertically — leftover height split evenly top and bottom (the letterbox bars).</p>
<p class="tl">Apply it: <span class="term" data-definition="transform is a CSS property that moves, rotates, or resizes an element without changing the elements around it — like lifting a sticker and repositioning it on the page.">transform</span> the stage by x,y then <span class="term" data-definition="scale is a transform value that grows or shrinks an element by a multiplier — scale(0.5) makes it half the size, scale(2) doubles it.">scale</span> it by factor, in one combined move.</p>
<p class="tl">End of the helper.</p>
<p class="tl">Run it once now so the deck fits immediately on load.</p>
<p class="tl">Re-run it every time the window changes size, so the deck always fits.</p>
<p class="tl">End of <code>setupStageScale</code>.</p>
</div>
</div>
</div>
</section>
<!-- SCREEN 6: The five non-negotiables -->
<section class="screen animate-in">
<h2 class="screen-heading">Five rules the AI never breaks</h2>
<p>These principles shape every phase. If the AI starts producing generic output or split files, one of these was violated.</p>
<div class="pattern-cards" style="margin-top: var(--space-6);">
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-1)">
<div class="pattern-icon" style="background: var(--color-actor-1)">1</div>
<h4 class="pattern-title">Zero Dependencies</h4>
<p class="pattern-desc">Single HTML files with inline CSS/JS. No <span class="term" data-definition="npm is a package manager for JavaScript — a tool that downloads third-party code libraries so your project can use them. This skill forbids it: everything is self-contained.">npm</span>, no <span class="term" data-definition="Build tools are programs that process your source code before it ships — bundling files, minifying, converting modern syntax. This project avoids them entirely so the output stays simple.">build tools</span>.</p>
</div>
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-2)">
<div class="pattern-icon" style="background: var(--color-actor-2)">2</div>
<h4 class="pattern-title">Show, Don't Tell</h4>
<p class="pattern-desc">Generate visual previews, not abstract choices. People discover what they want by seeing it.</p>
</div>
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-3)">
<div class="pattern-icon" style="background: var(--color-actor-3)">3</div>
<h4 class="pattern-title">Distinctive Design</h4>
<p class="pattern-desc">No generic AI slop. Every presentation must feel custom-crafted.</p>
</div>
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-4)">
<div class="pattern-icon" style="background: var(--color-actor-4)">4</div>
<h4 class="pattern-title">Progressive Disclosure</h4>
<p class="pattern-desc">Read lightweight style indexes first. Load the full <span class="term" data-definition="design.md is a Markdown file inside each template folder that contains the complete design recipe — colors, fonts, spacing rules — for that one style.">design.md</span> only after the user picks a <span class="term" data-definition="A template is a pre-built style recipe: a folder with a design.md file, fonts, and color rules that the AI uses as a starting point for a deck.">template</span>.</p>
</div>
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-5)">
<div class="pattern-icon" style="background: var(--color-actor-5)">5</div>
<h4 class="pattern-title">Fixed 16:9 Stage</h4>
<p class="pattern-desc">Every deck uses a 1920×1080 canvas scaled as a whole. Slides stay 16:9 on every screen, including phones. Do not reflow content to fit the device.</p>
</div>
</div>
</section>
<!-- SCREEN 7: Phase 5 delivery -->
<section class="screen animate-in">
<h2 class="screen-heading">Delivery: you are in the driver seat</h2>
<p>Phase 5 hands the keys to you. The AI cleans up, opens the file, and tells you how to drive it.</p>
<div class="step-cards" style="margin-top: var(--space-6);">
<div class="step-card">
<div class="step-num">1</div>
<div class="step-body">
<strong>Clean up</strong>
<p>Delete <code>.frontend-slides/slide-previews/</code> if it exists — no leftover scratch files.</p>
</div>
</div>
<div class="step-card">
<div class="step-num">2</div>
<div class="step-body">
<strong>Open</strong>
<p>Run <code>open [filename].html</code> to launch the deck in your browser.</p>
</div>
</div>
<div class="step-card">
<div class="step-num">3</div>
<div class="step-body">
<strong>Summarize</strong>
<p>Tell you the file location, style name, slide count. Explain navigation: arrow keys, space, swipe. Explain customization: <span class="term" data-definition=":root is a CSS selector that targets the top-level element of the page. Variables defined here — like colors and fonts — are available everywhere in the deck.">:root</span> CSS variables for colors, font link for typography, <span class="term" data-definition=".reveal is a CSS class the AI uses to mark elements that should animate in — typically fading or sliding onto the slide when it appears.">.reveal</span> class for animations.</p>
</div>
</div>
</div>
</section>
<!-- SCREEN 8: Quiz -->
<section class="screen animate-in">
<h2 class="screen-heading">Check your steering instincts</h2>
<p>Three scenarios. Pick the answer that shows you know which phase does what.</p>
<div class="quiz-container" id="quiz-module1" style="margin-top: var(--space-6);">
<div class="quiz-question-block"
data-correct="option-c"
data-explanation-right="Exactly — Phase 2 is style discovery. If you already know your style, tell the AI to skip the previews and jump straight to Phase 3 with your chosen template."
data-explanation-wrong="Not quite. Phase 2 is where the AI discovers what style you want by showing you visual previews. If you already know the style, that is the phase to skip or fast-forward.">
<h3 class="quiz-question">You already know exactly which style you want (Bold Signal). Which phase should you tell the AI to skip or fast-forward?</h3>
<div class="quiz-options">
<button class="quiz-option" data-value="option-a" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Phase 0 — Detect</span>
</button>
<button class="quiz-option" data-value="option-b" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Phase 1 — Content</span>
</button>
<button class="quiz-option" data-value="option-c" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Phase 2 — Style</span>
</button>
<button class="quiz-option" data-value="option-d" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Phase 5 — Delivery</span>
</button>
</div>
<div class="quiz-feedback"></div>
</div>
<div class="quiz-question-block"
data-correct="option-a"
data-explanation-right="Correct — Phase 1 must ask all four questions (purpose, length, content, density) at once, not dribble them out one at a time. That is the rule it is violating."
data-explanation-wrong="Not quite. Think about which phase gathers the brief from you. Phase 1 is required to ask all its questions together — one at a time is the exact failure mode the skill is designed to prevent.">
<h3 class="quiz-question">The AI keeps re-asking about colors and fonts one question at a time. Which phase rule is it violating?</h3>
<div class="quiz-options">
<button class="quiz-option" data-value="option-a" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Phase 1 — ask ALL questions together</span>
</button>
<button class="quiz-option" data-value="option-b" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Phase 0 — detect the mode first</span>
</button>
<button class="quiz-option" data-value="option-c" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Phase 3 — generate one HTML file</span>
</button>
<button class="quiz-option" data-value="option-d" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Phase 5 — clean up previews</span>
</button>
</div>
<div class="quiz-feedback"></div>
</div>
<div class="quiz-question-block"
data-correct="option-c"
data-explanation-right="Correct — Phase 0 detects Mode B (PPT conversion) and routes directly to Phase 4, skipping the content and style discovery phases entirely."
data-explanation-wrong="Not quite. When you hand over a .pptx, Phase 0 classifies it as Mode B and jumps to Phase 4 — the conversion phase that turns PowerPoint slides into HTML. The content and style already exist in the file.">
<h3 class="quiz-question">You hand the AI a .pptx file. Which phase does it jump to?</h3>
<div class="quiz-options">
<button class="quiz-option" data-value="option-a" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Phase 1 — Content</span>
</button>
<button class="quiz-option" data-value="option-b" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Phase 2 — Style</span>
</button>
<button class="quiz-option" data-value="option-c" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Phase 4 — Conversion</span>
</button>
<button class="quiz-option" data-value="option-d" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Phase 5 — Delivery</span>
</button>
</div>
<div class="quiz-feedback"></div>
</div>
<button class="quiz-check-btn" onclick="checkQuiz('quiz-module1')">Check Answers</button>
<button class="quiz-reset-btn" onclick="resetQuiz('quiz-module1')">Try Again</button>
</div>
</section>
<!-- SCREEN 9: Transition to Module 2 -->
<section class="screen animate-in">
<h2 class="screen-heading">Meet the cast</h2>
<p>That production line is staffed by a cast of files — each with a specific job. In the next module, we open the studio door and meet them one by one.</p>
<div class="callout callout-info" style="margin-top: var(--space-6);">
<div class="callout-icon">📂</div>
<div class="callout-content">
<strong class="callout-title">Next: Module 2 — Meet the Cast</strong>
<p><code>SKILL.md</code> is the studio manager, but it does not work alone. The repo contains template folders, style indexes, and a <code>design.md</code> for each look. We will trace who reads what, and when.</p>
</div>
</div>
</section>
</div>
</div>
</section>
<section class="module" id="module-2" style="background: var(--color-bg)">
<div class="module-content">
<header class="module-header animate-in">
<span class="module-number">02</span>
<h1 class="module-title">Meet the Cast</h1>
<p class="module-subtitle">The studio manager from Module 1 doesn't work alone. Behind every phase is a specialized file — a department that gets paged only when its expertise is needed.</p>
</header>
<div class="module-body">
<!-- SCREEN 1: Hook + Pattern Cards -->
<section class="screen animate-in">
<h2 class="screen-heading">A Film Crew, Not a Solo Act</h2>
<p>Think of the <span class="term" data-definition="A folder of files that tells an AI agent how to do a specialized job — like a crew manual the AI reads before starting work.">skill repo</span> as a film set. <code>SKILL.md</code> is the <strong>director</strong> who calls every shot. The supporting files are specialized departments — wardrobe, atelier, stage rigging, post-production — each paged onto set at one specific moment.</p>
<p>Knowing which file owns which job lets you tell the AI <em>where</em> to make a change. Here are the five departments:</p>
<div class="pattern-cards">
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-1)">
<div class="pattern-icon" style="background: var(--color-actor-1)">🎬</div>
<h4 class="pattern-title">Director</h4>
<p class="pattern-desc"><code>SKILL.md</code> — calls the shots and follows the shot list. Paged in every <span class="term" data-definition="A numbered step in the production line. The skill breaks deck-building into 6 phases, from brief to sharing.">phase</span>.</p>
</div>
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-4)">
<div class="pattern-icon" style="background: var(--color-actor-4)">👔</div>
<h4 class="pattern-title">Wardrobe</h4>
<p class="pattern-desc"><code>STYLE_PRESETS.md</code> — 12 safe, ready-to-wear looks with colors and fonts. Paged in Phase 2 (style selection).</p>
</div>
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-3)">
<div class="pattern-icon" style="background: var(--color-actor-3)">🎨</div>
<h4 class="pattern-title">Atelier</h4>
<p class="pattern-desc"><code>bold-template-pack/</code> — an <span class="term" data-definition="A French word for an artist's workshop or studio — in fashion, a high-end studio where one-of-a-kind pieces are crafted by hand.">atelier</span> of 34 designer collections. Paged in Phases 2–3.</p>
</div>
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-2)">
<div class="pattern-icon" style="background: var(--color-actor-2)">🎭</div>
<h4 class="pattern-title">Stage Rigger</h4>
<p class="pattern-desc"><code>viewport-base.css</code> — builds the fixed 1920×1080 stage. Paged in Phase 3 (generation), every time.</p>
</div>
<div class="pattern-card" style="border-top: 3px solid var(--color-actor-5)">
<div class="pattern-icon" style="background: var(--color-actor-5)">🎞️</div>
<h4 class="pattern-title">Post-Production</h4>
<p class="pattern-desc"><code>scripts/</code> — extract, export, and <span class="term" data-definition="To publish your project to the internet so others can access it — like moving from a rehearsal room to opening night.">deploy</span>. Paged in Phases 4 & 6 only.</p>
</div>
</div>
</section>
<!-- SCREEN 2: Cast List Table -->
<section class="screen animate-in">
<h2 class="screen-heading">The Cast List</h2>
<p>This table lives inside <code>SKILL.md</code> itself — the director's shot list of who does what, and when they're loaded:</p>
<div class="translation-block animate-in">
<div class="translation-code">
<span class="translation-label">SKILL.md</span>
<pre><code><span class="code-line">| File | Purpose | When to Read |</span>
<span class="code-line">| -------------------------------------------------- | -------------------------------------------------------------------- | ------------------------- |</span>
<span class="code-line">| STYLE_PRESETS.md | 12 curated visual presets with colors, fonts, and signature elements | Phase 2 (style selection) |</span>
<span class="code-line">| bold-template-pack/selection-index.json | Compact bold template metadata for candidate selection | Phase 2 (style selection) |</span>
<span class="code-line">| bold-template-pack/templates/*/preview.md | Lightweight style cards for shortlisted bold title previews | Phase 2 after shortlisting |</span>
<span class="code-line">| bold-template-pack/templates/*/design.md | Detailed design-system docs for the selected bold template only | Phase 3 after user selection |</span>
<span class="code-line">| viewport-base.css | Mandatory fixed-stage CSS — copy into every presentation | Phase 3 (generation) |</span>
<span class="code-line">| html-template.md | HTML structure, JS features, code quality standards | Phase 3 (generation) |</span>
<span class="code-line">| animation-patterns.md | CSS/JS animation snippets and effect-to-feeling guide | Phase 3 (generation) |</span>
<span class="code-line">| scripts/extract-pptx.py | Python script for PPT content extraction | Phase 4 (conversion) |</span>
<span class="code-line">| scripts/deploy.sh | Deploy slides to Vercel for instant sharing | Phase 6 (sharing) |</span>
<span class="code-line">| scripts/export-pdf.sh | Export slides to PDF | Phase 6 (sharing) |</span></code></pre>
</div>
<div class="translation-english">
<span class="translation-label">READ AS</span>
<div class="translation-lines">
<p class="tl"><strong>Style department</strong> — <code>STYLE_PRESETS.md</code> and the <code>bold-template-pack/</code> chain (index → preview → design) are all read during Phase 2, when the AI is picking a look.</p>
<p class="tl"><strong>Stage & screenplay</strong> — <code>viewport-base.css</code>, <code>html-template.md</code>, and <code>animation-patterns.md</code> are read during Phase 3, when the AI generates the actual slides.</p>
<p class="tl"><strong>Post-production</strong> — the three scripts are read only in Phase 4 (converting a <span class="term" data-definition="The file format Microsoft PowerPoint uses to save presentations. It bundles slides, text, images, and notes into one file.">.pptx</span>) and Phase 6 (sharing). They sit idle otherwise.</p>
<p class="tl">Each file has <strong>one job, loaded at one specific moment</strong>. That's the whole design.</p>
</div>
</div>
</div>
</section>
<!-- SCREEN 3: Group Chat Animation (Hero) -->
<section class="screen animate-in">
<h2 class="screen-heading">The Crew Briefing</h2>
<p>A new deck request just came in. Watch each file introduce itself — in the exact order they get paged onto set:</p>
<div class="chat-window" id="chat-module2">
<div class="chat-messages">
<div class="chat-message" data-msg="0" data-sender="skill" style="display:none">
<div class="chat-avatar" style="background: var(--color-actor-1)">S</div>
<div class="chat-bubble">
<span class="chat-sender" style="color: var(--color-actor-1)">SKILL.md</span>
<p>Alright crew — new deck request just came in. Phase 2 needs style options. Who's up?</p>
</div>
</div>
<div class="chat-message" data-msg="1" data-sender="presets" style="display:none">
<div class="chat-avatar" style="background: var(--color-actor-4)">P</div>
<div class="chat-bubble">
<span class="chat-sender" style="color: var(--color-actor-4)">STYLE_PRESETS.md</span>
<p>I've got 12 safe, tested presets ready to go — Bold Signal, Notebook Tabs, Neon Cyber...</p>
</div>
</div>
<div class="chat-message" data-msg="2" data-sender="index" style="display:none">
<div class="chat-avatar" style="background: var(--color-actor-3)">I</div>
<div class="chat-bubble">
<span class="chat-sender" style="color: var(--color-actor-3)">selection-index.json</span>
<p>Hold on — I'm the index for all 34 bold templates. Read ME first, I'm tiny. I'll tell you each one's mood and formality.</p>
</div>
</div>
<div class="chat-message" data-msg="3" data-sender="preview" style="display:none">
<div class="chat-avatar" style="background: var(--color-actor-2)">V</div>
<div class="chat-bubble">
<span class="chat-sender" style="color: var(--color-actor-2)">preview.md</span>
<p>Once the index shortlists a few, I'm the lightweight preview card. One glance, no commitment.</p>
</div>
</div>
<div class="chat-message" data-msg="4" data-sender="design" style="display:none">
<div class="chat-avatar" style="background: var(--color-actor-5)">D</div>
<div class="chat-bubble">
<span class="chat-sender" style="color: var(--color-actor-5)">design.md</span>
<p>And ONLY after the user picks one template — then I load. I'm the full design recipe. Big, so read me last.</p>
</div>
</div>
<div class="chat-message" data-msg="5" data-sender="viewport" style="display:none">
<div class="chat-avatar" style="background: var(--color-actor-2)">C</div>
<div class="chat-bubble">
<span class="chat-sender" style="color: var(--color-actor-2)">viewport-base.css</span>
<p>Whenever generation starts, I'm mandatory. I build the 1920×1080 stage. Copy me into EVERY deck, in full.</p>
</div>
</div>
<div class="chat-message" data-msg="6" data-sender="skill" style="display:none">
<div class="chat-avatar" style="background: var(--color-actor-1)">S</div>
<div class="chat-bubble">
<span class="chat-sender" style="color: var(--color-actor-1)">SKILL.md</span>
<p>Perfect. scripts/ — stand by for Phase 4 and 6. We don't page you unless there's a .pptx or a share request.</p>
</div>
</div>
</div>
<div class="chat-typing" id="chat-module2-typing" style="display:none">
<div class="chat-avatar" id="chat-module2-typing-avatar">?</div>
<div class="chat-typing-dots">
<span class="typing-dot"></span>
<span class="typing-dot"></span>
<span class="typing-dot"></span>
</div>
</div>
<div class="chat-controls">
<button class="btn chat-next-btn">Next Message</button>
<button class="btn chat-all-btn">Play All</button>
<button class="btn chat-reset-btn">Replay</button>
<span class="chat-progress"></span>
</div>
</div>
<p>Notice the color each file wears. These actor colors stay consistent across the whole course — <span style="color: var(--color-actor-1); font-weight: 600;">SKILL.md is vermillion</span>, <span style="color: var(--color-actor-4); font-weight: 600;">STYLE_PRESETS is golden</span>, <span style="color: var(--color-actor-3); font-weight: 600;">the index is plum</span>, <span style="color: var(--color-actor-2); font-weight: 600;">preview & viewport are teal</span>, <span style="color: var(--color-actor-5); font-weight: 600;">design & scripts are forest</span>.</p>
</section>
<!-- SCREEN 4: Visual File Tree -->
<section class="screen animate-in">
<h2 class="screen-heading">The Repo Layout</h2>
<p>Here's the actual folder structure — each file with its one-line role:</p>
<div class="file-tree">
<div class="ft-file">
<span class="ft-name">SKILL.md</span>
<span class="ft-desc">The director — calls the shots, follows the shot list</span>
</div>
<div class="ft-file">
<span class="ft-name">STYLE_PRESETS.md</span>
<span class="ft-desc">Wardrobe closet — 12 safe, ready-to-wear looks</span>
</div>
<div class="ft-file">
<span class="ft-name">viewport-base.css</span>
<span class="ft-desc">Stage rigger — builds the fixed 16:9 stage</span>
</div>
<div class="ft-file">
<span class="ft-name">html-template.md</span>
<span class="ft-desc">Screenplay format — the <span class="term" data-definition="The language that defines the structure of a webpage — headings, paragraphs, images, links. It's the skeleton every site is built on.">HTML</span> structure every deck follows</span>
</div>
<div class="ft-file">
<span class="ft-name">animation-patterns.md</span>
<span class="ft-desc">Effects library — <span class="term" data-definition="The language that controls how a webpage looks — colors, fonts, sizes, layout. HTML is the structure; CSS is the paint and decoration.">CSS</span>/JS animation snippets</span>
</div>
<div class="ft-folder open">
<span class="ft-name">bold-template-pack/</span>
<span class="ft-desc">High-fashion atelier — 34 designer collections</span>
<div class="ft-children">
<div class="ft-file">
<span class="ft-name">selection-index.json</span>
<span class="ft-desc">The catalog — tiny <span class="term" data-definition="Data that describes other data — like a label on a file folder that tells you what's inside without opening it. A photo's metadata might include the date, camera, and location.">metadata</span> for all 34 templates</span>
</div>
<div class="ft-folder open">
<span class="ft-name">templates/</span>
<span class="ft-desc">Individual template folders</span>
<div class="ft-children">
<div class="ft-folder open">
<span class="ft-name">8-bit-orbit/ (each template)</span>
<span class="ft-desc">One designer collection</span>
<div class="ft-children">
<div class="ft-file">
<span class="ft-name">preview.md</span>
<span class="ft-desc">Lightweight style card — one glance, no commitment</span>
</div>
<div class="ft-file">
<span class="ft-name">design.md</span>
<span class="ft-desc">Full design recipe — loaded LAST, only for the chosen one</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="ft-folder open">
<span class="ft-name">scripts/</span>
<span class="ft-desc">Post-production house — extract, export, deploy</span>
<div class="ft-children">
<div class="ft-file">
<span class="ft-name">extract-pptx.py</span>
<span class="ft-desc">Phase 4 — pull content out of .pptx files</span>
</div>
<div class="ft-file">
<span class="ft-name">deploy.sh</span>
<span class="ft-desc">Phase 6 — deploy to <span class="term" data-definition="A cloud platform that hosts websites and apps — you upload your files, Vercel gives them a public URL anyone can visit.">Vercel</span> for sharing</span>
</div>
<div class="ft-file">
<span class="ft-name">export-pdf.sh</span>
<span class="ft-desc">Phase 6 — export slides to PDF</span>
</div>
</div>
</div>
</div>
</section>
<!-- SCREEN 5: JSON Metadata Card Translation -->
<section class="screen animate-in">
<h2 class="screen-heading">One Template's Metadata Card</h2>
<p>Inside <code>selection-index.json</code>, every one of the 34 templates gets a compact card like this. The AI reads these cards to find candidates — no heavy files loaded yet:</p>
<div class="translation-block animate-in">
<div class="translation-code">
<span class="translation-label">JSON</span>
<pre><code><span class="code-line"><span class="code-operator">{</span></span>
<span class="code-line"> <span class="code-property">"slug"</span>: <span class="code-string">"8-bit-orbit"</span>,</span>
<span class="code-line"> <span class="code-property">"name"</span>: <span class="code-string">"8-Bit Orbit"</span>,</span>
<span class="code-line"> <span class="code-property">"tagline"</span>: <span class="code-string">"Pixel-art neon arcade aesthetic on a deep navy void."</span>,</span>
<span class="code-line"> <span class="code-property">"mood"</span>: <span class="code-operator">[</span><span class="code-string">"retro-tech"</span>, <span class="code-string">"playful"</span>, <span class="code-string">"cyberpunk"</span>, <span class="code-string">"energetic"</span><span class="code-operator">]</span>,</span>
<span class="code-line"> <span class="code-property">"tone"</span>: <span class="code-operator">[</span><span class="code-string">"geeky"</span>, <span class="code-string">"neon"</span>, <span class="code-string">"rebellious"</span>, <span class="code-string">"sci-fi"</span><span class="code-operator">]</span>,</span>
<span class="code-line"> <span class="code-property">"formality"</span>: <span class="code-string">"low"</span>,</span>
<span class="code-line"> <span class="code-property">"density"</span>: <span class="code-string">"medium"</span>,</span>
<span class="code-line"> <span class="code-property">"scheme"</span>: <span class="code-string">"dark"</span>,</span>
<span class="code-line"> <span class="code-property">"best_for"</span>: <span class="code-string">"Anything that should feel like a CRT screen at 2am: cyberpunk, gaming, web3, indie dev tools, hackathon demos..."</span>,</span>
<span class="code-line"> <span class="code-property">"avoid_for"</span>: <span class="code-string">"Contexts where the dark neon palette would actively work against the message — quiet institutional finance disclosures, healthcare patient-facing materials, traditional luxury."</span>,</span>
<span class="code-line"> <span class="code-property">"preview_md"</span>: <span class="code-string">"bold-template-pack/templates/8-bit-orbit/preview.md"</span>,</span>
<span class="code-line"> <span class="code-property">"design_md"</span>: <span class="code-string">"bold-template-pack/templates/8-bit-orbit/design.md"</span></span>
<span class="code-line"><span class="code-operator">}</span></span></code></pre>
</div>
<div class="translation-english">
<span class="translation-label">PLAIN ENGLISH</span>
<div class="translation-lines">
<p class="tl"><strong>slug</strong> + <strong>name</strong> — The template's computer ID (a <span class="term" data-definition="A short, URL-friendly identifier made of lowercase letters and dashes — like '8-bit-orbit'. It's the file's nickname that computers use to reference it.">slug</span>) and its human-friendly display name.</p>
<p class="tl"><strong>tagline</strong> — One sentence capturing the vibe, so the AI can match it against your request.</p>
<p class="tl"><strong>mood</strong> + <strong>tone</strong> — Keyword tags the AI compares against your brief. "Playful cyberpunk" here, "sober corporate" elsewhere.</p>
<p class="tl"><strong>formality</strong> + <strong>density</strong> + <strong>scheme</strong> — Quick dials: how formal, how much content per slide, light or dark background.</p>
<p class="tl"><strong>best_for</strong> — When to pick this template. The AI reads this to shortlist candidates.</p>
<p class="tl"><strong>avoid_for</strong> — When NOT to pick it. This prevents embarrassing mismatches (neon arcade for a healthcare deck).</p>
<p class="tl"><strong>preview_md</strong> + <strong>design_md</strong> — File paths to the preview card and the full design recipe. The AI follows these paths only when it's time — that's the chain.</p>
</div>
</div>
</div>
<p>This entire card is pure <span class="term" data-definition="A text format for storing structured data in a way both humans and machines can read — like a neatly labeled filing cabinet where every value has a name.">JSON</span> — a <span class="term" data-definition="A way of organizing data as labeled fields with values — like a form where each box has a name. The AI reads these fields to make decisions.">structured data</span> format. No styling, no code, just facts. Small enough that the AI can scan all 34 in one gulp.</p>
</section>
<!-- SCREEN 6: Python extract-pptx.py Translation -->
<section class="screen animate-in">
<h2 class="screen-heading">Post-Production: Converting a .pptx</h2>
<p>When a user uploads an old PowerPoint, <code>scripts/extract-pptx.py</code> is the file that runs. Here's the core loop — it walks each slide and sorts objects into text versus images:</p>
<div class="translation-block animate-in">
<div class="translation-code">
<span class="translation-label">Python</span>
<pre><code><span class="code-line"><span class="code-keyword">for</span> shape <span class="code-keyword">in</span> slide.shapes:</span>
<span class="code-line"> <span class="code-comment"># Extract text content</span></span>
<span class="code-line"> <span class="code-keyword">if</span> shape.has_text_frame:</span>
<span class="code-line"> <span class="code-keyword">if</span> shape <span class="code-operator">==</span> slide.shapes.title:</span>
<span class="code-line"> slide_data[<span class="code-string">"title"</span>] <span class="code-operator">=</span> shape.text</span>
<span class="code-line"> <span class="code-keyword">else</span>:</span>
<span class="code-line"> slide_data[<span class="code-string">"content"</span>].<span class="code-function">append</span>({<span class="code-string">"type"</span>: <span class="code-string">"text"</span>, <span class="code-string">"content"</span>: shape.text})</span>
<span class="code-line"></span>
<span class="code-line"> <span class="code-comment"># Extract images</span></span>
<span class="code-line"> <span class="code-keyword">if</span> shape.shape_type <span class="code-operator">==</span> <span class="code-number">13</span>: <span class="code-comment"># Picture type</span></span>
<span class="code-line"> image <span class="code-operator">=</span> shape.image</span>
<span class="code-line"> image_bytes <span class="code-operator">=</span> image.blob</span>
<span class="code-line"> image_ext <span class="code-operator">=</span> image.ext</span>
<span class="code-line"> image_name <span class="code-operator">=</span> <span class="code-string">f"slide{slide_num + 1}_img{len(slide_data['images']) + 1}.{image_ext}"</span></span>
<span class="code-line"> image_path <span class="code-operator">=</span> os.path.<span class="code-function">join</span>(assets_dir, image_name)</span>
<span class="code-line"> <span class="code-keyword">with</span> <span class="code-function">open</span>(image_path, <span class="code-string">"wb"</span>) <span class="code-keyword">as</span> f:</span>
<span class="code-line"> f.<span class="code-function">write</span>(image_bytes)</span></code></pre>
</div>
<div class="translation-english">
<span class="translation-label">PLAIN ENGLISH</span>
<div class="translation-lines">
<p class="tl">Walk through every <span class="term" data-definition="In PowerPoint, any object on a slide — a text box, picture, arrow, or rectangle. Everything you see on a slide is a shape.">shape</span> (object) on this slide, one at a time.</p>
<p class="tl"><strong>Text branch:</strong> if this object has text and it's the slide's title, save it as the title.</p>
<p class="tl">Otherwise it's body text — add it to the content list as a text block.</p>
<p class="tl"><strong>Image branch:</strong> if the object is a picture (type 13 is PowerPoint's code for images)...</p>
<p class="tl">...grab the image, its raw <span class="term" data-definition="The raw 0s and 1s that make up a file — like the individual pixels of an image, but for any digital data.">bytes</span> (the actual pixel data), and its file extension (.png, .jpg).</p>
<p class="tl">Give it a unique name like "slide3_img2.png" so nothing collides.</p>
<p class="tl">Build the full save path, then open a new binary file and write the image data to disk — so the new HTML deck can reference it locally instead of depending on the original .pptx.</p>
</div>
</div>
</div>
<p>This is <span class="term" data-definition="A popular programming language known for readable, almost English-like syntax — often used for scripts, data work, and automation.">Python</span> — a language chosen for this job because it reads top-to-bottom like English and has libraries that understand PowerPoint files natively.</p>
</section>
<!-- SCREEN 7: Callout — Separation of Concerns -->
<section class="screen animate-in">
<h2 class="screen-heading">Why This Matters</h2>
<p>Each file owns one concern and one concern only. That's not an accident — it's the most important idea in the whole repo:</p>
<div class="callout callout-accent">
<div class="callout-icon">💡</div>
<div class="callout-content">
<strong class="callout-title">Separation of Concerns</strong>
<p>Each file owns one job and one job only. That's why you can swap the wardrobe (presets) without touching the stage rigger (<code>viewport-base.css</code>). Engineers call this <span class="term" data-definition="A design principle where each part of a system handles one job and only one job — like a kitchen where the chef cooks, the waiter serves, and the cashier handles money.">separation of concerns</span> — and it's your superpower for catching the AI when it misplaces logic.</p>
<p>If you ask for a new font and the AI edits <code>viewport-base.css</code>, you'll know that's wrong: fonts live in the presets or the chosen template, not the stage. <span class="term" data-definition="Designing parts of a system so they don't depend on each other — change one without breaking the others. Like Lego blocks that snap together but swap freely.">Decoupling</span> is what makes that judgment possible.</p>
</div>
</div>
</section>
<!-- SCREEN 8: Quiz -->
<section class="screen animate-in">
<h2 class="screen-heading">Check Your Understanding</h2>
<p>Three scenarios. Think about where each piece of logic lives — and when it gets paged.</p>
<div class="quiz-container" id="quiz-module2">
<div class="quiz-question-block"
data-correct="option-b"
data-explanation-right="Exactly — selection-index.json is the discovery entry point. The AI reads it first to find candidates; without an entry here, your new template is invisible."
data-explanation-wrong="Not quite. Think about which file the AI reads FIRST to discover templates. The index is tiny on purpose — it's the catalog the AI scans before loading anything heavy.">
<h3 class="quiz-question">1. You want to add a 35th bold template. Which file MUST you update so the AI can discover and shortlist it?</h3>
<div class="quiz-options">
<button class="quiz-option" data-value="option-a" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>design.md</span>
</button>
<button class="quiz-option" data-value="option-b" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>selection-index.json</span>
</button>
<button class="quiz-option" data-value="option-c" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>STYLE_PRESETS.md</span>
</button>
<button class="quiz-option" data-value="option-d" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>viewport-base.css</span>
</button>
</div>
<div class="quiz-feedback"></div>
</div>
<div class="quiz-question-block"
data-correct="option-a"
data-explanation-right="Exactly — design.md is large and detailed, so the AI loads it ONLY for the single template the user picked. Reading all 34 would waste context and slow everything down."
data-explanation-wrong="Not quite. The rule is about WHEN design.md gets read. It's the heaviest file in the chain — the AI should load it for exactly ONE template, after the user has chosen.">
<h3 class="quiz-question">2. The AI is generating the deck and suddenly reads ALL 34 design.md files. Which rule did it violate?</h3>
<div class="quiz-options">
<button class="quiz-option" data-value="option-a" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Read design.md only for the ONE chosen template</span>
</button>
<button class="quiz-option" data-value="option-b" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Read all preview.md files instead</span>
</button>
<button class="quiz-option" data-value="option-c" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Skip design.md entirely</span>
</button>
<button class="quiz-option" data-value="option-d" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>Read STYLE_PRESETS.md first</span>
</button>
</div>
<div class="quiz-feedback"></div>
</div>
<div class="quiz-question-block"
data-correct="option-c"
data-explanation-right="Exactly — extract-pptx.py is the Phase 4 converter. It pulls text, images, and notes out of the .pptx so the AI can rebuild them as HTML slides."
data-explanation-wrong="Not quite. Think about what 'converting' means — you need to pull content OUT of the .pptx first. That's extract-pptx.py's job in Phase 4.">
<h3 class="quiz-question">3. You're converting a .pptx. Which file does the AI run first?</h3>
<div class="quiz-options">
<button class="quiz-option" data-value="option-a" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>scripts/deploy.sh</span>
</button>
<button class="quiz-option" data-value="option-b" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>scripts/export-pdf.sh</span>
</button>
<button class="quiz-option" data-value="option-c" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>scripts/extract-pptx.py</span>
</button>
<button class="quiz-option" data-value="option-d" onclick="selectOption(this)">
<div class="quiz-option-radio"></div>
<span>viewport-base.css</span>
</button>
</div>
<div class="quiz-feedback"></div>
</div>
<button class="quiz-check-btn" onclick="checkQuiz('quiz-module2')">Check Answers</button>
<button class="quiz-reset-btn" onclick="resetQuiz('quiz-module2')">Try Again</button>
</div>
</section>
<!-- SCREEN 9: Transition to Module 3 -->
<section class="screen animate-in">
<h2 class="screen-heading">What's Next</h2>
<p>You've met the cast. Now let's look at the cleverest trick they pull:</p>
<div class="callout callout-info">
<div class="callout-icon">🔗</div>
<div class="callout-content">
<strong class="callout-title">Coming up in Module 3</strong>
<p>Notice how <code>selection-index.json</code>, <code>preview.md</code>, and <code>design.md</code> form a chain? That chain is the repo's smartest idea. Next module, we dive deep into <span class="term" data-definition="A design pattern where you reveal information gradually — show a summary first, details only when asked. Like a menu with dish names up front and full ingredients on request.">progressive disclosure</span> — the funnel that keeps the AI's <span class="term" data-definition="The text an AI can see and remember at one time — its working memory. Everything the AI reads fills up this budget, so large files are expensive.">context</span> lean.</p>
</div>
</div>
</section>
</div>
</div>
</section>
<section class="module" id="module-3" style="background: var(--color-bg-warm)">
<div class="module-content">
<header class="module-header animate-in">
<span class="module-number">03</span>
<h1 class="module-title">Progressive Disclosure</h1>
<p class="module-subtitle">How 34 templates fit into the AI's memory without blowing it up</p>
</header>
<div class="module-body">
<!-- Screen 1: The Memory Problem -->
<section class="screen animate-in">
<h2 class="screen-heading">34 Manuals, One Question</h2>
<p>There are 34 bold templates, each with a full design manual. If the AI read all 34 manuals every time you asked for a deck, it would blow its <span class="term" data-definition="The amount of text an AI can hold in mind at once — its working memory. Too much input and earlier details get pushed out, like a desk too small for all your papers.">context window</span> before writing a single slide — or worse, <span class="term" data-definition="When an AI confidently invents something that is not real — like making up a template that does not exist. Usually happens when the AI has too much to process or too little of the right info.">hallucinate</span> details from the wrong template.</p>
<p>The repo solves this with a <span class="term" data-definition="Reveal information in stages — start with a tiny summary, show more only as the choice narrows. Like a museum: floor plan first, then placards, then the full gallery.">progressive disclosure</span> funnel: a tiny <span class="term" data-definition="A compact directory listing every item with a few key facts about each — like a book index at the back, not the chapters themselves.">index</span> of all 34 templates, a <span class="term" data-definition="A small picked group from a larger set — like the 3 finalists after round one of auditions.">shortlist</span> of previews, then exactly one full <span class="term" data-definition="In this codebase, the design.md file — the complete instructions for building one template. Like a cooking recipe: every ingredient and step laid out.">recipe</span>.</p>
<p>Think of a museum visit. You never read every placard, and you never carry all the wall texts at once:</p>
<div class="icon-rows">
<div class="icon-row">
<div class="icon-circle" style="background: var(--color-actor-3)">🗺️</div>
<div>
<strong>Floor Plan — selection-index.json</strong>
<p>A tiny map at the entrance. Shows where every exhibit lives, with a few tags each. You scan all 34 — but read nothing in depth.</p>
</div>
</div>
<div class="icon-row">
<div class="icon-circle" style="background: var(--color-actor-2)">🏷️</div>
<div>
<strong>Exhibit Placards — preview.md</strong>
<p>A card outside each gallery. A glance at what is inside. You read 3 or 4 — never all 34.</p>
</div>
</div>
<div class="icon-row">
<div class="icon-circle" style="background: var(--color-actor-5)">📖</div>
<div>
<strong>Gallery Wall Text — design.md</strong>
<p>The full write-up, only in the one room you actually enter. Complete, but you carry just one at a time.</p>
</div>
</div>
</div>
</section>
<!-- Screen 2: The Funnel Animation -->
<section class="screen animate-in">
<h2 class="screen-heading">Watch the Funnel Narrow</h2>
<p>Three files, three stages. Click through to see how the AI loads less and less — but deeper and deeper.</p>
<div class="flow-animation" data-steps='[
{"highlight":"flow-actor-1","label":"Start here: 34 templates, but only metadata — mood, formality, scheme. Tiny file."},
{"highlight":"flow-actor-1","label":"AI matches your brief against the metadata. Shortlists 3 candidates.","packet":true,"from":"actor-1","to":"actor-2"},
{"highlight":"flow-actor-2","label":"Loads ONLY those 3 preview.md cards. A glance each — enough to render a title slide."},
{"highlight":"flow-actor-2","label":"You pick one by looking at the previews.","packet":true,"from":"actor-2","to":"actor-3"},
{"highlight":"flow-actor-3","label":"NOW the AI loads that single design.md — the full recipe. 34 manuals were available; only 1 was ever read."}
]'>
<div class="flow-actors">
<div class="flow-actor" id="flow-actor-1">
<div class="flow-actor-icon" style="background: var(--color-actor-3)">34</div>
<span>Index — 34 templates</span>
</div>
<div class="flow-actor" id="flow-actor-2">
<div class="flow-actor-icon" style="background: var(--color-actor-2)">3</div>
<span>Preview — 3 cards</span>
</div>
<div class="flow-actor" id="flow-actor-3">
<div class="flow-actor-icon" style="background: var(--color-actor-5)">1</div>
<span>Design.md — 1 recipe</span>
</div>
</div>
<div class="flow-packet" id="flow-packet"></div>
<div class="flow-step-label" id="flow-label">Click "Next Step" to begin</div>
<div class="flow-controls">
<button class="btn flow-next-btn">Next Step</button>
<button class="btn flow-reset-btn">Restart</button>
<span class="flow-progress"></span>
</div>
</div>
</section>
<!-- Screen 3: The Self-Documenting Contract -->
<section class="screen animate-in">
<h2 class="screen-heading">The File States Its Own Rules</h2>
<p>The index file does not just list templates — it includes a <span class="term" data-definition="A way to write structured data as text using curly braces and quotes, so both humans and machines can read it. Like a neatly labeled filing card.">JSON</span> block explaining exactly how the AI should use it. Each key is a stage-gate rule:</p>
<div class="translation-block animate-in">
<div class="translation-code">
<span class="translation-label">CODE</span>
<pre><code><span class="code-line"><span class="code-property">"usage"</span>: {</span>
<span class="code-line"> <span class="code-property">"selection"</span>: <span class="code-string">"Read this compact index first to shortlist bold templates from metadata."</span>,</span>
<span class="code-line"> <span class="code-property">"previews"</span>: <span class="code-string">"For title-slide previews, read only the preview_md files for the shortlisted bold candidates."</span>,</span>
<span class="code-line"> <span class="code-property">"final_generation"</span>: <span class="code-string">"After the user chooses a bold template, read exactly that template design_md before generating the full deck."</span>,</span>
<span class="code-line"> <span class="code-property">"never"</span>: <span class="code-string">"Do not bulk-read templates/*/design.md and do not read template.html unless the selected design.md is missing a critical implementation detail."</span></span>
<span class="code-line">}</span>
</code></pre>
</div>
<div class="translation-english">
<span class="translation-label">PLAIN ENGLISH</span>
<div class="translation-lines">
<p class="tl">This block is a contract. The file tells the AI exactly how to use it — no guessing.</p>
<p class="tl"><strong>selection:</strong> Stage 1. Always read this small index first. Use it to pick a few candidates.</p>
<p class="tl"><strong>previews:</strong> Stage 2. Only now read the preview cards — and only for the candidates you shortlisted.</p>
<p class="tl"><strong>final_generation:</strong> Stage 3. After the user picks ONE, read exactly that one design.md.</p>
<p class="tl"><strong>never:</strong> Forbidden. Never open all 34 design.md files at once. That would blow the memory budget.</p>
</div>
</div>
</div>
<div class="callout callout-info">
<div class="callout-icon">📌</div>
<div class="callout-content">
<strong class="callout-title">Good to know</strong>