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.
- package/dist/index.js +119 -0
- package/package.json +36 -0
- package/template-full/README.md +99 -0
- package/template-full/package.json +47 -0
- package/template-full/src/reveal/components/auto-layout.ts +229 -0
- package/template-full/src/reveal/components/charts.tsx +213 -0
- package/template-full/src/reveal/core/blocks.ts +172 -0
- package/template-full/src/reveal/core/deck-init.ts +60 -0
- package/template-full/src/reveal/core/design.ts +46 -0
- package/template-full/src/reveal/core/layout.ts +187 -0
- package/template-full/src/reveal/core/mount-registry.ts +41 -0
- package/template-full/src/reveal/core/presets.ts +189 -0
- package/template-full/src/reveal/core/runtime.ts +141 -0
- package/template-full/src/reveal/core/types.ts +114 -0
- package/template-full/src/reveal/data/algorithms.ts +78 -0
- package/template-full/src/reveal/data/benchmark.ts +79 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-arc-progress.tsx +153 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-before-after.tsx +164 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-bigtext.tsx +70 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-card-flip.tsx +118 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-chat-bubbles.tsx +257 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-code.tsx +136 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-concept-map.tsx +336 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-counter.tsx +194 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-cover.tsx +188 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-dark-dashboard.tsx +166 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-eval-matrix.tsx +191 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-force-graph.tsx +169 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-fullbleed-bars.tsx +109 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-fullbleed-flow.tsx +177 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-heatmap.tsx +135 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-icon-wall.tsx +143 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-math.tsx +103 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-number-morph.tsx +126 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-path.tsx +185 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-radar.tsx +124 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-rough.tsx +169 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-sankey.tsx +144 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-screenshot-annotate.tsx +181 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-stacked-cards.tsx +159 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-tabs.tsx +206 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-timeline.tsx +162 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-treemap.tsx +161 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-zoom-focus.tsx +223 -0
- package/template-full/src/reveal/decks/demo-showcase/components/registry.ts +63 -0
- package/template-full/src/reveal/decks/demo-showcase/demo.css +237 -0
- package/template-full/src/reveal/decks/demo-showcase/index.html +24 -0
- package/template-full/src/reveal/decks/demo-showcase/main.ts +7 -0
- package/template-full/src/reveal/decks/demo-showcase/slides.ts +271 -0
- package/template-full/src/reveal/decks/fse26-rca/components/aws-cascade.tsx +295 -0
- package/template-full/src/reveal/decks/fse26-rca/components/bench-compare.tsx +64 -0
- package/template-full/src/reveal/decks/fse26-rca/components/bench-deficiency.tsx +104 -0
- package/template-full/src/reveal/decks/fse26-rca/components/bench-loop.tsx +402 -0
- package/template-full/src/reveal/decks/fse26-rca/components/bench-needs.tsx +78 -0
- package/template-full/src/reveal/decks/fse26-rca/components/closing-takeaway.tsx +165 -0
- package/template-full/src/reveal/decks/fse26-rca/components/cloud-incidents.tsx +88 -0
- package/template-full/src/reveal/decks/fse26-rca/components/failure-modes.tsx +59 -0
- package/template-full/src/reveal/decks/fse26-rca/components/fault-heatmap.tsx +85 -0
- package/template-full/src/reveal/decks/fse26-rca/components/hierarchy-tree.tsx +93 -0
- package/template-full/src/reveal/decks/fse26-rca/components/incident-hard.tsx +72 -0
- package/template-full/src/reveal/decks/fse26-rca/components/rca-pipeline.tsx +193 -0
- package/template-full/src/reveal/decks/fse26-rca/components/registry.ts +37 -0
- package/template-full/src/reveal/decks/fse26-rca/components/simple-rca.tsx +216 -0
- package/template-full/src/reveal/decks/fse26-rca/components/sota-collapse.tsx +63 -0
- package/template-full/src/reveal/decks/fse26-rca/components/srca-results.tsx +115 -0
- package/template-full/src/reveal/decks/fse26-rca/images/aws-outage-2025-deployflow.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/aws-post-event-summary.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/bbc-crowdstrike.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/cnn-meta-outage-2021.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/cover.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/nyt-facebook-2021.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/qr-repo.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/verge-crowdstrike-2024.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/wiki-meta-outage-2021.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/index.html +30 -0
- package/template-full/src/reveal/decks/fse26-rca/main.ts +8 -0
- package/template-full/src/reveal/decks/fse26-rca/slides.ts +175 -0
- package/template-full/src/reveal/env.d.ts +38 -0
- package/template-full/src/reveal/theme.css +762 -0
- package/template-full/src/reveal/tools/dev.mjs +120 -0
- package/template-full/src/reveal/tools/export-pdf.mjs +86 -0
- package/template-full/src/reveal/tools/preview.mjs +132 -0
- package/template-full/tsconfig.json +19 -0
- package/template-full/vite.config.ts +95 -0
- package/template-minimal/package.json +42 -0
- package/template-minimal/src/reveal/components/auto-layout.ts +229 -0
- package/template-minimal/src/reveal/components/charts.tsx +213 -0
- package/template-minimal/src/reveal/core/blocks.ts +172 -0
- package/template-minimal/src/reveal/core/deck-init.ts +60 -0
- package/template-minimal/src/reveal/core/design.ts +46 -0
- package/template-minimal/src/reveal/core/layout.ts +187 -0
- package/template-minimal/src/reveal/core/mount-registry.ts +41 -0
- package/template-minimal/src/reveal/core/presets.ts +189 -0
- package/template-minimal/src/reveal/core/runtime.ts +141 -0
- package/template-minimal/src/reveal/core/types.ts +114 -0
- package/template-minimal/src/reveal/data/.gitkeep +0 -0
- package/template-minimal/src/reveal/decks/my-deck/components/example-component.tsx +28 -0
- package/template-minimal/src/reveal/decks/my-deck/components/registry.ts +9 -0
- package/template-minimal/src/reveal/decks/my-deck/index.html +14 -0
- package/template-minimal/src/reveal/decks/my-deck/main.ts +5 -0
- package/template-minimal/src/reveal/decks/my-deck/slides.ts +34 -0
- package/template-minimal/src/reveal/env.d.ts +38 -0
- package/template-minimal/src/reveal/theme.css +762 -0
- package/template-minimal/tsconfig.json +19 -0
- package/template-minimal/vite.config.ts +95 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { CANVAS, vis, useRevealStep } from "../../../core/presets.ts";
|
|
3
|
+
import type { SlideComponentProps } from "../../../core/types.ts";
|
|
4
|
+
|
|
5
|
+
const anime = (typeof window !== "undefined") ? (window as any).anime : null;
|
|
6
|
+
|
|
7
|
+
const R = 60;
|
|
8
|
+
const CIRC = 2 * Math.PI * R;
|
|
9
|
+
|
|
10
|
+
const GAUGES = [
|
|
11
|
+
{ key: "precision", label: "Precision", value: 94.2, suffix: "%", color: "#2563eb", baseline: "78.3%" },
|
|
12
|
+
{ key: "recall", label: "Recall", value: 87.3, suffix: "%", color: "#9333ea", baseline: "71.2%" },
|
|
13
|
+
{ key: "f1", label: "F1 Score", value: 90.6, suffix: "%", color: "#db2777", baseline: "74.5%" },
|
|
14
|
+
{ key: "speed", label: "Speed", value: 7, suffix: "x", color: "#059669", baseline: "3x", max: 10 },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
export default function DemoArcProgress(props: SlideComponentProps) {
|
|
18
|
+
const Reveal = props.Reveal;
|
|
19
|
+
const ref = useRevealStep(Reveal);
|
|
20
|
+
const step = ref[0], ready = ref[1], instant = ref[2];
|
|
21
|
+
|
|
22
|
+
// animated fraction (0..1) and displayed number per gauge
|
|
23
|
+
const animRef = React.useState(GAUGES.map(function () { return { frac: 0, num: 0 }; }));
|
|
24
|
+
const anims = animRef[0], setAnims = animRef[1];
|
|
25
|
+
|
|
26
|
+
const playedRef = React.useRef(false);
|
|
27
|
+
|
|
28
|
+
React.useEffect(function () {
|
|
29
|
+
if (step >= 0) {
|
|
30
|
+
if (playedRef.current) return;
|
|
31
|
+
playedRef.current = true;
|
|
32
|
+
if (!anime || !anime.animate) {
|
|
33
|
+
setAnims(GAUGES.map(function (g) {
|
|
34
|
+
const frac = g.value / (g.max || 100);
|
|
35
|
+
return { frac: frac, num: g.value };
|
|
36
|
+
}));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
GAUGES.forEach(function (g, i) {
|
|
40
|
+
const target = g.value / (g.max || 100);
|
|
41
|
+
const obj = { frac: 0, num: 0 };
|
|
42
|
+
anime.animate(obj, {
|
|
43
|
+
frac: target,
|
|
44
|
+
num: g.value,
|
|
45
|
+
duration: 1400,
|
|
46
|
+
ease: "outCubic",
|
|
47
|
+
update: function () {
|
|
48
|
+
setAnims(function (prev) {
|
|
49
|
+
const next = prev.slice();
|
|
50
|
+
next[i] = { frac: obj.frac, num: obj.num };
|
|
51
|
+
return next;
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
playedRef.current = false;
|
|
58
|
+
setAnims(GAUGES.map(function () { return { frac: 0, num: 0 }; }));
|
|
59
|
+
}
|
|
60
|
+
}, [step]);
|
|
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
|
+
<div style={{ display: "flex", gap: 48, alignItems: "flex-start" }}>
|
|
72
|
+
{GAUGES.map(function (g, i) {
|
|
73
|
+
const a = anims[i] || { frac: 0, num: 0 };
|
|
74
|
+
const offset = CIRC * (1 - a.frac);
|
|
75
|
+
const isBest = g.key === "precision";
|
|
76
|
+
const displayNum = g.suffix === "x"
|
|
77
|
+
? a.num.toFixed(1)
|
|
78
|
+
: a.num.toFixed(1);
|
|
79
|
+
return (
|
|
80
|
+
<div key={g.key} style={{
|
|
81
|
+
display: "flex", flexDirection: "column", alignItems: "center",
|
|
82
|
+
}}>
|
|
83
|
+
<div style={{ position: "relative", width: 160, height: 160 }}>
|
|
84
|
+
<svg viewBox="0 0 160 160" style={{ width: 160, height: 160 }}>
|
|
85
|
+
{isBest && (
|
|
86
|
+
<circle
|
|
87
|
+
cx="80" cy="80" r={R + 12}
|
|
88
|
+
fill="none"
|
|
89
|
+
stroke={g.color}
|
|
90
|
+
strokeWidth="3"
|
|
91
|
+
style={Object.assign({
|
|
92
|
+
transformOrigin: "80px 80px",
|
|
93
|
+
animation: step >= 1 ? "arcPulse 1.6s ease-in-out infinite" : "none",
|
|
94
|
+
opacity: step >= 1 ? 1 : 0,
|
|
95
|
+
transition: instant ? "none" : "opacity 0.4s ease",
|
|
96
|
+
})}
|
|
97
|
+
/>
|
|
98
|
+
)}
|
|
99
|
+
<circle
|
|
100
|
+
cx="80" cy="80" r={R}
|
|
101
|
+
fill="none"
|
|
102
|
+
stroke="#e5e7eb"
|
|
103
|
+
strokeWidth="10"
|
|
104
|
+
/>
|
|
105
|
+
<circle
|
|
106
|
+
cx="80" cy="80" r={R}
|
|
107
|
+
fill="none"
|
|
108
|
+
stroke={g.color}
|
|
109
|
+
strokeWidth="10"
|
|
110
|
+
strokeLinecap="round"
|
|
111
|
+
strokeDasharray={CIRC}
|
|
112
|
+
strokeDashoffset={offset}
|
|
113
|
+
transform="rotate(-90 80 80)"
|
|
114
|
+
/>
|
|
115
|
+
</svg>
|
|
116
|
+
<div style={{
|
|
117
|
+
position: "absolute", top: 0, left: 0,
|
|
118
|
+
width: 160, height: 160,
|
|
119
|
+
display: "flex", alignItems: "center", justifyContent: "center",
|
|
120
|
+
fontSize: 32, fontWeight: 900, color: g.color,
|
|
121
|
+
fontVariantNumeric: "tabular-nums",
|
|
122
|
+
}}>
|
|
123
|
+
{displayNum}{g.suffix}
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
<div style={{ fontSize: 14, fontWeight: 700, color: "#374151", marginTop: 8 }}>
|
|
127
|
+
{g.label}
|
|
128
|
+
</div>
|
|
129
|
+
<div style={Object.assign({
|
|
130
|
+
fontSize: 14, color: "#9ca3af", marginTop: 6,
|
|
131
|
+
}, vis(step, 2, instant))}>
|
|
132
|
+
vs. {g.baseline}
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
);
|
|
136
|
+
})}
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<div style={Object.assign({
|
|
140
|
+
marginTop: 18, fontSize: 14, color: "#9ca3af",
|
|
141
|
+
}, vis(step, 2, instant))}>
|
|
142
|
+
vs. best baseline: 78.3% / 71.2% / 74.5% / 3x
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
<style>{
|
|
146
|
+
"@keyframes arcPulse {" +
|
|
147
|
+
"0%,100% { opacity: 0.25; transform: scale(0.98); }" +
|
|
148
|
+
"50% { opacity: 0.8; transform: scale(1.02); }" +
|
|
149
|
+
"}"
|
|
150
|
+
}</style>
|
|
151
|
+
</div>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { X, Check, ArrowRight } from "lucide-react";
|
|
3
|
+
import { CANVAS, useRevealStep, vis } from "../../../core/presets.ts";
|
|
4
|
+
import type { SlideComponentProps } from "../../../core/types.ts";
|
|
5
|
+
|
|
6
|
+
const PAIRS = [
|
|
7
|
+
{ before: "Manual log analysis", after: "Automated trace parsing" },
|
|
8
|
+
{ before: "30+ min mean time to detect", after: "4.2 min detection (7x faster)" },
|
|
9
|
+
{ before: "Single-metric alerting", after: "Multi-signal correlation" },
|
|
10
|
+
{ before: "Expert-dependent diagnosis", after: "ML-driven root cause ranking" },
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
const RED = "#dc2626";
|
|
14
|
+
const GREEN = "#16a34a";
|
|
15
|
+
const ROW_TOP = 150;
|
|
16
|
+
const ROW_GAP = 78;
|
|
17
|
+
|
|
18
|
+
export default function DemoBeforeAfter({ Reveal }: SlideComponentProps) {
|
|
19
|
+
const ref = useRevealStep(Reveal);
|
|
20
|
+
const step = ref[0], ready = ref[1], instant = ref[2];
|
|
21
|
+
|
|
22
|
+
const trans = function (extra?: string) {
|
|
23
|
+
return instant ? "none" : (extra || "opacity 0.5s ease, transform 0.5s ease");
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div style={{
|
|
28
|
+
position: "relative", width: "100%", height: "100%",
|
|
29
|
+
overflow: "hidden", fontFamily: CANVAS.fontFamily,
|
|
30
|
+
opacity: ready ? 1 : 0, transition: "opacity 0.2s ease",
|
|
31
|
+
}}>
|
|
32
|
+
{/* Left panel: Before (red), clipped to a 5-degree diagonal on its right edge */}
|
|
33
|
+
<div style={{
|
|
34
|
+
position: "absolute", inset: 0,
|
|
35
|
+
background: "#fef2f2",
|
|
36
|
+
clipPath: "polygon(0 0, 53% 0, 47% 100%, 0 100%)",
|
|
37
|
+
opacity: vis(step, 0, instant).opacity,
|
|
38
|
+
transition: trans("opacity 0.5s ease"),
|
|
39
|
+
}} />
|
|
40
|
+
|
|
41
|
+
{/* Right panel: After (green), slides in from the right */}
|
|
42
|
+
<div style={{
|
|
43
|
+
position: "absolute", inset: 0,
|
|
44
|
+
background: "#f0fdf4",
|
|
45
|
+
clipPath: "polygon(53% 0, 100% 0, 100% 100%, 47% 100%)",
|
|
46
|
+
opacity: step >= 1 ? 1 : 0,
|
|
47
|
+
transform: step >= 1 ? "translateX(0)" : "translateX(60px)",
|
|
48
|
+
transition: trans(),
|
|
49
|
+
}} />
|
|
50
|
+
|
|
51
|
+
{/* Diagonal divider line */}
|
|
52
|
+
<svg viewBox="0 0 1200 560" preserveAspectRatio="none" style={{
|
|
53
|
+
position: "absolute", inset: 0, width: "100%", height: "100%",
|
|
54
|
+
pointerEvents: "none",
|
|
55
|
+
opacity: step >= 1 ? 1 : 0,
|
|
56
|
+
transition: trans("opacity 0.5s ease"),
|
|
57
|
+
}}>
|
|
58
|
+
<line x1="636" y1="0" x2="564" y2="560" stroke="#94a3b8" strokeWidth="3" />
|
|
59
|
+
</svg>
|
|
60
|
+
|
|
61
|
+
{/* Left header */}
|
|
62
|
+
<div style={{
|
|
63
|
+
position: "absolute", top: 48, left: 70,
|
|
64
|
+
display: "flex", alignItems: "center", gap: 14,
|
|
65
|
+
opacity: vis(step, 0, instant).opacity,
|
|
66
|
+
transition: trans("opacity 0.5s ease"),
|
|
67
|
+
}}>
|
|
68
|
+
<div style={{
|
|
69
|
+
width: 48, height: 48, borderRadius: 12, background: RED,
|
|
70
|
+
display: "flex", alignItems: "center", justifyContent: "center",
|
|
71
|
+
}}>
|
|
72
|
+
<X size={30} color="#fff" strokeWidth={3} />
|
|
73
|
+
</div>
|
|
74
|
+
<span style={{ fontSize: 38, fontWeight: 900, color: RED, letterSpacing: 0.5 }}>Before</span>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
{/* Right header */}
|
|
78
|
+
<div style={{
|
|
79
|
+
position: "absolute", top: 48, right: 70,
|
|
80
|
+
display: "flex", alignItems: "center", gap: 14,
|
|
81
|
+
opacity: step >= 1 ? 1 : 0,
|
|
82
|
+
transform: step >= 1 ? "translateX(0)" : "translateX(60px)",
|
|
83
|
+
transition: trans(),
|
|
84
|
+
}}>
|
|
85
|
+
<span style={{ fontSize: 38, fontWeight: 900, color: GREEN, letterSpacing: 0.5 }}>After</span>
|
|
86
|
+
<div style={{
|
|
87
|
+
width: 48, height: 48, borderRadius: 12, background: GREEN,
|
|
88
|
+
display: "flex", alignItems: "center", justifyContent: "center",
|
|
89
|
+
}}>
|
|
90
|
+
<Check size={30} color="#fff" strokeWidth={3} />
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
{/* Rows */}
|
|
95
|
+
{PAIRS.map(function (p, i) {
|
|
96
|
+
const y = ROW_TOP + i * ROW_GAP;
|
|
97
|
+
return (
|
|
98
|
+
<React.Fragment key={i}>
|
|
99
|
+
{/* Left item */}
|
|
100
|
+
<div style={{
|
|
101
|
+
position: "absolute", left: 70, top: y, width: 430,
|
|
102
|
+
display: "flex", alignItems: "center", gap: 14,
|
|
103
|
+
opacity: vis(step, 0, instant).opacity,
|
|
104
|
+
transition: trans("opacity 0.5s ease"),
|
|
105
|
+
}}>
|
|
106
|
+
<span style={{
|
|
107
|
+
flex: "0 0 auto", width: 12, height: 12, borderRadius: "50%", background: RED,
|
|
108
|
+
}} />
|
|
109
|
+
<span style={{ fontSize: 23, fontWeight: 700, color: "#7f1d1d", lineHeight: 1.2 }}>
|
|
110
|
+
{p.before}
|
|
111
|
+
</span>
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
{/* Connecting arrow */}
|
|
115
|
+
<div style={{
|
|
116
|
+
position: "absolute", left: 540, top: y - 4, width: 120,
|
|
117
|
+
display: "flex", alignItems: "center", justifyContent: "center",
|
|
118
|
+
opacity: step >= 2 ? 1 : 0,
|
|
119
|
+
transform: step >= 2 ? "translateX(0)" : "translateX(-20px)",
|
|
120
|
+
transition: trans(),
|
|
121
|
+
}}>
|
|
122
|
+
<ArrowRight size={34} color="#475569" strokeWidth={2.5} />
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
{/* Right item */}
|
|
126
|
+
<div style={{
|
|
127
|
+
position: "absolute", right: 70, top: y, width: 430,
|
|
128
|
+
display: "flex", alignItems: "center", justifyContent: "flex-end", gap: 14,
|
|
129
|
+
textAlign: "right",
|
|
130
|
+
opacity: step >= 1 ? 1 : 0,
|
|
131
|
+
transform: step >= 1 ? "translateX(0)" : "translateX(60px)",
|
|
132
|
+
transition: trans(),
|
|
133
|
+
}}>
|
|
134
|
+
<span style={{ fontSize: 23, fontWeight: 700, color: "#14532d", lineHeight: 1.2 }}>
|
|
135
|
+
{p.after}
|
|
136
|
+
</span>
|
|
137
|
+
<span style={{
|
|
138
|
+
flex: "0 0 auto", width: 12, height: 12, borderRadius: "50%", background: GREEN,
|
|
139
|
+
}} />
|
|
140
|
+
</div>
|
|
141
|
+
</React.Fragment>
|
|
142
|
+
);
|
|
143
|
+
})}
|
|
144
|
+
|
|
145
|
+
{/* Bottom banner */}
|
|
146
|
+
<div style={{
|
|
147
|
+
position: "absolute", left: "50%", bottom: 30,
|
|
148
|
+
transform: step >= 3
|
|
149
|
+
? "translateX(-50%) translateY(0)"
|
|
150
|
+
: "translateX(-50%) translateY(30px)",
|
|
151
|
+
opacity: step >= 3 ? 1 : 0,
|
|
152
|
+
transition: trans(),
|
|
153
|
+
padding: "16px 44px", borderRadius: 14,
|
|
154
|
+
background: "linear-gradient(90deg, #dc2626 0%, #16a34a 100%)",
|
|
155
|
+
boxShadow: "0 8px 28px rgba(0,0,0,0.22)",
|
|
156
|
+
whiteSpace: "nowrap",
|
|
157
|
+
}}>
|
|
158
|
+
<span style={{ fontSize: 26, fontWeight: 900, color: "#fff", letterSpacing: 0.3 }}>
|
|
159
|
+
SRCA bridges this gap automatically
|
|
160
|
+
</span>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { SlideComponentProps } from "../../../core/types.ts";
|
|
3
|
+
import { CANVAS, vis, useRevealStep } from "../../../core/presets.ts";
|
|
4
|
+
|
|
5
|
+
export default function DemoBigText({ Reveal }: SlideComponentProps) {
|
|
6
|
+
const ref = useRevealStep(Reveal);
|
|
7
|
+
const step = ref[0], ready = ref[1], instant = ref[2];
|
|
8
|
+
const numRef = React.useRef<HTMLDivElement>(null);
|
|
9
|
+
|
|
10
|
+
React.useEffect(function () {
|
|
11
|
+
if (!ready || step < 0) return;
|
|
12
|
+
const anime = (window as any).anime;
|
|
13
|
+
const el = numRef.current;
|
|
14
|
+
if (!el) return;
|
|
15
|
+
if (instant || !anime || !anime.animate) {
|
|
16
|
+
el.style.transform = "scale(1)";
|
|
17
|
+
el.style.opacity = "1";
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
anime.animate(el, {
|
|
21
|
+
scale: [0.9, 1],
|
|
22
|
+
opacity: [0, 1],
|
|
23
|
+
duration: 700,
|
|
24
|
+
ease: "spring(1, 80, 12, 0)",
|
|
25
|
+
});
|
|
26
|
+
}, [ready, instant]);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div style={{
|
|
30
|
+
width: "100%", height: "100%", boxSizing: "border-box",
|
|
31
|
+
background: "#ffffff", fontFamily: CANVAS.fontFamily,
|
|
32
|
+
display: "flex", flexDirection: "column",
|
|
33
|
+
alignItems: "center", justifyContent: "center",
|
|
34
|
+
opacity: ready ? 1 : 0, transition: "opacity 0.2s ease",
|
|
35
|
+
}}>
|
|
36
|
+
<div
|
|
37
|
+
ref={numRef}
|
|
38
|
+
style={{
|
|
39
|
+
fontSize: 120, fontWeight: 800, color: "#4361ee",
|
|
40
|
+
lineHeight: 1, letterSpacing: -2,
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
94.2%
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div style={{
|
|
47
|
+
marginTop: 28, fontSize: 28, fontWeight: 300, color: "#8b8b8b",
|
|
48
|
+
letterSpacing: 0.3, textAlign: "center",
|
|
49
|
+
...vis(step, 1, instant),
|
|
50
|
+
}}>
|
|
51
|
+
Top-1 accuracy on 3 benchmark suites
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div style={{
|
|
55
|
+
marginTop: 48, display: "flex", flexDirection: "column",
|
|
56
|
+
alignItems: "center", gap: 14,
|
|
57
|
+
...vis(step, 2, instant),
|
|
58
|
+
}}>
|
|
59
|
+
<div style={{ width: 200, height: 1, background: "#d8d8d8" }} />
|
|
60
|
+
<div style={{
|
|
61
|
+
fontSize: 17, fontWeight: 400, color: "#9a9a9a",
|
|
62
|
+
display: "flex", alignItems: "baseline", gap: 12,
|
|
63
|
+
}}>
|
|
64
|
+
<span>vs. 78.3% best baseline</span>
|
|
65
|
+
<span style={{ color: "#2e9e5b", fontWeight: 700 }}>+15.9%</span>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Zap, Shield, Layers } from "lucide-react";
|
|
3
|
+
import { CANVAS, useRevealStep } from "../../../core/presets.ts";
|
|
4
|
+
import type { SlideComponentProps } from "../../../core/types.ts";
|
|
5
|
+
|
|
6
|
+
const CARDS = [
|
|
7
|
+
{ Icon: Zap, title: "Speed", subtitle: "Fast by default", stat: "12ms", desc: "Sub-frame response times keep every interaction instant and fluid." },
|
|
8
|
+
{ Icon: Shield, title: "Security", subtitle: "Locked down", stat: "0 CVE", desc: "End-to-end encryption and zero open vulnerabilities across the stack." },
|
|
9
|
+
{ Icon: Layers, title: "Scale", subtitle: "Grows with you", stat: "10x", desc: "Horizontal scaling absorbs traffic spikes without a redeploy." },
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
export default function DemoCardFlip({ Reveal }: SlideComponentProps) {
|
|
13
|
+
const ref = useRevealStep(Reveal);
|
|
14
|
+
const step = ref[0], ready = ref[1], instant = ref[2];
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div
|
|
18
|
+
style={{
|
|
19
|
+
width: "100%",
|
|
20
|
+
height: "100%",
|
|
21
|
+
display: "flex",
|
|
22
|
+
alignItems: "center",
|
|
23
|
+
justifyContent: "center",
|
|
24
|
+
gap: 40,
|
|
25
|
+
fontFamily: CANVAS.fontFamily,
|
|
26
|
+
opacity: ready ? 1 : 0,
|
|
27
|
+
transition: "opacity 0.2s ease",
|
|
28
|
+
}}
|
|
29
|
+
>
|
|
30
|
+
{CARDS.map(function (card, i) {
|
|
31
|
+
const flipped = step >= i;
|
|
32
|
+
const Icon = card.Icon;
|
|
33
|
+
return (
|
|
34
|
+
<div
|
|
35
|
+
key={i}
|
|
36
|
+
style={{
|
|
37
|
+
width: 280,
|
|
38
|
+
height: 350,
|
|
39
|
+
perspective: 1200,
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
42
|
+
<div
|
|
43
|
+
style={{
|
|
44
|
+
position: "relative",
|
|
45
|
+
width: "100%",
|
|
46
|
+
height: "100%",
|
|
47
|
+
transformStyle: "preserve-3d",
|
|
48
|
+
transform: flipped ? "rotateY(180deg)" : "rotateY(0deg)",
|
|
49
|
+
transition: instant ? "none" : "transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1)",
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
{/* Front */}
|
|
53
|
+
<div
|
|
54
|
+
style={{
|
|
55
|
+
position: "absolute",
|
|
56
|
+
inset: 0,
|
|
57
|
+
backfaceVisibility: "hidden",
|
|
58
|
+
WebkitBackfaceVisibility: "hidden",
|
|
59
|
+
borderRadius: 16,
|
|
60
|
+
background: "#fff",
|
|
61
|
+
boxShadow: "0 12px 32px rgba(49,49,49,0.16)",
|
|
62
|
+
display: "flex",
|
|
63
|
+
flexDirection: "column",
|
|
64
|
+
alignItems: "center",
|
|
65
|
+
justifyContent: "center",
|
|
66
|
+
gap: 18,
|
|
67
|
+
}}
|
|
68
|
+
>
|
|
69
|
+
<div
|
|
70
|
+
style={{
|
|
71
|
+
width: 96,
|
|
72
|
+
height: 96,
|
|
73
|
+
borderRadius: "50%",
|
|
74
|
+
background: "#eef1ff",
|
|
75
|
+
display: "flex",
|
|
76
|
+
alignItems: "center",
|
|
77
|
+
justifyContent: "center",
|
|
78
|
+
}}
|
|
79
|
+
>
|
|
80
|
+
<Icon size={52} color="#4361ee" strokeWidth={2} />
|
|
81
|
+
</div>
|
|
82
|
+
<div style={{ fontSize: 30, fontWeight: 900, color: "#1d3557" }}>{card.title}</div>
|
|
83
|
+
<div style={{ fontSize: 16, fontWeight: 600, color: "#767676" }}>{card.subtitle}</div>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
{/* Back */}
|
|
87
|
+
<div
|
|
88
|
+
style={{
|
|
89
|
+
position: "absolute",
|
|
90
|
+
inset: 0,
|
|
91
|
+
backfaceVisibility: "hidden",
|
|
92
|
+
WebkitBackfaceVisibility: "hidden",
|
|
93
|
+
transform: "rotateY(180deg)",
|
|
94
|
+
borderRadius: 16,
|
|
95
|
+
background: "linear-gradient(145deg, #4361ee, #3a0ca3)",
|
|
96
|
+
boxShadow: "0 12px 32px rgba(58,12,163,0.32)",
|
|
97
|
+
color: "#fff",
|
|
98
|
+
display: "flex",
|
|
99
|
+
flexDirection: "column",
|
|
100
|
+
alignItems: "center",
|
|
101
|
+
justifyContent: "center",
|
|
102
|
+
gap: 16,
|
|
103
|
+
padding: "0 28px",
|
|
104
|
+
boxSizing: "border-box",
|
|
105
|
+
textAlign: "center",
|
|
106
|
+
}}
|
|
107
|
+
>
|
|
108
|
+
<div style={{ fontSize: 52, fontWeight: 900, lineHeight: 1 }}>{card.stat}</div>
|
|
109
|
+
<div style={{ fontSize: 22, fontWeight: 800 }}>{card.title}</div>
|
|
110
|
+
<div style={{ fontSize: 16, fontWeight: 500, lineHeight: 1.5, opacity: 0.92 }}>{card.desc}</div>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
})}
|
|
116
|
+
</div>
|
|
117
|
+
);
|
|
118
|
+
}
|