@digilogiclabs/saas-factory-ui 1.33.0 → 1.34.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.d.mts +46 -4
- package/dist/index.d.ts +46 -4
- package/dist/index.js +94 -51
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +94 -51
- package/dist/index.mjs.map +1 -1
- package/dist/web/index.d.mts +36 -2
- package/dist/web/index.d.ts +36 -2
- package/dist/web/index.js +92 -49
- package/dist/web/index.js.map +1 -1
- package/dist/web/index.mjs +89 -46
- package/dist/web/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -3759,8 +3759,16 @@ declare function useEscapeKey(handler: () => void, enabled?: boolean): void;
|
|
|
3759
3759
|
* 3. `prefers-color-scheme: dark` media query.
|
|
3760
3760
|
*
|
|
3761
3761
|
* Live-updates via a `MutationObserver` watching the root class attribute
|
|
3762
|
-
* and a `change` listener on the media query.
|
|
3763
|
-
*
|
|
3762
|
+
* and a `change` listener on the media query.
|
|
3763
|
+
*
|
|
3764
|
+
* SSR-safe by construction: the FIRST render always returns `false` (or the
|
|
3765
|
+
* `forced` value when provided), matching what the server renders. Detection
|
|
3766
|
+
* only runs after mount in `useEffect`, so the initial client render is
|
|
3767
|
+
* byte-identical to SSR — no hydration mismatch warnings. The trade-off is
|
|
3768
|
+
* a brief flash of light-theme markup before the effect commits the real
|
|
3769
|
+
* value; a no-flash app should also set `.dark` on `<html>` via a synchronous
|
|
3770
|
+
* script tag in the document head before React hydrates (next-themes does
|
|
3771
|
+
* this), in which case this hook then picks up that class on mount.
|
|
3764
3772
|
*/
|
|
3765
3773
|
declare function useDarkMode(forced?: boolean): boolean;
|
|
3766
3774
|
|
|
@@ -4979,9 +4987,9 @@ interface RandomPlayerPickerProps {
|
|
|
4979
4987
|
* Visual intensity preset. Default "normal".
|
|
4980
4988
|
* - "subtle" / "normal": current behavior — shorter spins, standard
|
|
4981
4989
|
* ease-out curve.
|
|
4982
|
-
* - "dramatic": physics-like spin —
|
|
4990
|
+
* - "dramatic": physics-like spin — 2.5× duration, inertia-style
|
|
4983
4991
|
* curve so motion continues through the full duration with a slow
|
|
4984
|
-
* winding-down tail, +
|
|
4992
|
+
* winding-down tail, +12 extra revolutions, plus more
|
|
4985
4993
|
* particles/glow/shake on reveal.
|
|
4986
4994
|
*/
|
|
4987
4995
|
intensity?: RandomPlayerIntensity;
|
|
@@ -5066,6 +5074,40 @@ interface HeroBannerCta {
|
|
|
5066
5074
|
interface HeroBannerSlide {
|
|
5067
5075
|
/** Background image URL. */
|
|
5068
5076
|
image?: string;
|
|
5077
|
+
/**
|
|
5078
|
+
* Render this slide's image as a real `<img>` (with `fetchpriority="high"`,
|
|
5079
|
+
* `loading="eager"`, `decoding="async"`) instead of a CSS `background-image`.
|
|
5080
|
+
*
|
|
5081
|
+
* Set this on the first slide to make it a reliable LCP target. CSS
|
|
5082
|
+
* backgrounds are valid LCP candidates but the browser discovers them
|
|
5083
|
+
* later (after CSS parse), and `<link rel="preload">` connects to real
|
|
5084
|
+
* `<img>` elements far more reliably than to `background-image` URLs.
|
|
5085
|
+
*
|
|
5086
|
+
* Only the slide with `priority: true` swaps to `<img>`; all other slides
|
|
5087
|
+
* stay on CSS `background-image` (cheaper to cycle). The `imageFilter`,
|
|
5088
|
+
* `bgColor`, overlays, and accent layers all still apply.
|
|
5089
|
+
*/
|
|
5090
|
+
priority?: boolean;
|
|
5091
|
+
/**
|
|
5092
|
+
* Optional alt text for the priority `<img>`. Defaults to empty (decorative)
|
|
5093
|
+
* — appropriate when the slide already carries semantic text via headline /
|
|
5094
|
+
* kicker.
|
|
5095
|
+
*/
|
|
5096
|
+
imageAlt?: string;
|
|
5097
|
+
/**
|
|
5098
|
+
* Optional intrinsic width of the priority image (in pixels). When set with
|
|
5099
|
+
* `imageHeight`, emitted as the `<img>` `width` HTML attribute. Lets the
|
|
5100
|
+
* browser compute aspect ratio for the preload connection without waiting
|
|
5101
|
+
* for image headers. Has no layout effect when the parent already sizes
|
|
5102
|
+
* the image via absolute positioning (the default). Ignored unless
|
|
5103
|
+
* `priority` is true.
|
|
5104
|
+
*/
|
|
5105
|
+
imageWidth?: number;
|
|
5106
|
+
/**
|
|
5107
|
+
* Optional intrinsic height of the priority image (in pixels). Companion
|
|
5108
|
+
* to `imageWidth`. See `imageWidth` for usage notes.
|
|
5109
|
+
*/
|
|
5110
|
+
imageHeight?: number;
|
|
5069
5111
|
/** CSS gradient string (e.g. `"linear-gradient(135deg,#0f172a,#0f4c75)"`). */
|
|
5070
5112
|
gradient?: string;
|
|
5071
5113
|
/** Fallback solid background color. */
|
package/dist/index.d.ts
CHANGED
|
@@ -3759,8 +3759,16 @@ declare function useEscapeKey(handler: () => void, enabled?: boolean): void;
|
|
|
3759
3759
|
* 3. `prefers-color-scheme: dark` media query.
|
|
3760
3760
|
*
|
|
3761
3761
|
* Live-updates via a `MutationObserver` watching the root class attribute
|
|
3762
|
-
* and a `change` listener on the media query.
|
|
3763
|
-
*
|
|
3762
|
+
* and a `change` listener on the media query.
|
|
3763
|
+
*
|
|
3764
|
+
* SSR-safe by construction: the FIRST render always returns `false` (or the
|
|
3765
|
+
* `forced` value when provided), matching what the server renders. Detection
|
|
3766
|
+
* only runs after mount in `useEffect`, so the initial client render is
|
|
3767
|
+
* byte-identical to SSR — no hydration mismatch warnings. The trade-off is
|
|
3768
|
+
* a brief flash of light-theme markup before the effect commits the real
|
|
3769
|
+
* value; a no-flash app should also set `.dark` on `<html>` via a synchronous
|
|
3770
|
+
* script tag in the document head before React hydrates (next-themes does
|
|
3771
|
+
* this), in which case this hook then picks up that class on mount.
|
|
3764
3772
|
*/
|
|
3765
3773
|
declare function useDarkMode(forced?: boolean): boolean;
|
|
3766
3774
|
|
|
@@ -4979,9 +4987,9 @@ interface RandomPlayerPickerProps {
|
|
|
4979
4987
|
* Visual intensity preset. Default "normal".
|
|
4980
4988
|
* - "subtle" / "normal": current behavior — shorter spins, standard
|
|
4981
4989
|
* ease-out curve.
|
|
4982
|
-
* - "dramatic": physics-like spin —
|
|
4990
|
+
* - "dramatic": physics-like spin — 2.5× duration, inertia-style
|
|
4983
4991
|
* curve so motion continues through the full duration with a slow
|
|
4984
|
-
* winding-down tail, +
|
|
4992
|
+
* winding-down tail, +12 extra revolutions, plus more
|
|
4985
4993
|
* particles/glow/shake on reveal.
|
|
4986
4994
|
*/
|
|
4987
4995
|
intensity?: RandomPlayerIntensity;
|
|
@@ -5066,6 +5074,40 @@ interface HeroBannerCta {
|
|
|
5066
5074
|
interface HeroBannerSlide {
|
|
5067
5075
|
/** Background image URL. */
|
|
5068
5076
|
image?: string;
|
|
5077
|
+
/**
|
|
5078
|
+
* Render this slide's image as a real `<img>` (with `fetchpriority="high"`,
|
|
5079
|
+
* `loading="eager"`, `decoding="async"`) instead of a CSS `background-image`.
|
|
5080
|
+
*
|
|
5081
|
+
* Set this on the first slide to make it a reliable LCP target. CSS
|
|
5082
|
+
* backgrounds are valid LCP candidates but the browser discovers them
|
|
5083
|
+
* later (after CSS parse), and `<link rel="preload">` connects to real
|
|
5084
|
+
* `<img>` elements far more reliably than to `background-image` URLs.
|
|
5085
|
+
*
|
|
5086
|
+
* Only the slide with `priority: true` swaps to `<img>`; all other slides
|
|
5087
|
+
* stay on CSS `background-image` (cheaper to cycle). The `imageFilter`,
|
|
5088
|
+
* `bgColor`, overlays, and accent layers all still apply.
|
|
5089
|
+
*/
|
|
5090
|
+
priority?: boolean;
|
|
5091
|
+
/**
|
|
5092
|
+
* Optional alt text for the priority `<img>`. Defaults to empty (decorative)
|
|
5093
|
+
* — appropriate when the slide already carries semantic text via headline /
|
|
5094
|
+
* kicker.
|
|
5095
|
+
*/
|
|
5096
|
+
imageAlt?: string;
|
|
5097
|
+
/**
|
|
5098
|
+
* Optional intrinsic width of the priority image (in pixels). When set with
|
|
5099
|
+
* `imageHeight`, emitted as the `<img>` `width` HTML attribute. Lets the
|
|
5100
|
+
* browser compute aspect ratio for the preload connection without waiting
|
|
5101
|
+
* for image headers. Has no layout effect when the parent already sizes
|
|
5102
|
+
* the image via absolute positioning (the default). Ignored unless
|
|
5103
|
+
* `priority` is true.
|
|
5104
|
+
*/
|
|
5105
|
+
imageWidth?: number;
|
|
5106
|
+
/**
|
|
5107
|
+
* Optional intrinsic height of the priority image (in pixels). Companion
|
|
5108
|
+
* to `imageWidth`. See `imageWidth` for usage notes.
|
|
5109
|
+
*/
|
|
5110
|
+
imageHeight?: number;
|
|
5069
5111
|
/** CSS gradient string (e.g. `"linear-gradient(135deg,#0f172a,#0f4c75)"`). */
|
|
5070
5112
|
gradient?: string;
|
|
5071
5113
|
/** Fallback solid background color. */
|
package/dist/index.js
CHANGED
|
@@ -10,8 +10,8 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
10
10
|
var __esm = (fn, res) => function __init() {
|
|
11
11
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
12
12
|
};
|
|
13
|
-
var __commonJS = (cb,
|
|
14
|
-
return
|
|
13
|
+
var __commonJS = (cb, mod2) => function __require() {
|
|
14
|
+
return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports;
|
|
15
15
|
};
|
|
16
16
|
var __export = (target, all) => {
|
|
17
17
|
for (var name in all)
|
|
@@ -25,15 +25,15 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
25
25
|
}
|
|
26
26
|
return to;
|
|
27
27
|
};
|
|
28
|
-
var __toESM = (
|
|
28
|
+
var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps(
|
|
29
29
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
30
|
// file that has been converted to a CommonJS file using a Babel-
|
|
31
31
|
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
32
|
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
-
isNodeMode || !
|
|
34
|
-
|
|
33
|
+
isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target,
|
|
34
|
+
mod2
|
|
35
35
|
));
|
|
36
|
-
var __toCommonJS = (
|
|
36
|
+
var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
|
|
37
37
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
38
38
|
|
|
39
39
|
// src/config/constants.ts
|
|
@@ -25443,11 +25443,6 @@ var import_react55 = require("react");
|
|
|
25443
25443
|
function useDarkMode(forced) {
|
|
25444
25444
|
const [dark, setDark] = (0, import_react55.useState)(() => {
|
|
25445
25445
|
if (typeof forced === "boolean") return forced;
|
|
25446
|
-
if (typeof document === "undefined") return false;
|
|
25447
|
-
if (document.documentElement.classList.contains("dark")) return true;
|
|
25448
|
-
if (typeof window !== "undefined" && window.matchMedia) {
|
|
25449
|
-
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
25450
|
-
}
|
|
25451
25446
|
return false;
|
|
25452
25447
|
});
|
|
25453
25448
|
(0, import_react55.useEffect)(() => {
|
|
@@ -31768,8 +31763,7 @@ function BracketGenerator({
|
|
|
31768
31763
|
champion: null
|
|
31769
31764
|
};
|
|
31770
31765
|
setBracketState(newState);
|
|
31771
|
-
|
|
31772
|
-
}, [effectiveParticipants, seedingStrategy, onStateChange]);
|
|
31766
|
+
}, [effectiveParticipants, seedingStrategy]);
|
|
31773
31767
|
const simulateNext = (0, import_react69.useCallback)(() => {
|
|
31774
31768
|
setBracketState((prev) => {
|
|
31775
31769
|
const next = prev.matches.find((m) => m.a && m.b && !m.winner);
|
|
@@ -31782,13 +31776,9 @@ function BracketGenerator({
|
|
|
31782
31776
|
matches = propagateWinner(matches, completed);
|
|
31783
31777
|
const finalMatch = matches.find((m) => m.round === prev.rounds - 1);
|
|
31784
31778
|
const champion = finalMatch?.winner || null;
|
|
31785
|
-
|
|
31786
|
-
if (champion && !prev.champion) onChampion?.(champion);
|
|
31787
|
-
const newState = { ...prev, matches, champion };
|
|
31788
|
-
onStateChange?.(newState);
|
|
31789
|
-
return newState;
|
|
31779
|
+
return { ...prev, matches, champion };
|
|
31790
31780
|
});
|
|
31791
|
-
}, [
|
|
31781
|
+
}, []);
|
|
31792
31782
|
const autoPlay = (0, import_react69.useCallback)(() => {
|
|
31793
31783
|
if (simulating) {
|
|
31794
31784
|
if (autoRef.current) clearTimeout(autoRef.current);
|
|
@@ -31811,17 +31801,13 @@ function BracketGenerator({
|
|
|
31811
31801
|
matches = propagateWinner(matches, completed);
|
|
31812
31802
|
const finalMatch = matches.find((m) => m.round === prev.rounds - 1);
|
|
31813
31803
|
const champion = finalMatch?.winner || null;
|
|
31814
|
-
onMatchComplete?.(completed, completed.winner);
|
|
31815
|
-
if (champion && !prev.champion) onChampion?.(champion);
|
|
31816
|
-
const newState = { ...prev, matches, champion };
|
|
31817
|
-
onStateChange?.(newState);
|
|
31818
31804
|
if (!champion) autoRef.current = setTimeout(tick, simulateDelayMs);
|
|
31819
31805
|
else setSimulating(false);
|
|
31820
|
-
return
|
|
31806
|
+
return { ...prev, matches, champion };
|
|
31821
31807
|
});
|
|
31822
31808
|
};
|
|
31823
31809
|
tick();
|
|
31824
|
-
}, [simulating, simulateDelayMs
|
|
31810
|
+
}, [simulating, simulateDelayMs]);
|
|
31825
31811
|
const advanceWinner = (0, import_react69.useCallback)(
|
|
31826
31812
|
(matchId, winnerSlot) => {
|
|
31827
31813
|
setBracketState((prev) => {
|
|
@@ -31840,15 +31826,31 @@ function BracketGenerator({
|
|
|
31840
31826
|
matches = propagateWinner(matches, completed);
|
|
31841
31827
|
const finalMatch = matches.find((x) => x.round === prev.rounds - 1);
|
|
31842
31828
|
const champion = finalMatch?.winner || null;
|
|
31843
|
-
|
|
31844
|
-
if (champion && !prev.champion) onChampion?.(champion);
|
|
31845
|
-
const newState = { ...prev, matches, champion };
|
|
31846
|
-
onStateChange?.(newState);
|
|
31847
|
-
return newState;
|
|
31829
|
+
return { ...prev, matches, champion };
|
|
31848
31830
|
});
|
|
31849
31831
|
},
|
|
31850
|
-
[
|
|
31832
|
+
[]
|
|
31851
31833
|
);
|
|
31834
|
+
const prevBracketStateRef = (0, import_react69.useRef)(bracketState);
|
|
31835
|
+
(0, import_react69.useEffect)(() => {
|
|
31836
|
+
const prev = prevBracketStateRef.current;
|
|
31837
|
+
const next = bracketState;
|
|
31838
|
+
if (prev === next) return;
|
|
31839
|
+
if (onMatchComplete) {
|
|
31840
|
+
const prevById = new Map(prev.matches.map((m) => [m.id, m]));
|
|
31841
|
+
for (const m of next.matches) {
|
|
31842
|
+
const before = prevById.get(m.id);
|
|
31843
|
+
if (m.winner && !before?.winner) {
|
|
31844
|
+
onMatchComplete(m, m.winner);
|
|
31845
|
+
}
|
|
31846
|
+
}
|
|
31847
|
+
}
|
|
31848
|
+
if (onChampion && next.champion && !prev.champion) {
|
|
31849
|
+
onChampion(next.champion);
|
|
31850
|
+
}
|
|
31851
|
+
onStateChange?.(next);
|
|
31852
|
+
prevBracketStateRef.current = next;
|
|
31853
|
+
}, [bracketState, onMatchComplete, onChampion, onStateChange]);
|
|
31852
31854
|
(0, import_react69.useEffect)(() => {
|
|
31853
31855
|
seedBracket();
|
|
31854
31856
|
return () => {
|
|
@@ -31940,7 +31942,7 @@ function BracketGenerator({
|
|
|
31940
31942
|
height: MATCH_H / 2,
|
|
31941
31943
|
cursor: hasBoth && !m.winner ? "pointer" : "default",
|
|
31942
31944
|
opacity: isLoss ? 0.45 : 1,
|
|
31943
|
-
|
|
31945
|
+
textDecorationLine: isLoss ? "line-through" : "none",
|
|
31944
31946
|
textDecorationColor: colors.faint,
|
|
31945
31947
|
transition: "background 0.2s, color 0.2s",
|
|
31946
31948
|
fontStyle: !p ? "italic" : "normal"
|
|
@@ -33324,8 +33326,8 @@ var WEDGE_PALETTE = [
|
|
|
33324
33326
|
"#14b8a6",
|
|
33325
33327
|
"#f97316"
|
|
33326
33328
|
];
|
|
33327
|
-
var DEFAULT_EASING = "cubic-bezier(0.
|
|
33328
|
-
var DRAMATIC_EASING = "cubic-bezier(0.
|
|
33329
|
+
var DEFAULT_EASING = "cubic-bezier(0.25, 0.46, 0.45, 0.94)";
|
|
33330
|
+
var DRAMATIC_EASING = "cubic-bezier(0.39, 0.575, 0.565, 1)";
|
|
33329
33331
|
var INTENSITY_CONFIG = {
|
|
33330
33332
|
subtle: {
|
|
33331
33333
|
particles: 14,
|
|
@@ -33350,9 +33352,9 @@ var INTENSITY_CONFIG = {
|
|
|
33350
33352
|
shakePeak: 10,
|
|
33351
33353
|
glowMult: 1.45,
|
|
33352
33354
|
pulseStroke: 8,
|
|
33353
|
-
durationMult:
|
|
33355
|
+
durationMult: 2.5,
|
|
33354
33356
|
easing: DRAMATIC_EASING,
|
|
33355
|
-
revsBoost:
|
|
33357
|
+
revsBoost: 12
|
|
33356
33358
|
}
|
|
33357
33359
|
};
|
|
33358
33360
|
function polar(cx, cy, r, a) {
|
|
@@ -33378,6 +33380,20 @@ function weightedIndex(pool) {
|
|
|
33378
33380
|
}
|
|
33379
33381
|
return pool.length - 1;
|
|
33380
33382
|
}
|
|
33383
|
+
function mod(value, divisor) {
|
|
33384
|
+
return (value % divisor + divisor) % divisor;
|
|
33385
|
+
}
|
|
33386
|
+
function wheelIndexAtPointer(rotation, count2) {
|
|
33387
|
+
if (count2 < 1) return -1;
|
|
33388
|
+
const wedgeDeg = 360 / count2;
|
|
33389
|
+
const localDegAtPointer = mod(-rotation, 360);
|
|
33390
|
+
return Math.min(count2 - 1, Math.floor(localDegAtPointer / wedgeDeg));
|
|
33391
|
+
}
|
|
33392
|
+
function reelIndexAtCenter(reelY, centerOffsetPx, rowHeight, count2) {
|
|
33393
|
+
if (count2 < 1) return -1;
|
|
33394
|
+
const centerRow = Math.round((reelY + centerOffsetPx) / rowHeight);
|
|
33395
|
+
return mod(centerRow, count2);
|
|
33396
|
+
}
|
|
33381
33397
|
function ReelStage({
|
|
33382
33398
|
pool,
|
|
33383
33399
|
winner,
|
|
@@ -33805,7 +33821,9 @@ function RandomPlayerPicker({
|
|
|
33805
33821
|
const winnerIdx = weightedIndex(pool);
|
|
33806
33822
|
const minRev = minRevolutions + intensityCfg.revsBoost;
|
|
33807
33823
|
const maxRev = maxRevolutions + intensityCfg.revsBoost;
|
|
33808
|
-
const
|
|
33824
|
+
const minFullRevs = Math.ceil(minRev);
|
|
33825
|
+
const maxFullRevs = Math.max(minFullRevs, Math.floor(maxRev));
|
|
33826
|
+
const revolutions = minFullRevs + Math.floor(Math.random() * (maxFullRevs - minFullRevs + 1));
|
|
33809
33827
|
const wedgeMidRad = winnerIdx * anglePerWedge + anglePerWedge / 2;
|
|
33810
33828
|
const wedgeMidDeg = wedgeMidRad * 180 / Math.PI;
|
|
33811
33829
|
const wheelWobble = (Math.random() - 0.5) * (anglePerWedge * 180 / Math.PI) * 0.6;
|
|
@@ -33819,10 +33837,12 @@ function RandomPlayerPicker({
|
|
|
33819
33837
|
const currentCenterRow = Math.round(
|
|
33820
33838
|
(reelY + centerOffsetPx) / reelRowHeight
|
|
33821
33839
|
);
|
|
33822
|
-
const currentCenterMod = (currentCenterRow
|
|
33840
|
+
const currentCenterMod = mod(currentCenterRow, n);
|
|
33823
33841
|
const targetRowOffset = (winnerIdx - currentCenterMod + n) % n;
|
|
33824
33842
|
const reelRevRows = Math.round(revolutions * n);
|
|
33825
33843
|
const finalReelY = reelY + (reelRevRows + targetRowOffset) * reelRowHeight;
|
|
33844
|
+
const settledWinnerIdx = mode === "reel" ? reelIndexAtCenter(finalReelY, centerOffsetPx, reelRowHeight, n) : wheelIndexAtPointer(finalRotation, n);
|
|
33845
|
+
const finalWinnerIdx = settledWinnerIdx >= 0 && settledWinnerIdx < pool.length ? settledWinnerIdx : winnerIdx;
|
|
33826
33846
|
const effectiveDuration = reducedMotion ? 250 : Math.round(spinDuration * intensityCfg.durationMult);
|
|
33827
33847
|
setSpinning(true);
|
|
33828
33848
|
setWinner(null);
|
|
@@ -33867,7 +33887,7 @@ function RandomPlayerPicker({
|
|
|
33867
33887
|
schedule();
|
|
33868
33888
|
}
|
|
33869
33889
|
winnerTimer.current = setTimeout(() => {
|
|
33870
|
-
const picked = pool[
|
|
33890
|
+
const picked = pool[finalWinnerIdx];
|
|
33871
33891
|
if (!picked) {
|
|
33872
33892
|
setSpinning(false);
|
|
33873
33893
|
return;
|
|
@@ -33914,7 +33934,7 @@ function RandomPlayerPicker({
|
|
|
33914
33934
|
}
|
|
33915
33935
|
if (removeWinners) {
|
|
33916
33936
|
popTimer.current = setTimeout(() => {
|
|
33917
|
-
setPool((p) => p.filter((_, i) => i !==
|
|
33937
|
+
setPool((p) => p.filter((_, i) => i !== finalWinnerIdx));
|
|
33918
33938
|
setWinner(null);
|
|
33919
33939
|
setRotation(0);
|
|
33920
33940
|
setReelY(0);
|
|
@@ -35059,23 +35079,46 @@ function DynamicHeroBanner({
|
|
|
35059
35079
|
const filter = IMAGE_FILTERS[slide.imageFilter ?? imageFilter] ?? IMAGE_FILTERS.cinematic;
|
|
35060
35080
|
const slideOverlayOpacity = slide.overlayOpacity ?? overlayOpacity;
|
|
35061
35081
|
const slideAlign = slide.textAlign ?? textAlign;
|
|
35082
|
+
const usePriorityImg = slide.priority === true && !!slide.image;
|
|
35083
|
+
const bgDivStyle = usePriorityImg ? {
|
|
35084
|
+
position: "absolute",
|
|
35085
|
+
inset: 0,
|
|
35086
|
+
backgroundColor: slide.bgColor ?? "#0c0e14",
|
|
35087
|
+
transform: isCurrent ? "scale(1)" : "scale(1.06)",
|
|
35088
|
+
transition: reducedMotion ? "none" : `transform ${autoPlayInterval}ms linear`
|
|
35089
|
+
} : {
|
|
35090
|
+
position: "absolute",
|
|
35091
|
+
inset: 0,
|
|
35092
|
+
backgroundImage: slide.image ? `url(${slide.image})` : slide.gradient ?? "none",
|
|
35093
|
+
backgroundColor: slide.bgColor ?? "#0c0e14",
|
|
35094
|
+
backgroundSize: "cover",
|
|
35095
|
+
backgroundPosition: "center",
|
|
35096
|
+
filter,
|
|
35097
|
+
transform: isCurrent ? "scale(1)" : "scale(1.06)",
|
|
35098
|
+
transition: reducedMotion ? "none" : `transform ${autoPlayInterval}ms linear`
|
|
35099
|
+
};
|
|
35062
35100
|
return /* @__PURE__ */ (0, import_jsx_runtime118.jsxs)("div", { style: bgStyle(i), "aria-hidden": !isCurrent, children: [
|
|
35063
|
-
/* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
35064
|
-
"
|
|
35101
|
+
/* @__PURE__ */ (0, import_jsx_runtime118.jsx)("div", { style: bgDivStyle, children: usePriorityImg && /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
35102
|
+
"img",
|
|
35065
35103
|
{
|
|
35104
|
+
src: slide.image,
|
|
35105
|
+
alt: slide.imageAlt ?? "",
|
|
35106
|
+
width: slide.imageWidth && slide.imageHeight ? slide.imageWidth : void 0,
|
|
35107
|
+
height: slide.imageWidth && slide.imageHeight ? slide.imageHeight : void 0,
|
|
35108
|
+
fetchPriority: "high",
|
|
35109
|
+
loading: "eager",
|
|
35110
|
+
decoding: "async",
|
|
35066
35111
|
style: {
|
|
35067
35112
|
position: "absolute",
|
|
35068
35113
|
inset: 0,
|
|
35069
|
-
|
|
35070
|
-
|
|
35071
|
-
|
|
35072
|
-
|
|
35073
|
-
filter
|
|
35074
|
-
transform: isCurrent ? "scale(1)" : "scale(1.06)",
|
|
35075
|
-
transition: reducedMotion ? "none" : `transform ${autoPlayInterval}ms linear`
|
|
35114
|
+
width: "100%",
|
|
35115
|
+
height: "100%",
|
|
35116
|
+
objectFit: "cover",
|
|
35117
|
+
objectPosition: "center",
|
|
35118
|
+
filter
|
|
35076
35119
|
}
|
|
35077
35120
|
}
|
|
35078
|
-
),
|
|
35121
|
+
) }),
|
|
35079
35122
|
/* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
35080
35123
|
"div",
|
|
35081
35124
|
{
|
|
@@ -35475,7 +35518,7 @@ function CtaButton({
|
|
|
35475
35518
|
background: isPrimary ? accent : isGhost ? "transparent" : "rgba(255,255,255,0.06)",
|
|
35476
35519
|
color: isPrimary ? "#fff" : "rgba(255,255,255,0.8)",
|
|
35477
35520
|
cursor: "pointer",
|
|
35478
|
-
|
|
35521
|
+
textDecorationLine: isGhost ? "underline" : "none",
|
|
35479
35522
|
textUnderlineOffset: isGhost ? 4 : void 0,
|
|
35480
35523
|
letterSpacing: "-0.01em",
|
|
35481
35524
|
boxShadow: isPrimary ? `0 4px 20px ${glow}33` : "none",
|