create-slide-deck 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/index.js +119 -0
  2. package/package.json +36 -0
  3. package/template-full/README.md +99 -0
  4. package/template-full/package.json +47 -0
  5. package/template-full/src/reveal/components/auto-layout.ts +229 -0
  6. package/template-full/src/reveal/components/charts.tsx +213 -0
  7. package/template-full/src/reveal/core/blocks.ts +172 -0
  8. package/template-full/src/reveal/core/deck-init.ts +60 -0
  9. package/template-full/src/reveal/core/design.ts +46 -0
  10. package/template-full/src/reveal/core/layout.ts +187 -0
  11. package/template-full/src/reveal/core/mount-registry.ts +41 -0
  12. package/template-full/src/reveal/core/presets.ts +189 -0
  13. package/template-full/src/reveal/core/runtime.ts +141 -0
  14. package/template-full/src/reveal/core/types.ts +114 -0
  15. package/template-full/src/reveal/data/algorithms.ts +78 -0
  16. package/template-full/src/reveal/data/benchmark.ts +79 -0
  17. package/template-full/src/reveal/decks/demo-showcase/components/demo-arc-progress.tsx +153 -0
  18. package/template-full/src/reveal/decks/demo-showcase/components/demo-before-after.tsx +164 -0
  19. package/template-full/src/reveal/decks/demo-showcase/components/demo-bigtext.tsx +70 -0
  20. package/template-full/src/reveal/decks/demo-showcase/components/demo-card-flip.tsx +118 -0
  21. package/template-full/src/reveal/decks/demo-showcase/components/demo-chat-bubbles.tsx +257 -0
  22. package/template-full/src/reveal/decks/demo-showcase/components/demo-code.tsx +136 -0
  23. package/template-full/src/reveal/decks/demo-showcase/components/demo-concept-map.tsx +336 -0
  24. package/template-full/src/reveal/decks/demo-showcase/components/demo-counter.tsx +194 -0
  25. package/template-full/src/reveal/decks/demo-showcase/components/demo-cover.tsx +188 -0
  26. package/template-full/src/reveal/decks/demo-showcase/components/demo-dark-dashboard.tsx +166 -0
  27. package/template-full/src/reveal/decks/demo-showcase/components/demo-eval-matrix.tsx +191 -0
  28. package/template-full/src/reveal/decks/demo-showcase/components/demo-force-graph.tsx +169 -0
  29. package/template-full/src/reveal/decks/demo-showcase/components/demo-fullbleed-bars.tsx +109 -0
  30. package/template-full/src/reveal/decks/demo-showcase/components/demo-fullbleed-flow.tsx +177 -0
  31. package/template-full/src/reveal/decks/demo-showcase/components/demo-heatmap.tsx +135 -0
  32. package/template-full/src/reveal/decks/demo-showcase/components/demo-icon-wall.tsx +143 -0
  33. package/template-full/src/reveal/decks/demo-showcase/components/demo-math.tsx +103 -0
  34. package/template-full/src/reveal/decks/demo-showcase/components/demo-number-morph.tsx +126 -0
  35. package/template-full/src/reveal/decks/demo-showcase/components/demo-path.tsx +185 -0
  36. package/template-full/src/reveal/decks/demo-showcase/components/demo-radar.tsx +124 -0
  37. package/template-full/src/reveal/decks/demo-showcase/components/demo-rough.tsx +169 -0
  38. package/template-full/src/reveal/decks/demo-showcase/components/demo-sankey.tsx +144 -0
  39. package/template-full/src/reveal/decks/demo-showcase/components/demo-screenshot-annotate.tsx +181 -0
  40. package/template-full/src/reveal/decks/demo-showcase/components/demo-stacked-cards.tsx +159 -0
  41. package/template-full/src/reveal/decks/demo-showcase/components/demo-tabs.tsx +206 -0
  42. package/template-full/src/reveal/decks/demo-showcase/components/demo-timeline.tsx +162 -0
  43. package/template-full/src/reveal/decks/demo-showcase/components/demo-treemap.tsx +161 -0
  44. package/template-full/src/reveal/decks/demo-showcase/components/demo-zoom-focus.tsx +223 -0
  45. package/template-full/src/reveal/decks/demo-showcase/components/registry.ts +63 -0
  46. package/template-full/src/reveal/decks/demo-showcase/demo.css +237 -0
  47. package/template-full/src/reveal/decks/demo-showcase/index.html +24 -0
  48. package/template-full/src/reveal/decks/demo-showcase/main.ts +7 -0
  49. package/template-full/src/reveal/decks/demo-showcase/slides.ts +271 -0
  50. package/template-full/src/reveal/decks/fse26-rca/components/aws-cascade.tsx +295 -0
  51. package/template-full/src/reveal/decks/fse26-rca/components/bench-compare.tsx +64 -0
  52. package/template-full/src/reveal/decks/fse26-rca/components/bench-deficiency.tsx +104 -0
  53. package/template-full/src/reveal/decks/fse26-rca/components/bench-loop.tsx +402 -0
  54. package/template-full/src/reveal/decks/fse26-rca/components/bench-needs.tsx +78 -0
  55. package/template-full/src/reveal/decks/fse26-rca/components/closing-takeaway.tsx +165 -0
  56. package/template-full/src/reveal/decks/fse26-rca/components/cloud-incidents.tsx +88 -0
  57. package/template-full/src/reveal/decks/fse26-rca/components/failure-modes.tsx +59 -0
  58. package/template-full/src/reveal/decks/fse26-rca/components/fault-heatmap.tsx +85 -0
  59. package/template-full/src/reveal/decks/fse26-rca/components/hierarchy-tree.tsx +93 -0
  60. package/template-full/src/reveal/decks/fse26-rca/components/incident-hard.tsx +72 -0
  61. package/template-full/src/reveal/decks/fse26-rca/components/rca-pipeline.tsx +193 -0
  62. package/template-full/src/reveal/decks/fse26-rca/components/registry.ts +37 -0
  63. package/template-full/src/reveal/decks/fse26-rca/components/simple-rca.tsx +216 -0
  64. package/template-full/src/reveal/decks/fse26-rca/components/sota-collapse.tsx +63 -0
  65. package/template-full/src/reveal/decks/fse26-rca/components/srca-results.tsx +115 -0
  66. package/template-full/src/reveal/decks/fse26-rca/images/aws-outage-2025-deployflow.png +0 -0
  67. package/template-full/src/reveal/decks/fse26-rca/images/aws-post-event-summary.png +0 -0
  68. package/template-full/src/reveal/decks/fse26-rca/images/bbc-crowdstrike.png +0 -0
  69. package/template-full/src/reveal/decks/fse26-rca/images/cnn-meta-outage-2021.png +0 -0
  70. package/template-full/src/reveal/decks/fse26-rca/images/cover.png +0 -0
  71. package/template-full/src/reveal/decks/fse26-rca/images/nyt-facebook-2021.png +0 -0
  72. package/template-full/src/reveal/decks/fse26-rca/images/qr-repo.png +0 -0
  73. package/template-full/src/reveal/decks/fse26-rca/images/verge-crowdstrike-2024.png +0 -0
  74. package/template-full/src/reveal/decks/fse26-rca/images/wiki-meta-outage-2021.png +0 -0
  75. package/template-full/src/reveal/decks/fse26-rca/index.html +30 -0
  76. package/template-full/src/reveal/decks/fse26-rca/main.ts +8 -0
  77. package/template-full/src/reveal/decks/fse26-rca/slides.ts +175 -0
  78. package/template-full/src/reveal/env.d.ts +38 -0
  79. package/template-full/src/reveal/theme.css +762 -0
  80. package/template-full/src/reveal/tools/dev.mjs +120 -0
  81. package/template-full/src/reveal/tools/export-pdf.mjs +86 -0
  82. package/template-full/src/reveal/tools/preview.mjs +132 -0
  83. package/template-full/tsconfig.json +19 -0
  84. package/template-full/vite.config.ts +95 -0
  85. package/template-minimal/package.json +42 -0
  86. package/template-minimal/src/reveal/components/auto-layout.ts +229 -0
  87. package/template-minimal/src/reveal/components/charts.tsx +213 -0
  88. package/template-minimal/src/reveal/core/blocks.ts +172 -0
  89. package/template-minimal/src/reveal/core/deck-init.ts +60 -0
  90. package/template-minimal/src/reveal/core/design.ts +46 -0
  91. package/template-minimal/src/reveal/core/layout.ts +187 -0
  92. package/template-minimal/src/reveal/core/mount-registry.ts +41 -0
  93. package/template-minimal/src/reveal/core/presets.ts +189 -0
  94. package/template-minimal/src/reveal/core/runtime.ts +141 -0
  95. package/template-minimal/src/reveal/core/types.ts +114 -0
  96. package/template-minimal/src/reveal/data/.gitkeep +0 -0
  97. package/template-minimal/src/reveal/decks/my-deck/components/example-component.tsx +28 -0
  98. package/template-minimal/src/reveal/decks/my-deck/components/registry.ts +9 -0
  99. package/template-minimal/src/reveal/decks/my-deck/index.html +14 -0
  100. package/template-minimal/src/reveal/decks/my-deck/main.ts +5 -0
  101. package/template-minimal/src/reveal/decks/my-deck/slides.ts +34 -0
  102. package/template-minimal/src/reveal/env.d.ts +38 -0
  103. package/template-minimal/src/reveal/theme.css +762 -0
  104. package/template-minimal/tsconfig.json +19 -0
  105. package/template-minimal/vite.config.ts +95 -0
@@ -0,0 +1,143 @@
1
+ import React from "react";
2
+ import {
3
+ Server, Database, Shield, Zap, Globe, Cloud, Lock, Cpu,
4
+ HardDrive, Wifi, Monitor, Smartphone, Code, Terminal, GitBranch, Layers,
5
+ } from "lucide-react";
6
+ import type { SlideComponentProps } from "../../../core/types.ts";
7
+ import { CANVAS, useRevealStep } from "../../../core/presets.ts";
8
+
9
+ const PALETTE = ["#4361ee", "#3a0ca3", "#7209b7", "#f72585", "#4cc9f0"];
10
+
11
+ const ICONS = [
12
+ { Icon: Server, label: "Server" },
13
+ { Icon: Database, label: "Database" },
14
+ { Icon: Shield, label: "Shield" },
15
+ { Icon: Zap, label: "Compute" },
16
+ { Icon: Globe, label: "Network" },
17
+ { Icon: Cloud, label: "Cloud" },
18
+ { Icon: Lock, label: "Security" },
19
+ { Icon: Cpu, label: "CPU" },
20
+ { Icon: HardDrive, label: "Storage" },
21
+ { Icon: Wifi, label: "Wireless" },
22
+ { Icon: Monitor, label: "Desktop" },
23
+ { Icon: Smartphone, label: "Mobile" },
24
+ { Icon: Code, label: "Code" },
25
+ { Icon: Terminal, label: "Shell" },
26
+ { Icon: GitBranch, label: "Branch" },
27
+ { Icon: Layers, label: "Layers" },
28
+ ];
29
+
30
+ export default function DemoIconWall({ Reveal }: SlideComponentProps) {
31
+ const ref = useRevealStep(Reveal);
32
+ const step = ref[0], ready = ref[1], instant = ref[2];
33
+
34
+ const gridRef = React.useRef<HTMLDivElement>(null);
35
+ const cellRefs = React.useRef<(HTMLDivElement | null)[]>([]);
36
+
37
+ // Step 0: stagger wave-in across the 4x4 grid.
38
+ React.useEffect(function () {
39
+ const cells = cellRefs.current.filter(Boolean) as HTMLDivElement[];
40
+ if (!cells.length) return;
41
+ const anime = (window as any).anime;
42
+ if (step < 0) {
43
+ cells.forEach(function (el) { el.style.opacity = "0"; el.style.transform = "scale(0)"; });
44
+ return;
45
+ }
46
+ if (!anime || instant) {
47
+ cells.forEach(function (el) { el.style.opacity = "1"; el.style.transform = "scale(1)"; });
48
+ return;
49
+ }
50
+ cells.forEach(function (el) { el.style.opacity = "0"; el.style.transform = "scale(0)"; });
51
+ anime.animate(cells, {
52
+ opacity: [0, 1],
53
+ scale: [0, 1],
54
+ duration: 520,
55
+ easing: "outBack",
56
+ delay: anime.stagger(80, { grid: [4, 4], from: "first" }),
57
+ });
58
+ }, [step >= 0, instant]);
59
+
60
+ // Step 2: one icon pulses to demo interaction.
61
+ React.useEffect(function () {
62
+ const anime = (window as any).anime;
63
+ const target = cellRefs.current[5];
64
+ if (!target) return;
65
+ if (step < 2 || !anime || instant) {
66
+ target.style.transform = "scale(1)";
67
+ return;
68
+ }
69
+ const loop = anime.animate(target, {
70
+ scale: [1, 1.12, 1],
71
+ duration: 900,
72
+ easing: "inOutQuad",
73
+ loop: true,
74
+ });
75
+ return function () { loop && loop.pause && loop.pause(); };
76
+ }, [step >= 2, instant]);
77
+
78
+ return (
79
+ <div
80
+ style={{
81
+ width: "100%",
82
+ height: "100%",
83
+ display: "flex",
84
+ alignItems: "center",
85
+ justifyContent: "center",
86
+ fontFamily: CANVAS.fontFamily,
87
+ opacity: ready ? 1 : 0,
88
+ transition: "opacity 0.2s ease",
89
+ }}
90
+ >
91
+ <div
92
+ ref={gridRef}
93
+ style={{
94
+ display: "grid",
95
+ gridTemplateColumns: "repeat(4, 140px)",
96
+ gridTemplateRows: "repeat(4, 130px)",
97
+ gap: 16,
98
+ }}
99
+ >
100
+ {ICONS.map(function (item, i) {
101
+ const color = PALETTE[i % PALETTE.length];
102
+ const colored = step >= 1;
103
+ const Icon = item.Icon;
104
+ return (
105
+ <div
106
+ key={i}
107
+ ref={function (el) { cellRefs.current[i] = el; }}
108
+ style={{
109
+ width: 140,
110
+ height: 130,
111
+ display: "flex",
112
+ flexDirection: "column",
113
+ alignItems: "center",
114
+ justifyContent: "center",
115
+ gap: 10,
116
+ borderRadius: 8,
117
+ background: colored ? "#fff" : "#f7f7f9",
118
+ boxShadow: colored ? "0 6px 18px rgba(49,49,49,0.12)" : "0 2px 6px rgba(49,49,49,0.06)",
119
+ transition: instant ? "none" : "background 0.4s ease, box-shadow 0.4s ease",
120
+ }}
121
+ >
122
+ <div
123
+ style={{
124
+ width: 64,
125
+ height: 64,
126
+ borderRadius: "50%",
127
+ display: "flex",
128
+ alignItems: "center",
129
+ justifyContent: "center",
130
+ background: colored ? color : "transparent",
131
+ transition: instant ? "none" : "background 0.4s ease",
132
+ }}
133
+ >
134
+ <Icon size={40} color={colored ? "#fff" : "#767676"} strokeWidth={2} />
135
+ </div>
136
+ <div style={{ fontSize: 14, fontWeight: 600, color: "#767676" }}>{item.label}</div>
137
+ </div>
138
+ );
139
+ })}
140
+ </div>
141
+ </div>
142
+ );
143
+ }
@@ -0,0 +1,103 @@
1
+ import React from "react";
2
+ import katex from "katex";
3
+ import type { SlideComponentProps } from "../../../core/types.ts";
4
+ import { CANVAS, useRevealStep } from "../../../core/presets.ts";
5
+
6
+ const KATEX_CSS = `@font-face{font-display:block;font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_AMS-Regular.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(/node_modules/katex/dist/fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(/node_modules/katex/dist/fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(/node_modules/katex/dist/fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Main-Bold.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(/node_modules/katex/dist/fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Main-Italic.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Main-Regular.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(/node_modules/katex/dist/fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Math-Italic.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(/node_modules/katex/dist/fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Script-Regular.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Size1-Regular.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Size2-Regular.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Size3-Regular.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Size4-Regular.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(/node_modules/katex/dist/fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(/node_modules/katex/dist/fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(/node_modules/katex/dist/fonts/KaTeX_Typewriter-Regular.ttf) format("truetype")}.katex{font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;position:relative;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.17.0"}.katex .katex-mathml{border:0;-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .mathsfit,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .smash{display:inline;line-height:0}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.1666666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.6666666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.4566666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.1466666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.7142857143em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.8571428571em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.1428571429em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.2857142857em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.4285714286em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.7142857143em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.0571428571em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.4685714286em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.9628571429em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.5542857143em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.7777777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.8888888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.1111111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.3044444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.7644444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.5833333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.7283333333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.0733333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.4861111111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.4402777778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.7277777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.2893518519em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.4050925926em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.462962963em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.5208333333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.2002314815em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.4398148148em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.2410800386em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.2892960463em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.337512054em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.3857280617em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.4339440694em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.4821600771em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.5785920926em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.6943105111em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.8331726133em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.1996142719em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.2009646302em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.2411575563em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.2813504823em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.3215434084em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.3617363344em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.4019292605em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.4823151125em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.578778135em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.6945337621em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.8336012862em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex svg{fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo}
7
+ `;
8
+
9
+ const EXTRA_CSS = "\
10
+ .dm-card .katex{font-size:1.5em;}\
11
+ .dm-card .katex-display{margin:0;}";
12
+
13
+ const FORMULAS = [
14
+ {
15
+ name: "Bayes' Theorem",
16
+ tex: "P(A\\mid B) = \\frac{P(B\\mid A)\\,P(A)}{P(B)}",
17
+ },
18
+ {
19
+ name: "Cross-Entropy Loss",
20
+ tex: "H(p,q) = -\\sum_{x} p(x)\\,\\log q(x)",
21
+ },
22
+ {
23
+ name: "Softmax",
24
+ tex: "\\mathrm{softmax}(x_i) = \\frac{e^{x_i}}{\\sum_{j} e^{x_j}}",
25
+ },
26
+ ];
27
+
28
+ function renderTex(tex: string) {
29
+ return katex.renderToString(tex, { throwOnError: false, displayMode: true });
30
+ }
31
+
32
+ export default function DemoMath({ Reveal }: SlideComponentProps) {
33
+ const ref = useRevealStep(Reveal);
34
+ const step = ref[0], ready = ref[1], instant = ref[2];
35
+
36
+ return (
37
+ <div style={{
38
+ width: "100%",
39
+ height: "100%",
40
+ display: "flex",
41
+ flexDirection: "column",
42
+ alignItems: "center",
43
+ justifyContent: "center",
44
+ gap: 20,
45
+ fontFamily: CANVAS.fontFamily,
46
+ opacity: ready ? 1 : 0,
47
+ transition: "opacity 0.2s ease",
48
+ }}>
49
+ <style dangerouslySetInnerHTML={{ __html: KATEX_CSS + EXTRA_CSS }} />
50
+
51
+ {FORMULAS.map(function (f, i) {
52
+ const shown = step >= i;
53
+ return (
54
+ <div
55
+ key={i}
56
+ className="dm-card"
57
+ style={{
58
+ opacity: shown ? 1 : 0,
59
+ transform: shown ? "translateY(0)" : "translateY(16px)",
60
+ transition: instant ? "none" : "opacity 0.45s ease, transform 0.45s ease",
61
+ background: "#ffffff",
62
+ borderRadius: 16,
63
+ padding: "26px 30px",
64
+ boxShadow: "0 6px 22px rgba(0,0,0,0.10)",
65
+ width: 760,
66
+ maxWidth: 900,
67
+ boxSizing: "border-box",
68
+ textAlign: "center",
69
+ }}
70
+ >
71
+ <div style={{ fontSize: 18, fontWeight: 800, color: "#4361ee", marginBottom: 14 }}>
72
+ {f.name}
73
+ </div>
74
+ <div dangerouslySetInnerHTML={{ __html: renderTex(f.tex) }} />
75
+ </div>
76
+ );
77
+ })}
78
+
79
+ <div style={{
80
+ opacity: step >= 3 ? 1 : 0,
81
+ transform: step >= 3 ? "translateY(0)" : "translateY(16px)",
82
+ transition: instant ? "none" : "opacity 0.45s ease, transform 0.45s ease",
83
+ marginTop: 4,
84
+ background: "#eef2ff",
85
+ border: "1px solid #c7d2fe",
86
+ borderRadius: 12,
87
+ padding: "14px 24px",
88
+ width: 760,
89
+ maxWidth: 900,
90
+ boxSizing: "border-box",
91
+ fontSize: 15,
92
+ fontWeight: 600,
93
+ color: "#3730a3",
94
+ lineHeight: 1.5,
95
+ textAlign: "center",
96
+ }}>
97
+ All three share a probabilistic core: Bayes inverts a conditional, cross-entropy
98
+ scores a predicted distribution against the truth, and softmax produces that
99
+ normalized distribution in the first place.
100
+ </div>
101
+ </div>
102
+ );
103
+ }
@@ -0,0 +1,126 @@
1
+ import React from "react";
2
+ import type { SlideComponentProps } from "../../../core/types.ts";
3
+ import { CANVAS, vis, useRevealStep } from "../../../core/presets.ts";
4
+
5
+ const anime = (typeof window !== "undefined") ? (window as any).anime : null;
6
+
7
+ function lerpColor(a: number[], b: number[], t: number) {
8
+ const r = Math.round(a[0] + (b[0] - a[0]) * t);
9
+ const g = Math.round(a[1] + (b[1] - a[1]) * t);
10
+ const bl = Math.round(a[2] + (b[2] - a[2]) * t);
11
+ return "rgb(" + r + "," + g + "," + bl + ")";
12
+ }
13
+
14
+ const RED = [220, 38, 38]; // #dc2626
15
+ const GREEN = [5, 150, 105]; // #059669
16
+
17
+ const COMPARISONS = [
18
+ { label: "Top-1 Accuracy", old: "58.4%", neu: "94.2%" },
19
+ { label: "Coverage", old: "62%", neu: "87.3%" },
20
+ { label: "False Positives", old: "23%", neu: "3.1%" },
21
+ ];
22
+
23
+ export default function DemoNumberMorph(props: SlideComponentProps) {
24
+ const Reveal = props.Reveal;
25
+ const ref = useRevealStep(Reveal);
26
+ const step = ref[0], ready = ref[1], instant = ref[2];
27
+
28
+ const stateRef = React.useState({ val: 30, color: "rgb(220,38,38)" });
29
+ const view = stateRef[0], setView = stateRef[1];
30
+
31
+ const morphedRef = React.useRef(false);
32
+
33
+ React.useEffect(function () {
34
+ if (step >= 1) {
35
+ if (morphedRef.current) return;
36
+ morphedRef.current = true;
37
+ if (!anime || !anime.animate) {
38
+ setView({ val: 4.2, color: "rgb(5,150,105)" });
39
+ return;
40
+ }
41
+ const obj = { val: 30, t: 0 };
42
+ anime.animate(obj, {
43
+ val: 4.2,
44
+ t: 1,
45
+ duration: 1500,
46
+ ease: "outExpo",
47
+ update: function () {
48
+ setView({ val: obj.val, color: lerpColor(RED, GREEN, obj.t) });
49
+ },
50
+ });
51
+ } else {
52
+ morphedRef.current = false;
53
+ setView({ val: 30, color: "rgb(220,38,38)" });
54
+ }
55
+ }, [step]);
56
+
57
+ const isMorphed = step >= 1;
58
+ const displayVal = isMorphed
59
+ ? view.val.toFixed(1)
60
+ : Math.round(view.val) + "+";
61
+
62
+ return (
63
+ <div style={{
64
+ width: "100%", height: "100%",
65
+ display: "flex", flexDirection: "column",
66
+ alignItems: "center", justifyContent: "center",
67
+ fontFamily: CANVAS.fontFamily,
68
+ opacity: ready ? 1 : 0,
69
+ transition: "opacity 0.2s ease",
70
+ }}>
71
+ {/* hero number */}
72
+ <div style={{ display: "flex", alignItems: "baseline", gap: 12 }}>
73
+ <span style={{
74
+ fontSize: 100, fontWeight: 900,
75
+ color: view.color, lineHeight: 1,
76
+ fontVariantNumeric: "tabular-nums",
77
+ }}>{displayVal}</span>
78
+ <span style={{ fontSize: 40, fontWeight: 700, color: view.color }}>min</span>
79
+ <span style={Object.assign({
80
+ marginLeft: 16, fontSize: 22, fontWeight: 800,
81
+ color: "#059669", background: "#d1fae5",
82
+ padding: "6px 14px", borderRadius: 999,
83
+ }, vis(step, 1, instant))}>7x faster</span>
84
+ </div>
85
+
86
+ {/* label */}
87
+ <div style={{ fontSize: 20, fontWeight: 600, color: "#6b7280", marginTop: 14 }}>
88
+ Mean Time to Detect
89
+ </div>
90
+
91
+ {/* comparison stats */}
92
+ <div style={Object.assign({
93
+ display: "flex", gap: 32, marginTop: 48,
94
+ }, vis(step, 2, instant))}>
95
+ {COMPARISONS.map(function (c, i) {
96
+ return (
97
+ <div key={i} style={{
98
+ display: "flex", flexDirection: "column", alignItems: "center",
99
+ minWidth: 200,
100
+ }}>
101
+ <div style={{ fontSize: 15, fontWeight: 700, color: "#6b7280", marginBottom: 8 }}>
102
+ {c.label}
103
+ </div>
104
+ <div style={{ display: "flex", alignItems: "baseline", gap: 8 }}>
105
+ <span style={{
106
+ fontSize: 22, fontWeight: 700, color: "#dc2626",
107
+ textDecoration: "line-through",
108
+ }}>{c.old}</span>
109
+ <span style={{ fontSize: 18, color: "#9ca3af" }}>&#8594;</span>
110
+ <span style={{ fontSize: 26, fontWeight: 900, color: "#059669" }}>{c.neu}</span>
111
+ </div>
112
+ </div>
113
+ );
114
+ })}
115
+ </div>
116
+
117
+ {/* conclusion */}
118
+ <div style={Object.assign({
119
+ marginTop: 44, fontSize: 18, fontWeight: 600,
120
+ color: "#374151", fontStyle: "italic",
121
+ }, vis(step, 3, instant))}>
122
+ End-to-end improvement across all dimensions
123
+ </div>
124
+ </div>
125
+ );
126
+ }
@@ -0,0 +1,185 @@
1
+ import React from "react";
2
+ import type { SlideComponentProps } from "../../../core/types.ts";
3
+ import { useRevealStep } from "../../../core/presets.ts";
4
+
5
+ const W = 1200, H = 560;
6
+
7
+ // An S-shaped bezier curve spanning the canvas.
8
+ const PATH_D =
9
+ "M 120,440 C 320,440 320,120 560,120 S 880,440 1080,120";
10
+
11
+ const PARTICLE_COLORS = ["#4361ee", "#7209b7", "#f72585", "#4cc9f0", "#4895ef"];
12
+
13
+ // Subtle background grid dots.
14
+ function gridDots() {
15
+ const dots = [];
16
+ for (let y = 40; y < H; y += 60) {
17
+ for (let x = 40; x < W; x += 60) {
18
+ dots.push(<circle key={x + "-" + y} cx={x} cy={y} r={1.5} fill="#d6d6e8" />);
19
+ }
20
+ }
21
+ return dots;
22
+ }
23
+
24
+ export default function DemoPath({ Reveal }: SlideComponentProps) {
25
+ const rs = useRevealStep(Reveal);
26
+ const step = rs[0], ready = rs[1], instant = rs[2];
27
+
28
+ const pathRef = React.useRef<SVGPathElement>(null);
29
+ const leadRef = React.useRef<SVGGElement>(null);
30
+ const trailRefs = React.useRef<(SVGGElement | null)[]>([]);
31
+ const gradStopRefs = React.useRef<(SVGStopElement | null)[]>([]);
32
+
33
+ function pointAt(progress: number) {
34
+ const el = pathRef.current;
35
+ if (!el) return { x: 0, y: 0 };
36
+ const len = el.getTotalLength();
37
+ return el.getPointAtLength(len * progress);
38
+ }
39
+
40
+ function placeAt(node: SVGGElement | null, progress: number) {
41
+ if (!node) return;
42
+ const p = pointAt(progress);
43
+ node.setAttribute("transform", "translate(" + p.x + "," + p.y + ")");
44
+ }
45
+
46
+ function runStep(step: number, instant: boolean) {
47
+ const anime = (window as any).anime;
48
+ const path = pathRef.current;
49
+ if (!path) return;
50
+ const len = path.getTotalLength();
51
+ path.style.strokeDasharray = String(len);
52
+
53
+ // Step 0: draw the path.
54
+ if (step >= 0) {
55
+ if (!anime || instant) {
56
+ path.style.strokeDashoffset = String(0);
57
+ } else if (path.dataset.drawn !== "1") {
58
+ path.dataset.drawn = "1";
59
+ anime.animate(path, {
60
+ strokeDashoffset: [len, 0],
61
+ duration: 1400,
62
+ easing: "inOutQuad",
63
+ });
64
+ }
65
+ } else {
66
+ path.style.strokeDashoffset = String(len);
67
+ path.dataset.drawn = "0";
68
+ }
69
+
70
+ // Step 1: single particle travels along the path.
71
+ const lead = leadRef.current;
72
+ if (lead) {
73
+ if (step >= 1) {
74
+ lead.style.opacity = "1";
75
+ if (!anime || instant) {
76
+ placeAt(lead, 1);
77
+ } else {
78
+ const moverL = { t: 0 };
79
+ anime.animate(moverL, {
80
+ t: 1,
81
+ duration: 2000,
82
+ easing: "inOutCubic",
83
+ onUpdate: function () { placeAt(lead, moverL.t); },
84
+ });
85
+ }
86
+ } else {
87
+ lead.style.opacity = "0";
88
+ placeAt(lead, 0);
89
+ }
90
+ }
91
+
92
+ // Step 2: staggered trail of particles.
93
+ const trail = trailRefs.current.filter(Boolean) as SVGGElement[];
94
+ trail.forEach(function (node, i) {
95
+ if (step >= 2) {
96
+ node.style.opacity = "1";
97
+ if (!anime || instant) {
98
+ placeAt(node, 1);
99
+ } else {
100
+ const mover = { t: 0 };
101
+ anime.animate(mover, {
102
+ t: 1,
103
+ duration: 2200,
104
+ easing: "inOutSine",
105
+ delay: i * 180,
106
+ loop: true,
107
+ onUpdate: function () { placeAt(node, mover.t); },
108
+ });
109
+ }
110
+ } else {
111
+ node.style.opacity = "0";
112
+ placeAt(node, 0);
113
+ }
114
+ });
115
+
116
+ // Step 3: gradient color sweep.
117
+ const stops = gradStopRefs.current.filter(Boolean) as SVGStopElement[];
118
+ if (stops.length && step >= 3 && anime && !instant) {
119
+ anime.animate(stops, {
120
+ stopColor: ["#4361ee", "#f72585", "#4cc9f0"],
121
+ duration: 1600,
122
+ easing: "inOutQuad",
123
+ loop: true,
124
+ alternate: true,
125
+ });
126
+ }
127
+ }
128
+
129
+ // Drive imperative anime after the SVG paints with current refs.
130
+ React.useEffect(function () {
131
+ const id = requestAnimationFrame(function () { runStep(step, instant); });
132
+ return function () { cancelAnimationFrame(id); };
133
+ }, [step, instant]);
134
+
135
+ return (
136
+ <svg
137
+ viewBox={"0 0 " + W + " " + H}
138
+ style={{ width: "100%", height: "100%", display: "block", opacity: ready ? 1 : 0, transition: "opacity 0.2s ease" }}
139
+ >
140
+ <defs>
141
+ <linearGradient id="demoPathGrad" x1="0" y1="0" x2="1" y2="0">
142
+ <stop ref={function (el) { gradStopRefs.current[0] = el; }} offset="0%" stopColor="#4361ee" />
143
+ <stop ref={function (el) { gradStopRefs.current[1] = el; }} offset="100%" stopColor="#f72585" />
144
+ </linearGradient>
145
+ <filter id="demoGlow" x="-150%" y="-150%" width="400%" height="400%">
146
+ <feGaussianBlur stdDeviation="4" result="blur" />
147
+ <feMerge>
148
+ <feMergeNode in="blur" />
149
+ <feMergeNode in="SourceGraphic" />
150
+ </feMerge>
151
+ </filter>
152
+ </defs>
153
+
154
+ <g>{gridDots()}</g>
155
+
156
+ <path
157
+ ref={pathRef}
158
+ d={PATH_D}
159
+ fill="none"
160
+ stroke="url(#demoPathGrad)"
161
+ strokeWidth={6}
162
+ strokeLinecap="round"
163
+ />
164
+
165
+ {/* Trail particles */}
166
+ {PARTICLE_COLORS.map(function (c, i) {
167
+ return (
168
+ <g
169
+ key={i}
170
+ ref={function (el) { trailRefs.current[i] = el; }}
171
+ style={{ opacity: 0 }}
172
+ >
173
+ <circle r={7} fill={c} filter="url(#demoGlow)" />
174
+ </g>
175
+ );
176
+ })}
177
+
178
+ {/* Lead particle */}
179
+ <g ref={leadRef} style={{ opacity: 0 }}>
180
+ <circle r={11} fill="#fff" filter="url(#demoGlow)" />
181
+ <circle r={6} fill="#4361ee" />
182
+ </g>
183
+ </svg>
184
+ );
185
+ }