@devrongx/games 0.4.44 → 0.4.46
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/package.json
CHANGED
|
@@ -252,34 +252,34 @@ const deriveDemoData = (config: IChallengeConfig) => {
|
|
|
252
252
|
return { marketA, marketB, marketC, optIdxA, optIdxB, optionA, optionB, betA, betB, chips, rewardA, rewardB, combinedStake, combinedOdds, combinedReward };
|
|
253
253
|
};
|
|
254
254
|
|
|
255
|
-
// ── Slide 3: Markets demo —
|
|
255
|
+
// ── Slide 3: Markets demo — two questions with full bet flow ──
|
|
256
256
|
const MarketsSlide = ({ config }: SlideProps) => {
|
|
257
257
|
const demo = useMemo(() => deriveDemoData(config), [config]);
|
|
258
258
|
const [demoStep, setDemoStep] = useState(0);
|
|
259
259
|
|
|
260
260
|
useEffect(() => {
|
|
261
261
|
const timers = [
|
|
262
|
-
setTimeout(() => setDemoStep(1),
|
|
263
|
-
setTimeout(() => setDemoStep(2),
|
|
264
|
-
setTimeout(() => setDemoStep(3),
|
|
265
|
-
setTimeout(() => setDemoStep(4),
|
|
266
|
-
setTimeout(() => setDemoStep(5),
|
|
267
|
-
setTimeout(() => setDemoStep(6),
|
|
268
|
-
setTimeout(() => setDemoStep(7),
|
|
262
|
+
setTimeout(() => setDemoStep(1), 800), // Card 1 appears
|
|
263
|
+
setTimeout(() => setDemoStep(2), 2200), // Card 1 option selected
|
|
264
|
+
setTimeout(() => setDemoStep(3), 3200), // Card 1 chips appear (none selected)
|
|
265
|
+
setTimeout(() => setDemoStep(4), 4400), // Card 1 chip selected (1200ms gap)
|
|
266
|
+
setTimeout(() => setDemoStep(5), 5200), // Card 1 outcome, chips collapse
|
|
267
|
+
setTimeout(() => setDemoStep(6), 6200), // Card 2 appears
|
|
268
|
+
setTimeout(() => setDemoStep(7), 7400), // Card 2 option selected
|
|
269
|
+
setTimeout(() => setDemoStep(8), 8400), // Card 2 chips appear (none selected)
|
|
270
|
+
setTimeout(() => setDemoStep(9), 9600), // Card 2 chip selected (1200ms gap)
|
|
271
|
+
setTimeout(() => setDemoStep(10), 10400), // Card 2 outcome, chips collapse
|
|
269
272
|
];
|
|
270
273
|
return () => timers.forEach(clearTimeout);
|
|
271
274
|
}, []);
|
|
272
275
|
|
|
273
|
-
const { marketA, marketB,
|
|
276
|
+
const { marketA, marketB, optIdxA, optIdxB, optionA, optionB, betA, betB, chips, rewardA, rewardB } = demo;
|
|
274
277
|
const IconA = MARKET_ICONS[marketA.icon];
|
|
275
278
|
const IconB = MARKET_ICONS[marketB.icon];
|
|
276
|
-
const IconC = MARKET_ICONS[marketC.icon];
|
|
277
|
-
|
|
278
|
-
const card1Compressed = demoStep >= 5;
|
|
279
279
|
|
|
280
|
-
// Shared option renderer
|
|
280
|
+
// Shared option renderer
|
|
281
281
|
const renderOptionsGrid = (market: typeof marketA, selectedOptIdx: number | null) => (
|
|
282
|
-
<div className="grid grid-cols-2 gap-
|
|
282
|
+
<div className="grid grid-cols-2 gap-2">
|
|
283
283
|
{market.options.map((opt, j) => {
|
|
284
284
|
const isSelected = selectedOptIdx !== null && j === selectedOptIdx;
|
|
285
285
|
return (
|
|
@@ -315,7 +315,7 @@ const MarketsSlide = ({ config }: SlideProps) => {
|
|
|
315
315
|
</div>
|
|
316
316
|
);
|
|
317
317
|
|
|
318
|
-
//
|
|
318
|
+
// Chip carousel — selectedAmt of -1 means none selected
|
|
319
319
|
const renderChips = (selectedAmt: number) => (
|
|
320
320
|
<motion.div
|
|
321
321
|
initial={{ opacity: 0, height: 0 }}
|
|
@@ -326,7 +326,7 @@ const MarketsSlide = ({ config }: SlideProps) => {
|
|
|
326
326
|
>
|
|
327
327
|
<span className="text-[8px] text-white/60 font-semibold flex-shrink-0" style={OUTFIT}>Bet:</span>
|
|
328
328
|
{chips.map((amt, i) => {
|
|
329
|
-
const isChipSelected = amt === selectedAmt;
|
|
329
|
+
const isChipSelected = selectedAmt > 0 && amt === selectedAmt;
|
|
330
330
|
return (
|
|
331
331
|
<motion.div
|
|
332
332
|
key={amt}
|
|
@@ -349,7 +349,7 @@ const MarketsSlide = ({ config }: SlideProps) => {
|
|
|
349
349
|
</motion.div>
|
|
350
350
|
);
|
|
351
351
|
|
|
352
|
-
//
|
|
352
|
+
// Outcome line
|
|
353
353
|
const renderOutcome = (bet: number, odds: number, reward: number) => (
|
|
354
354
|
<motion.div
|
|
355
355
|
initial={{ opacity: 0, y: 4 }}
|
|
@@ -361,7 +361,7 @@ const MarketsSlide = ({ config }: SlideProps) => {
|
|
|
361
361
|
<span className="text-[9px] text-white font-semibold" style={OUTFIT}>{bet}</span>
|
|
362
362
|
<span className="text-[8px] text-white" style={OUTFIT}>×</span>
|
|
363
363
|
<span className="text-[9px] text-white/60 font-semibold" style={OUTFIT}>{odds}</span>
|
|
364
|
-
<span className="text-[8px] text-white/
|
|
364
|
+
<span className="text-[8px] text-white/50" style={OUTFIT}>{"\u2192"}</span>
|
|
365
365
|
<PointsIcon size={7} />
|
|
366
366
|
<span className="text-[9px] text-[#22E3E8] font-bold" style={OUTFIT}>{reward}</span>
|
|
367
367
|
</motion.div>
|
|
@@ -369,7 +369,7 @@ const MarketsSlide = ({ config }: SlideProps) => {
|
|
|
369
369
|
|
|
370
370
|
return (
|
|
371
371
|
<motion.div
|
|
372
|
-
className="flex flex-col items-center gap-
|
|
372
|
+
className="flex flex-col items-center gap-3 w-full max-w-[300px]"
|
|
373
373
|
initial="initial"
|
|
374
374
|
animate="animate"
|
|
375
375
|
exit="exit"
|
|
@@ -385,149 +385,101 @@ const MarketsSlide = ({ config }: SlideProps) => {
|
|
|
385
385
|
{config.markets.length} questions to predict
|
|
386
386
|
</motion.p>
|
|
387
387
|
|
|
388
|
-
{/*
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
{/* Card 1 */}
|
|
397
|
-
<div
|
|
398
|
-
className="w-full rounded-lg px-3 py-2.5"
|
|
388
|
+
{/* Card 1 — always expanded */}
|
|
389
|
+
<AnimatePresence>
|
|
390
|
+
{demoStep >= 1 && (
|
|
391
|
+
<motion.div
|
|
392
|
+
initial={{ opacity: 0, y: 20 }}
|
|
393
|
+
animate={{ opacity: 1, y: 0 }}
|
|
394
|
+
transition={{ duration: 0.5 }}
|
|
395
|
+
className="w-full rounded-lg px-3 py-3"
|
|
399
396
|
style={{
|
|
400
397
|
background: "rgba(255,255,255,0.03)",
|
|
401
398
|
border: "1px solid rgba(255,255,255,0.08)",
|
|
402
399
|
}}
|
|
403
400
|
>
|
|
404
|
-
<div className="flex items-center gap-2 mb-
|
|
401
|
+
<div className="flex items-center gap-2 mb-2">
|
|
405
402
|
{IconA && <IconA size={14} style={{ color: marketA.accent }} className="flex-shrink-0" />}
|
|
406
|
-
<span className=
|
|
403
|
+
<span className="text-[13px] text-white font-semibold leading-tight" style={OUTFIT}>
|
|
407
404
|
{marketA.question}
|
|
408
405
|
</span>
|
|
409
406
|
</div>
|
|
410
407
|
|
|
411
|
-
{
|
|
412
|
-
<>
|
|
413
|
-
{renderOptionsGrid(marketA, demoStep >= 2 ? optIdxA : null)}
|
|
414
|
-
<AnimatePresence>
|
|
415
|
-
{demoStep >= 3 && demoStep < 5 && renderChips(betA)}
|
|
416
|
-
</AnimatePresence>
|
|
417
|
-
</>
|
|
418
|
-
) : (
|
|
419
|
-
<div className="flex items-center gap-1.5">
|
|
420
|
-
<svg width="10" height="10" viewBox="0 0 16 16" fill="none">
|
|
421
|
-
<circle cx="8" cy="8" r="8" fill="white" />
|
|
422
|
-
<path d="M5 8l2 2 4-4" stroke="#9945FF" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
|
423
|
-
</svg>
|
|
424
|
-
<span className="text-[10px] text-white font-semibold" style={OUTFIT}>{optionA.label}</span>
|
|
425
|
-
<span className="text-[9px] text-white/40 font-semibold" style={OUTFIT}>{optionA.odds}x</span>
|
|
426
|
-
</div>
|
|
427
|
-
)}
|
|
408
|
+
{renderOptionsGrid(marketA, demoStep >= 2 ? optIdxA : null)}
|
|
428
409
|
|
|
429
|
-
|
|
430
|
-
|
|
410
|
+
<AnimatePresence>
|
|
411
|
+
{demoStep >= 3 && demoStep < 5 && renderChips(demoStep >= 4 ? betA : -1)}
|
|
412
|
+
</AnimatePresence>
|
|
431
413
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
414
|
+
{demoStep >= 5 && renderOutcome(betA, optionA.odds, rewardA)}
|
|
415
|
+
</motion.div>
|
|
416
|
+
)}
|
|
417
|
+
</AnimatePresence>
|
|
418
|
+
|
|
419
|
+
{/* Card 2 — always expanded */}
|
|
420
|
+
<AnimatePresence>
|
|
421
|
+
{demoStep >= 6 && (
|
|
422
|
+
<motion.div
|
|
423
|
+
initial={{ opacity: 0, y: 20 }}
|
|
424
|
+
animate={{ opacity: 1, y: 0 }}
|
|
425
|
+
transition={{ duration: 0.5 }}
|
|
426
|
+
className="w-full rounded-lg px-3 py-3"
|
|
435
427
|
style={{
|
|
436
428
|
background: "rgba(255,255,255,0.03)",
|
|
437
429
|
border: "1px solid rgba(255,255,255,0.08)",
|
|
438
430
|
}}
|
|
439
431
|
>
|
|
440
|
-
<div className="flex items-center gap-2 mb-
|
|
432
|
+
<div className="flex items-center gap-2 mb-2">
|
|
441
433
|
{IconB && <IconB size={14} style={{ color: marketB.accent }} className="flex-shrink-0" />}
|
|
442
434
|
<span className="text-[13px] text-white font-semibold leading-tight" style={OUTFIT}>
|
|
443
435
|
{marketB.question}
|
|
444
436
|
</span>
|
|
445
437
|
</div>
|
|
446
438
|
|
|
447
|
-
{renderOptionsGrid(marketB, demoStep >=
|
|
439
|
+
{renderOptionsGrid(marketB, demoStep >= 7 ? optIdxB : null)}
|
|
448
440
|
|
|
449
441
|
<AnimatePresence>
|
|
450
|
-
{demoStep >=
|
|
442
|
+
{demoStep >= 8 && demoStep < 10 && renderChips(demoStep >= 9 ? betB : -1)}
|
|
451
443
|
</AnimatePresence>
|
|
452
444
|
|
|
453
|
-
{demoStep >=
|
|
454
|
-
</div>
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
<div
|
|
458
|
-
className="w-full rounded-lg px-3 py-2.5"
|
|
459
|
-
style={{
|
|
460
|
-
background: "rgba(255,255,255,0.03)",
|
|
461
|
-
border: "1px solid rgba(255,255,255,0.08)",
|
|
462
|
-
opacity: demoStep >= 2 ? 0.5 : 1,
|
|
463
|
-
transition: "opacity 0.5s",
|
|
464
|
-
}}
|
|
465
|
-
>
|
|
466
|
-
<div className="flex items-center gap-2 mb-1.5">
|
|
467
|
-
{IconC && <IconC size={14} style={{ color: marketC.accent }} className="flex-shrink-0" />}
|
|
468
|
-
<span className="text-[13px] text-white font-semibold leading-tight" style={OUTFIT}>
|
|
469
|
-
{marketC.question}
|
|
470
|
-
</span>
|
|
471
|
-
</div>
|
|
472
|
-
{renderOptionsGrid(marketC, null)}
|
|
473
|
-
</div>
|
|
474
|
-
</motion.div>
|
|
475
|
-
)}
|
|
445
|
+
{demoStep >= 10 && renderOutcome(betB, optionB.odds, rewardB)}
|
|
446
|
+
</motion.div>
|
|
447
|
+
)}
|
|
448
|
+
</AnimatePresence>
|
|
476
449
|
</motion.div>
|
|
477
450
|
);
|
|
478
451
|
};
|
|
479
452
|
|
|
480
|
-
// ── Slide 4: Compound bet demo ──
|
|
453
|
+
// ── Slide 4: Compound bet demo — 3 full cards, 2 combined ──
|
|
481
454
|
const MultiplierSlide = ({ config }: SlideProps) => {
|
|
482
455
|
const demo = useMemo(() => deriveDemoData(config), [config]);
|
|
483
456
|
const [step, setStep] = useState(0);
|
|
484
457
|
|
|
485
458
|
useEffect(() => {
|
|
486
459
|
const timers = [
|
|
487
|
-
setTimeout(() => setStep(1), 300),
|
|
488
|
-
setTimeout(() => setStep(2), 1200),
|
|
489
|
-
setTimeout(() => setStep(3), 3000),
|
|
490
|
-
setTimeout(() => setStep(4), 4200),
|
|
491
|
-
setTimeout(() => setStep(5), 5200),
|
|
492
|
-
setTimeout(() => setStep(6), 6500),
|
|
460
|
+
setTimeout(() => setStep(1), 300), // Headline
|
|
461
|
+
setTimeout(() => setStep(2), 1200), // 3 full cards appear
|
|
462
|
+
setTimeout(() => setStep(3), 3000), // Card 1 highlights, outcome fades out
|
|
463
|
+
setTimeout(() => setStep(4), 4200), // Card 2 highlights, outcome fades out
|
|
464
|
+
setTimeout(() => setStep(5), 5200), // Combined outcome line
|
|
465
|
+
setTimeout(() => setStep(6), 6500), // Payoff text
|
|
493
466
|
];
|
|
494
467
|
return () => timers.forEach(clearTimeout);
|
|
495
468
|
}, []);
|
|
496
469
|
|
|
497
|
-
const { marketA, marketB, optionA, optionB, betA, betB, rewardA, rewardB, combinedStake,
|
|
470
|
+
const { marketA, marketB, marketC, optionA, optionB, betA, betB, rewardA, rewardB, combinedStake, combinedReward } = demo;
|
|
498
471
|
const IconA = MARKET_ICONS[marketA.icon];
|
|
499
472
|
const IconB = MARKET_ICONS[marketB.icon];
|
|
473
|
+
const IconC = MARKET_ICONS[marketC.icon];
|
|
500
474
|
|
|
501
|
-
//
|
|
502
|
-
const
|
|
503
|
-
<div className="flex items-center gap-[5px]">
|
|
504
|
-
<PointsIcon size={10} />
|
|
505
|
-
<span className="text-[12px] text-white font-semibold" style={OUTFIT}>{bet}</span>
|
|
506
|
-
<span className="text-[11px] text-white font-medium" style={OUTFIT}>×</span>
|
|
507
|
-
{pulse ? (
|
|
508
|
-
<motion.span
|
|
509
|
-
className="text-[12px] text-white font-bold"
|
|
510
|
-
style={OUTFIT}
|
|
511
|
-
animate={{ scale: [1, 1.25, 1] }}
|
|
512
|
-
transition={{ duration: 0.5, delay: 0.2 }}
|
|
513
|
-
>
|
|
514
|
-
{odds}
|
|
515
|
-
</motion.span>
|
|
516
|
-
) : (
|
|
517
|
-
<span className="text-[12px] text-white font-bold" style={OUTFIT}>{odds}</span>
|
|
518
|
-
)}
|
|
519
|
-
<span className="text-[11px] text-white/50" style={OUTFIT}>{"\u2192"}</span>
|
|
520
|
-
<PointsIcon size={10} />
|
|
521
|
-
<span className="text-[12px] text-[#22E3E8] font-bold" style={OUTFIT}>{reward}</span>
|
|
522
|
-
</div>
|
|
523
|
-
);
|
|
524
|
-
|
|
525
|
-
const renderCompactCard = (
|
|
475
|
+
// Full expanded card with options grid — selected option highlighted
|
|
476
|
+
const renderFullCard = (
|
|
526
477
|
market: typeof marketA,
|
|
527
478
|
Icon: typeof IconA,
|
|
528
|
-
|
|
529
|
-
betAmount: number,
|
|
530
|
-
|
|
479
|
+
selectedOptIdx: number | null,
|
|
480
|
+
betAmount: number | null,
|
|
481
|
+
odds: number | null,
|
|
482
|
+
reward: number | null,
|
|
531
483
|
highlighted: boolean,
|
|
532
484
|
hideOutcome: boolean,
|
|
533
485
|
) => (
|
|
@@ -543,32 +495,60 @@ const MultiplierSlide = ({ config }: SlideProps) => {
|
|
|
543
495
|
border: "1px solid rgba(255,255,255,0.08)",
|
|
544
496
|
}}
|
|
545
497
|
>
|
|
546
|
-
<div className="flex items-center gap-
|
|
547
|
-
{Icon && <Icon size={
|
|
548
|
-
<span className="text-[
|
|
498
|
+
<div className="flex items-center gap-2 mb-1.5">
|
|
499
|
+
{Icon && <Icon size={14} style={{ color: market.accent }} className="flex-shrink-0" />}
|
|
500
|
+
<span className="text-[12px] text-white font-semibold leading-tight" style={OUTFIT}>{market.question}</span>
|
|
549
501
|
</div>
|
|
550
|
-
<div className="
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
502
|
+
<div className="grid grid-cols-2 gap-1.5">
|
|
503
|
+
{market.options.map((opt, j) => {
|
|
504
|
+
const isSelected = selectedOptIdx !== null && j === selectedOptIdx;
|
|
505
|
+
return (
|
|
506
|
+
<div
|
|
507
|
+
key={j}
|
|
508
|
+
className="flex items-center justify-between px-2 py-1 rounded-sm"
|
|
509
|
+
style={{
|
|
510
|
+
background: isSelected ? "linear-gradient(135deg, #22E3E8, #9945FF)" : "transparent",
|
|
511
|
+
borderLeft: isSelected ? "1px solid transparent" : "1px solid rgba(255,255,255,0.12)",
|
|
512
|
+
borderBottom: isSelected ? "1px solid transparent" : "1px solid rgba(255,255,255,0.06)",
|
|
513
|
+
borderTop: "1px solid transparent",
|
|
514
|
+
borderRight: "1px solid transparent",
|
|
515
|
+
}}
|
|
516
|
+
>
|
|
517
|
+
<div className="flex items-center gap-1 min-w-0 flex-shrink">
|
|
518
|
+
{isSelected && (
|
|
519
|
+
<svg width="8" height="8" viewBox="0 0 16 16" fill="none">
|
|
520
|
+
<circle cx="8" cy="8" r="8" fill="white" />
|
|
521
|
+
<path d="M5 8l2 2 4-4" stroke="#9945FF" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
|
522
|
+
</svg>
|
|
523
|
+
)}
|
|
524
|
+
<span className="text-[9px] text-white font-semibold truncate" style={OUTFIT}>{opt.label}</span>
|
|
525
|
+
</div>
|
|
526
|
+
<span className={`text-[9px] font-bold flex-shrink-0 ${isSelected ? "text-white" : "text-[#22E3E8]"}`} style={OUTFIT}>{opt.odds}x</span>
|
|
527
|
+
</div>
|
|
528
|
+
);
|
|
529
|
+
})}
|
|
558
530
|
</div>
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
531
|
+
{betAmount !== null && odds !== null && reward !== null && (
|
|
532
|
+
<motion.div
|
|
533
|
+
className="flex items-center gap-[4px] mt-1.5 overflow-hidden"
|
|
534
|
+
animate={{ opacity: hideOutcome ? 0 : 1, height: hideOutcome ? 0 : "auto" }}
|
|
535
|
+
transition={{ duration: 0.3 }}
|
|
536
|
+
>
|
|
537
|
+
<PointsIcon size={8} />
|
|
538
|
+
<span className="text-[10px] text-white font-semibold" style={OUTFIT}>{betAmount}</span>
|
|
539
|
+
<span className="text-[9px] text-white" style={OUTFIT}>×</span>
|
|
540
|
+
<span className="text-[10px] text-white font-bold" style={OUTFIT}>{odds}</span>
|
|
541
|
+
<span className="text-[9px] text-white/50" style={OUTFIT}>{"\u2192"}</span>
|
|
542
|
+
<PointsIcon size={8} />
|
|
543
|
+
<span className="text-[10px] text-[#22E3E8] font-bold" style={OUTFIT}>{reward}</span>
|
|
544
|
+
</motion.div>
|
|
545
|
+
)}
|
|
566
546
|
</motion.div>
|
|
567
547
|
);
|
|
568
548
|
|
|
569
549
|
return (
|
|
570
550
|
<motion.div
|
|
571
|
-
className="flex flex-col items-center gap-
|
|
551
|
+
className="flex flex-col items-center gap-2.5 w-full max-w-[300px]"
|
|
572
552
|
initial="initial"
|
|
573
553
|
animate="animate"
|
|
574
554
|
exit="exit"
|
|
@@ -586,7 +566,7 @@ const MultiplierSlide = ({ config }: SlideProps) => {
|
|
|
586
566
|
</motion.p>
|
|
587
567
|
)}
|
|
588
568
|
|
|
589
|
-
{/*
|
|
569
|
+
{/* 3 full expanded cards */}
|
|
590
570
|
{step >= 2 && (
|
|
591
571
|
<motion.div
|
|
592
572
|
initial={{ opacity: 0, y: 16 }}
|
|
@@ -594,8 +574,39 @@ const MultiplierSlide = ({ config }: SlideProps) => {
|
|
|
594
574
|
transition={{ duration: 0.5 }}
|
|
595
575
|
className="w-full flex flex-col gap-2"
|
|
596
576
|
>
|
|
597
|
-
{
|
|
598
|
-
{
|
|
577
|
+
{renderFullCard(marketA, IconA, demo.optIdxA, betA, optionA.odds, rewardA, step >= 3, step >= 3)}
|
|
578
|
+
{renderFullCard(marketB, IconB, demo.optIdxB, betB, optionB.odds, rewardB, step >= 4, step >= 4)}
|
|
579
|
+
{/* Card 3 — unselected, no bet */}
|
|
580
|
+
<div
|
|
581
|
+
className="w-full rounded-lg px-3 py-2.5"
|
|
582
|
+
style={{
|
|
583
|
+
background: "rgba(255,255,255,0.03)",
|
|
584
|
+
border: "1px solid rgba(255,255,255,0.08)",
|
|
585
|
+
opacity: 0.5,
|
|
586
|
+
}}
|
|
587
|
+
>
|
|
588
|
+
<div className="flex items-center gap-2 mb-1.5">
|
|
589
|
+
{IconC && <IconC size={14} style={{ color: marketC.accent }} className="flex-shrink-0" />}
|
|
590
|
+
<span className="text-[12px] text-white font-semibold leading-tight" style={OUTFIT}>{marketC.question}</span>
|
|
591
|
+
</div>
|
|
592
|
+
<div className="grid grid-cols-2 gap-1.5">
|
|
593
|
+
{marketC.options.map((opt, j) => (
|
|
594
|
+
<div
|
|
595
|
+
key={j}
|
|
596
|
+
className="flex items-center justify-between px-2 py-1 rounded-sm"
|
|
597
|
+
style={{
|
|
598
|
+
borderLeft: "1px solid rgba(255,255,255,0.12)",
|
|
599
|
+
borderBottom: "1px solid rgba(255,255,255,0.06)",
|
|
600
|
+
borderTop: "1px solid transparent",
|
|
601
|
+
borderRight: "1px solid transparent",
|
|
602
|
+
}}
|
|
603
|
+
>
|
|
604
|
+
<span className="text-[9px] text-white font-semibold truncate" style={OUTFIT}>{opt.label}</span>
|
|
605
|
+
<span className="text-[9px] font-bold text-[#22E3E8] flex-shrink-0" style={OUTFIT}>{opt.odds}x</span>
|
|
606
|
+
</div>
|
|
607
|
+
))}
|
|
608
|
+
</div>
|
|
609
|
+
</div>
|
|
599
610
|
</motion.div>
|
|
600
611
|
)}
|
|
601
612
|
|
|
@@ -647,10 +658,18 @@ const MultiplierSlide = ({ config }: SlideProps) => {
|
|
|
647
658
|
};
|
|
648
659
|
|
|
649
660
|
// Free leaderboard payouts: ranks 1-10, $25 down to $2.5 in $2.5 steps
|
|
650
|
-
const FREE_PAYOUTS =
|
|
651
|
-
rank:
|
|
652
|
-
|
|
653
|
-
}
|
|
661
|
+
const FREE_PAYOUTS = [
|
|
662
|
+
{ rank: 1, points: 4850, usdc: 25 },
|
|
663
|
+
{ rank: 2, points: 4200, usdc: 22.5 },
|
|
664
|
+
{ rank: 3, points: 3900, usdc: 20 },
|
|
665
|
+
{ rank: 4, points: 3400, usdc: 17.5 },
|
|
666
|
+
{ rank: 5, points: 2950, usdc: 15 },
|
|
667
|
+
{ rank: 6, points: 2600, usdc: 12.5 },
|
|
668
|
+
{ rank: 7, points: 2100, usdc: 10 },
|
|
669
|
+
{ rank: 8, points: 1750, usdc: 7.5 },
|
|
670
|
+
{ rank: 9, points: 1300, usdc: 5 },
|
|
671
|
+
{ rank: 10, points: 900, usdc: 2.5 },
|
|
672
|
+
];
|
|
654
673
|
|
|
655
674
|
// ── Slide 5: Win USDC ──
|
|
656
675
|
const WinSlide = ({ config, onComplete }: SlideProps) => {
|
|
@@ -693,9 +712,13 @@ const WinSlide = ({ config, onComplete }: SlideProps) => {
|
|
|
693
712
|
style={{ border: "1px solid rgba(255,255,255,0.08)", background: "rgba(255,255,255,0.02)" }}
|
|
694
713
|
>
|
|
695
714
|
{/* Table header */}
|
|
696
|
-
<div className="
|
|
715
|
+
<div className="grid grid-cols-3 items-center px-3 py-1.5" style={{ borderBottom: "1px solid rgba(255,255,255,0.06)", background: "rgba(255,255,255,0.03)" }}>
|
|
697
716
|
<span className="text-[9px] font-bold text-white/50 uppercase tracking-widest" style={OUTFIT}>Rank</span>
|
|
698
|
-
<div className="flex items-center gap-1">
|
|
717
|
+
<div className="flex items-center gap-1 justify-center">
|
|
718
|
+
<PointsIcon size={9} />
|
|
719
|
+
<span className="text-[9px] font-bold text-white/50 uppercase tracking-widest" style={OUTFIT}>Points</span>
|
|
720
|
+
</div>
|
|
721
|
+
<div className="flex items-center gap-1 justify-end">
|
|
699
722
|
<Image src="/icons/ic_usdc_hd.png" alt="USDC" width={11} height={11} className="rounded-full" />
|
|
700
723
|
<span className="text-[9px] font-bold text-white/50 uppercase tracking-widest" style={OUTFIT}>Reward</span>
|
|
701
724
|
</div>
|
|
@@ -707,7 +730,7 @@ const WinSlide = ({ config, onComplete }: SlideProps) => {
|
|
|
707
730
|
initial={{ opacity: 0, x: -8 }}
|
|
708
731
|
animate={{ opacity: 1, x: 0 }}
|
|
709
732
|
transition={{ delay: 1.6 + idx * 0.06, duration: 0.2 }}
|
|
710
|
-
className="
|
|
733
|
+
className="grid grid-cols-3 items-center px-3 py-1.5"
|
|
711
734
|
style={{
|
|
712
735
|
borderBottom: idx < FREE_PAYOUTS.length - 1 ? "1px solid rgba(255,255,255,0.04)" : "none",
|
|
713
736
|
background: idx === 0 ? "rgba(255,215,0,0.04)" : idx < 3 ? "rgba(255,255,255,0.015)" : "transparent",
|
|
@@ -727,8 +750,14 @@ const WinSlide = ({ config, onComplete }: SlideProps) => {
|
|
|
727
750
|
)}
|
|
728
751
|
</div>
|
|
729
752
|
<span
|
|
730
|
-
className="text-[
|
|
731
|
-
style={{ ...OUTFIT, color: idx === 0 ? "#
|
|
753
|
+
className="text-[10px] font-semibold text-center"
|
|
754
|
+
style={{ ...OUTFIT, color: idx === 0 ? "#22E3E8" : idx < 3 ? "rgba(255,255,255,0.75)" : "rgba(255,255,255,0.5)" }}
|
|
755
|
+
>
|
|
756
|
+
{row.points.toLocaleString()}
|
|
757
|
+
</span>
|
|
758
|
+
<span
|
|
759
|
+
className="text-[11px] font-bold text-right select-none"
|
|
760
|
+
style={{ ...OUTFIT, color: idx === 0 ? "#FFD700" : idx < 3 ? "rgba(255,255,255,0.85)" : "rgba(255,255,255,0.6)", filter: "blur(5px)" }}
|
|
732
761
|
>
|
|
733
762
|
${row.usdc.toFixed(2)}
|
|
734
763
|
</span>
|