1import{r,j as t}from"./index-9ZedHETz.js";const a=` 2<div id="ctf-wheel-root" aria-live="polite"></div> 3 4<style> 5 .om-element-html:has(#ctf-wheel-root), 6 .om-html:has(#ctf-wheel-root), 7 [class*="col"]:has(#ctf-wheel-root), 8 [class*="row"]:has(#ctf-wheel-root), 9 [class*="html"]:has(#ctf-wheel-root) { 10 width:100% !important; max-width:100% !important; flex:1 1 100% !important; 11 padding:0 !important; margin:0 !important; 12 } 13 14 #ctf-wheel-root { 15 --bg-0: #0a0608; 16 --bg-1: #0f0f0f; 17 --glass: rgba(255,255,255,.05); 18 --glass-2: rgba(255,255,255,.08); 19 --stroke: rgba(239,32,32,.18); 20 --ink: #f5f5f5; 21 --muted: #a0a0a0; 22 --accent: #ef2222; 23 --accent-2:#ff5252; 24 --danger: #ff6b6b; 25 --lv-starter: #ff5252; 26 --lv-explorer: #ef2222; 27 --lv-operator: #c81e1e; 28 --lv-elite: #ffb347; 29 30 --r-lg: 22px; --r-md: 14px; --r-sm: 10px; 31 --sans: "Plus Jakarta Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; 32 --orbitron: "Outfit", ui-sans-serif, system-ui, sans-serif; 33 34 position:relative; isolation:isolate; 35 font-family:var(--sans); color:var(--ink); 36 display:block; width:100%; max-width:100%; 37 margin:0; padding:32px clamp(20px, 4vw, 48px); 38 box-sizing:border-box; overflow:hidden; 39 background: 40 radial-gradient(130% 90% at 50% -20%, color-mix(in srgb, var(--accent) 28%, transparent), transparent 55%), 41 linear-gradient(180deg, var(--bg-0), var(--bg-1)); 42 border:1px solid var(--stroke); 43 box-shadow: 0 24px 60px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.06); 44 } 45 46 47 #ctf-wheel-root .cw-grid{ 48 display:grid; grid-template-columns: 1fr; gap:32px; align-items:center; 49 } 50 @media (min-width: 900px){ 51 #ctf-wheel-root .cw-grid{ grid-template-columns: 1.05fr 1fr; gap:56px; align-items:center; } 52 #ctf-wheel-root .cw-left{ text-align:left; } 53 } 54 @media (min-width: 1200px){ 55 #ctf-wheel-root .cw-grid{ grid-template-columns: 1fr 1fr; gap:72px; } 56 } 57 #ctf-wheel-root .cw-right{ display:flex; flex-direction:column; align-items:center; } 58 59 #ctf-wheel-root *, #ctf-wheel-root *::before, #ctf-wheel-root *::after { box-sizing:border-box; } 60 61 #ctf-wheel-root::before{ 62 content:""; position:absolute; inset:-40% -20% auto -20%; height:80%; z-index:-1; 63 background:radial-gradient(50% 50% at 50% 50%, color-mix(in srgb, var(--lvc, var(--accent)) 30%, transparent), transparent 70%); 64 filter:blur(40px); opacity:.6; animation:cw-aura 7s ease-in-out infinite alternate; 65 } 66 @keyframes cw-aura { from{transform:translateY(-6%) scale(1)} to{transform:translateY(4%) scale(1.08)} } 67 68 #ctf-wheel-root .cw-head { text-align:center; margin-bottom:18px; } 69 #ctf-wheel-root .cw-eyebrow{ 70 display:inline-block; font-size:10.5px; letter-spacing:.22em; text-transform:uppercase; 71 color:color-mix(in srgb, var(--lvc, var(--accent)) 80%, white 20%); font-weight:700; margin:0 0 8px; 72 padding:4px 11px; border-radius:999px; background:var(--glass); border:1px solid var(--stroke); 73 backdrop-filter:blur(6px); 74 } 75 #ctf-wheel-root .cw-title{ 76 font-family:var(--orbitron); font-size:28px; font-weight:900; margin:0; letter-spacing:.02em; line-height:1.12; 77 background:linear-gradient(180deg,#fff, #c7cfe6); -webkit-background-clip:text; background-clip:text; color:transparent; 78 } 79 #ctf-wheel-root .cw-sub{ font-size:13px; color:var(--muted); margin:8px auto 0; line-height:1.5; max-width:30ch; } 80 81 /* Stats bar */ 82 #ctf-wheel-root .cw-stats{ 83 display:flex; justify-content:center; gap:12px; margin-bottom:18px; 84 } 85 #ctf-wheel-root .cw-stat{ 86 flex:1; text-align:center; padding:12px; 87 background:rgba(255,255,255,.04); border:1px solid rgba(255,255,255,.08); border-radius:16px; 88 } 89 #ctf-wheel-root .cw-stat-label{ 90 font-size:9px; text-transform:uppercase; letter-spacing:.15em; color:var(--muted); font-weight:700; margin-bottom:4px; 91 } 92 #ctf-wheel-root .cw-stat-val{ 93 font-family:var(--orbitron); font-size:20px; font-weight:900; 94 } 95 #ctf-wheel-root .cw-stat-streak{ color:#facc15; text-shadow:0 0 12px rgba(250,204,21,.4); } 96 #ctf-wheel-root .cw-stat-jackpot{ color:#ff5252; text-shadow:0 0 14px rgba(239,32,32,.5); } 97 98 #ctf-wheel-root .cw-levels{ display:grid; gap:11px; margin-top:20px; } 99 100 /* Offer banner */ 101 #ctf-wheel-root .cw-offer{ 102 position:relative; text-align:center; 103 padding:22px 16px 20px; border-radius:18px; overflow:hidden; 104 background: 105 radial-gradient(120% 120% at 50% 0%, rgba(255,82,82,.18), transparent 60%), 106 linear-gradient(180deg, rgba(255,255,255,.04), rgba(255,255,255,.02)); 107 border:1px solid rgba(255,82,82,.28); 108 box-shadow:0 10px 40px rgba(239,32,32,.18), inset 0 1px 0 rgba(255,255,255,.06); 109 } 110 #ctf-wheel-root .cw-offer::before{ 111 content:""; position:absolute; inset:0; pointer-events:none; opacity:.35; 112 background: 113 radial-gradient(2px 2px at 12% 30%, #ff7575 50%, transparent 60%), 114 radial-gradient(2px 2px at 86% 22%, #ef2222 50%, transparent 60%), 115 radial-gradient(1.5px 1.5px at 22% 78%, #ffd166 50%, transparent 60%), 116 radial-gradient(1.5px 1.5px at 78% 82%, #ff7575 50%, transparent 60%); 117 filter:blur(.4px); 118 } 119 #ctf-wheel-root .cw-ribbon{ 120 display:inline-flex; flex-direction:column; align-items:stretch; gap:0; margin-bottom:14px; 121 transform:rotate(-1.5deg); 122 } 123 #ctf-wheel-root .cw-ribbon-top{ 124 align-self:center; background:#facc15;
124 color:#1a1306; 125 font-family:var(--orbitron); font-weight:900; font-size:11px; letter-spacing:.18em; 126 padding:5px 14px; border-radius:4px; text-transform:uppercase; 127 box-shadow:0 4px 14px rgba(250,204,21,.35); 128 } 129 #ctf-wheel-root .cw-ribbon-main{ 130 margin-top:-3px; padding:9px 22px; border-radius:6px; 131 background:linear-gradient(135deg,#ff3b3b,#c81e1e); 132 color:#fff; font-family:'Georgia', serif; font-style:italic; font-weight:700; font-size:22px; 133 letter-spacing:.01em; box-shadow:0 8px 22px rgba(220,38,38,.45); 134 border-top:1px solid rgba(255,255,255,.2); 135 } 136 #ctf-wheel-root .cw-offer-pre{ 137 font-family:var(--sans); font-style:italic; font-weight:600; font-size:13px; 138 color:#e9eef9; opacity:.95; margin:0 0 4px; 139 } 140 #ctf-wheel-root .cw-offer-h{ 141 font-family:var(--orbitron); font-weight:900; font-size:20px; line-height:1.2; 142 margin:0; color:#fff; 143 } 144 #ctf-wheel-root .cw-offer-script{ 145 font-family:'Brush Script MT','Snell Roundhand',cursive; font-style:italic; 146 font-size:26px; margin:8px 0 2px; line-height:1; letter-spacing:.01em; 147 background:linear-gradient(180deg,#ff7575,#ef2222); 148 -webkit-background-clip:text; background-clip:text; color:transparent; 149 text-shadow:0 2px 10px rgba(239,32,32,.25); 150 } 151 #ctf-wheel-root .cw-offer-cta{ 152 display:inline-flex; align-items:center; gap:8px; margin-top:10px; 153 font-family:var(--sans); font-weight:800; font-size:13px; color:#ff7575; 154 letter-spacing:.04em; text-transform:uppercase; 155 } 156 #ctf-wheel-root .cw-offer-cta::before{ content:"\\1F3AF"; font-size:14px; } 157 #ctf-wheel-root .cw-offer-cta::after{ 158 content:""; width:18px; height:1px; background:#ff7575; opacity:.6; 159 } 160 161 /* Left column â branded promo */ 162 #ctf-wheel-root .cw-left{ display:flex; flex-direction:column; gap:22px; } 163 #ctf-wheel-root .cw-tag{ 164 align-self:flex-start; display:inline-flex; align-items:center; gap:8px; 165 padding:6px 14px; border-radius:999px; 166 background:hsl(0 85% 50% / .12); border:1px solid hsl(0 85% 50% / .4); 167 color:#ff7575; font-family:var(--sans); font-weight:800; font-size:11px; 168 letter-spacing:.22em; text-transform:uppercase; 169 } 170 #ctf-wheel-root .cw-tag::before{ 171 content:""; width:6px; height:6px; border-radius:50%; 172 background:#ff5252; box-shadow:0 0 10px #ff5252; 173 animation:cw-dot 1.4s ease-in-out infinite; 174 } 175 @keyframes cw-dot { 0%,100%{opacity:1} 50%{opacity:.35} } 176 177 #ctf-wheel-root .cw-promo-h{ 178 font-family:var(--orbitron); font-weight:900; 179 font-size:clamp(34px, 4.4vw, 52px); line-height:1.02; letter-spacing:-.025em; 180 margin:0; color:#fff; 181 } 182 #ctf-wheel-root .cw-promo-h .cw-num{ 183 background:linear-gradient(180deg, #ff7575, #ef2222); 184 -webkit-background-clip:text; background-clip:text; color:transparent; 185 text-shadow:0 0 30px hsl(0 85% 50% / .25); 186 } 187 #ctf-wheel-root .cw-promo-sub{ 188 margin:0; color:var(--muted); font-size:15px; line-height:1.55; max-width:42ch; 189 } 190 #ctf-wheel-root .cw-promo-sub b{ color:#fff; font-weight:700; } 191 192 /* Inventory stat row */ 193 #ctf-wheel-root .cw-inv{ 194 display:grid; grid-template-columns:repeat(3, 1fr); gap:10px; margin-top:4px; 195 } 196 #ctf-wheel-root .cw-inv-cell{ 197 padding:14px 12px; border-radius:14px; text-align:center; 198 background:linear-gradient(180deg, rgba(255,255,255,.04), rgba(255,255,255,.02)); 199 border:1px solid rgba(255,82,82,.18); 200 } 201 #ctf-wheel-root .cw-inv-num{ 202 font-family:var(--orbitron); font-weight:900; font-size:22px; 203 color:#fff; letter-spacing:-.02em; line-height:1; 204 } 205 #ctf-wheel-root .cw-inv-num.is-red{ color:#ff5252; text-shadow:0 0 14px rgba(239,32,32,.5); } 206 #ctf-wheel-root .cw-inv-lbl{ 207 margin-top:6px; font-size:10px; font-weight:700; letter-spacing:.16em; 208 text-transform:uppercase; color:var(--muted); 209 } 210 211 /* Prize bullets */ 212 #ctf-wheel-root .cw-perks{ display:flex; flex-direction:column; gap:9px; margin-top:4px; } 213 #ctf-wheel-root .cw-perk{ 214 display:flex; align-items:center; gap:12px; 215 padding:11px 14px; border-radius:12px; 216 background:rgba(255,255,255,.03); border:1px solid rgba(255,255,255,.06); 217 font-size:13.5px; color:#e8e8e8; 218 } 219 #ctf-wheel-root .cw-perk-ic{ 220 flex:0 0 auto; width:26px; height:26px; border-radius:8px; 221 display:flex; align-items:center; justify-content:center; font-size:14px; 222 background:hsl(0 85% 50% / .15); border:1px solid hsl(0 85% 50% / .35); color:#ff7575; 223 } 224 #ctf-wheel-root .cw-perk b{ color:#fff; font-weight:700; } 225 226 /* Trust line */ 227 #ctf-wheel-root .cw-trust{ 228 display:flex; align-items:center; gap:14px; flex-wrap:wrap; 229 margin-top:2px; color:var(--muted); font-size:12px; 230 } 231 #ctf-wheel-root .cw-trust b{ color:#fff; } 232 #ctf-wheel-root .cw-trust .dot{ width:3px; height:3px; border-radius:50%; background:var(--muted); opacity:.5; } 233 234 235 #ctf-wheel-root .cw-level{ 236 --lvc:var(--accent); 237 position:relative; text-align:left; width:100%; cursor:pointer; overflow:hidden; 238 background:var(--glass); border:1px solid var(--stroke); border-radius:var(--r-md); 239 padding:14px 15px; color:var(--ink); font-family:var(--sans); 240 display:flex; align-items:center; gap:14px; backdrop-filter:blur(10px); 241 transition:transform .14s ease, border-color .18s ease, background .18s ease, box-shadow .18s ease; 242 } 243 #ctf-wheel-root .cw-level[data-l="Starter"] { --lvc:var(--lv-starter); } 244 #ctf-wheel-root .cw-level[data-l="Explorer"] { --lvc:var(--lv-explorer); } 245 #ctf-wheel-root .cw-level[data-l="Operator"] { --lvc:var(--lv-operator); } 246 #ctf-wheel-root .cw-level[data-l="Elite"] { --lvc:var(--lv-elite); } 247 #ctf-wheel-root .cw-level::after{ 248 content:""; position:absolute; left:0; top:0; bottom:0; width:3px; background:var(--lvc); 249 box-shadow:0 0 16px var(--lvc); opacity:.0; transition:opacity .18s ease; 250 } 251 #ctf-wheel-root .cw-level:hover{ transform:translateY(-2px); background:var(--glass-2); 252 border-color:color-mix(in srgb, var(--lvc) 55%, transparent); 253 box-shadow:0 10px 30px rgba(0,0,0,.35); } 254 #ctf-wheel-root .cw-level:hover::after{ opacity:1; } 255 #ctf-wheel-root .cw-level:focus-visible{ outline:2px solid var(--lvc); outline-offset:3px; } 256 #ctf-wheel-root .cw-badge{ 257 flex:0 0 auto; width:42px; height:42px; border-radius:12px; 258 display:flex; align-items:center; justify-content:center; font-weight:800; font-size:16px; 259 color:var(--lvc); 260 background:radial-gradient(120% 120% at 30% 20%, color-mix(in srgb, var(--lvc) 28%, transparent), transparent 70%), var(--glass); 261 border:1px solid color-mix(in srgb, var(--lvc) 45%, transparent); 262 box-shadow:0 0 18px color-mix(in srgb, var(--lvc) 30%, transparent); 263 } 264 #ctf-wheel-root .cw-level > .cw-txt{ display:flex; flex-direction:column; min-width:0; } 265 #ctf-wheel-root .cw-level-name{ font-weight:700; font-size:15px; } 266 #ctf-wheel-root .cw-level-arrow{ margin-left:auto; color:var(--lvc); font-size:18px; opacity:.7; transition:transform .18s ease; } 267 #ctf-wheel-root .cw-level:hover .cw-level-arrow{ transform:translateX(3px); opacity:1; } 268 269 #ctf-wheel-root .cw-back{ background:none; border:none;
269 color:var(--muted); font-size:13px; cursor:pointer; padding:0; margin-bottom:8px; display:inline-flex; align-items:center; gap:6px; } 270 #ctf-wheel-root .cw-back:hover{ color:var(--ink); } 271 272 /* Wheel stage - BIGGER */ 273 #ctf-wheel-root .cw-stage{ position:relative; width:min(440px, 88vw); aspect-ratio:1/1; height:auto; margin:0 auto 14px; } 274 #ctf-wheel-root .cw-glow{ 275 position:absolute; inset:-18px; border-radius:50%; z-index:0; 276 background:radial-gradient(closest-side, color-mix(in srgb, var(--lvc) 45%, transparent), transparent 78%); 277 filter:blur(10px); animation:cw-breathe 3.4s ease-in-out infinite; 278 } 279 @keyframes cw-breathe{ 0%,100%{opacity:.55; transform:scale(.98)} 50%{opacity:.9; transform:scale(1.03)} } 280 #ctf-wheel-root .cw-stage.is-spinning .cw-glow{ animation:cw-breathe-fast .6s ease-in-out infinite; } 281 @keyframes cw-breathe-fast{ 0%,100%{opacity:.8; transform:scale(1)} 50%{opacity:1; transform:scale(1.05)} } 282 283 /* Marquee rim with LED bulbs */ 284 #ctf-wheel-root .cw-marquee{ 285 position:absolute; inset:-18px; border-radius:50%; z-index:0; 286 border:14px solid #1a1c25; 287 box-shadow: 0 0 60px rgba(0,0,0,.8), inset 0 0 20px rgba(0,0,0,.5); 288 } 289 #ctf-wheel-root .cw-led{ 290 position:absolute; width:10px; height:10px; border-radius:50%; 291 background:#ff5252; 292 box-shadow:0 0 10px #ff5252, 0 0 20px rgba(239,32,32,.5); 293 animation:cw-led-blink 1.2s ease-in-out infinite; 294 } 295 #ctf-wheel-root .cw-led:nth-child(1){ top:0; left:50%; transform:translate(-50%,-50%); animation-delay:0s; } 296 #ctf-wheel-root .cw-led:nth-child(2){ top:50%; right:0; transform:translate(50%,-50%); animation-delay:.15s; } 297 #ctf-wheel-root .cw-led:nth-child(3){ bottom:0; left:50%; transform:translate(-50%,50%); animation-delay:.3s; } 298 #ctf-wheel-root .cw-led:nth-child(4){ top:50%; left:0; transform:translate(-50%,-50%); animation-delay:.45s; } 299 #ctf-wheel-root .cw-led:nth-child(5){ top:15%; right:15%; transform:translate(50%,-50%); animation-delay:.6s; } 300 #ctf-wheel-root .cw-led:nth-child(6){ top:15%; left:15%; transform:translate(-50%,-50%); animation-delay:.75s; } 301 #ctf-wheel-root .cw-led:nth-child(7){ bottom:15%; right:15%; transform:translate(50%,50%); animation-delay:.9s; } 302 #ctf-wheel-root .cw-led:nth-child(8){ bottom:15%; left:15%; transform:translate(-50%,50%); animation-delay:1.05s; } 303 @keyframes cw-led-blink{ 304 0%,100%{ opacity:1; filter:brightness(1.3); } 305 50%{ opacity:.2; filter:brightness(.4); } 306 } 307 308 /* The wheel */ 309 #ctf-wheel-root .cw-wheel{ 310 position:relative; z-index:1; width:100%; height:100%; border-radius:50%; 311 transition: transform 4.6s cubic-bezier(.16,.74,.12,1); 312 box-shadow: 313 0 0 0 6px rgba(255,255,255,.04), 314 0 0 0 7px color-mix(in srgb, var(--lvc) 60%, transparent), 315 0 0 40px color-mix(in srgb, var(--lvc) 45%, transparent), 316 0 18px 46px rgba(0,0,0,.6); 317 } 318 #ctf-wheel-root .cw-dome{ 319 position:absolute; z-index:2; inset:7px; border-radius:50%; pointer-events:none; 320 background:radial-gradient(120% 80% at 32% 18%, rgba(255,255,255,.35), rgba(255,255,255,.06) 38%, transparent 60%); 321 mix-blend-mode:screen; opacity:.7; 322 } 323 324 /* Metallic pointer */ 325 #ctf-wheel-root .cw-pointer{ 326 position:absolute; z-index:5; top:-16px; left:50%; transform:translateX(-50%); transform-origin:50% 90%; 327 width:28px; height:44px; filter:drop-shadow(0 4px 6px rgba(0,0,0,.6)); 328 } 329 #ctf-wheel-root .cw-pointer.tick{ animation:cw-tick .07s ease-out; } 330 @keyframes cw-tick{ 0%{transform:translateX(-50%) rotate(0)} 45%{transform:translateX(-50%) rotate(-13deg)} 100%{transform:translateX(-50%) rotate(0)} } 331 332 /* Center SPIN hub - BIG & TACTILE */ 333 #ctf-wheel-root .cw-hub{ 334 position:absolute; z-index:4; top:50%; left:50%; transform:translate(-50%,-50%); 335 width:110px; height:110px; border-radius:50%; cursor:pointer; 336 background:radial-gradient(120% 120% at 30% 25%, #2a1414, #14080a); 337 border:3px solid color-mix(in srgb, var(--lvc) 55%, transparent); 338 box-shadow:0 0 28px color-mix(in srgb, var(--lvc) 40%, transparent), inset 0 1px 2px rgba(255,255,255,.25), 0 8px 0 #0a0608; 339 display:flex; align-items:center; justify-content:center; 340 font-family:var(--orbitron); font-weight:900; font-size:18px; 341 color:color-mix(in srgb, var(--lvc) 80%, white); letter-spacing:.06em; 342 transition:transform .08s ease, box-shadow .18s ease; 343 } 344 #ctf-wheel-root .cw-hub:active{ 345 transform:translate(-50%,-46%); 346 box-shadow:0 0 28px color-mix(in srgb, var(--lvc) 40%, transparent), inset 0 1px 2px rgba(255,255,255,.25), 0 2px 0 #0a0608; 347 } 348 349 /* Hero SPIN NOW button */ 350 #ctf-wheel-root .cw-btn{ 351 position:relative; display:block; width:100%; margin-top:20px; padding:18px 20px; 352 font-family:var(--orbitron); font-size:18px; font-weight:900; letter-spacing:.08em; overflow:hidden; 353 color:#fff; border:none; border-radius:18px; cursor:pointer; 354 background:linear-gradient(135deg, #ff5252, #c81e1e); 355 box-shadow:0 0 30px rgba(239,32,32,.4), 0 8px 0 #8a0f0f, inset 0 1px 0 rgba(255,255,255,.3); 356 transition:transform .08s ease, box-shadow .18s ease, opacity .2s ease; 357 } 358 #ctf-wheel-root .cw-btn::after{ 359 content:""; position:absolute; top:0; left:-60%; width:40%; height:100%; 360 background:linear-gradient(100deg, transparent, rgba(255,255,255,.55), transparent); 361 transform:skewX(-18deg); animation:cw-sheen 3.2s ease-in-out infinite; 362 } 363 @keyframes cw-sheen{ 0%,60%{left:-60%} 85%,100%{left:140%} } 364 #ctf-wheel-root .cw-btn:hover:not(:disabled){ transform:translateY(-1px); } 365 #ctf-wheel-root .cw-btn:disabled{ opacity:.45; cursor:not-allowed; } 366 #ctf-wheel-root .cw-btn:disabled::after{ display:none; } 367 #ctf-wheel-root .cw-btn:active:not(:disabled){ 368 transform:translateY(2px); 369 box-shadow:0 0 20px rgba(239,32,32,.3), 0 3px 0 #8a0f0f, inset 0 1px 0 rgba(255,255,255,.3); 370 } 371 372 #ctf-wheel-root .cw-msg{ margin-top:14px; font-size:13px; text-align:center; min-height:20px; transition:opacity .2s; } 373 #ctf-wheel-root .cw-msg.is-win{ color:var(--accent-2); font-weight:800; font-size:15px; } 374 #ctf-wheel-root .cw-msg.is-warn{ color:var(--danger); } 375 #ctf-wheel-root .cw-msg.pop{ animation:cw-pop .5s cubic-bezier(.2,1.4,.4,1); } 376 @keyframes cw-pop{ 0%{transform:scale(.6); opacity:0}
376 60%{transform:scale(1.12)} 100%{transform:scale(1); opacity:1} } 377 378 #ctf-wheel-root .cw-level-tag{ 379 display:inline-block; font-size:11px; font-weight:700; padding:4px 11px; border-radius:999px; margin-bottom:6px; 380 color:var(--lvc); background:color-mix(in srgb, var(--lvc) 16%, transparent); 381 border:1px solid color-mix(in srgb, var(--lvc) 42%, transparent); 382 } 383 384 /* Legend - scoreboard style */ 385 #ctf-wheel-root .cw-legend{ margin-top:18px; } 386 #ctf-wheel-root .cw-leg-head{ 387 font-size:9px; letter-spacing:.15em; text-transform:uppercase; color:var(--muted); 388 font-weight:700; margin-bottom:12px; text-align:center; 389 } 390 #ctf-wheel-root .cw-leg-row{ 391 display:flex; align-items:center; gap:10px; padding:10px 14px; 392 background:rgba(255,255,255,.03); border:1px solid rgba(255,255,255,.05); border-radius:12px; 393 margin-bottom:6px; transition:background .15s ease; 394 } 395 #ctf-wheel-root .cw-leg-row:hover{ background:rgba(255,255,255,.06); } 396 #ctf-wheel-root .cw-leg-dot{ flex:0 0 auto; width:10px; height:10px; border-radius:50%; 397 box-shadow:0 0 8px currentColor; } 398 #ctf-wheel-root .cw-leg-cat{ font-weight:700; font-size:13px; color:var(--ink); } 399 #ctf-wheel-root .cw-leg-count{ margin-left:auto; color:var(--muted); font-size:11.5px; 400 font-variant-numeric:tabular-nums; } 401 402 #ctf-wheel-root .cw-pending{ margin-top:18px; border-top:1px solid var(--stroke); padding-top:15px; } 403 #ctf-wheel-root .cw-pending h4{ font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--muted); margin:0 0 11px; } 404 #ctf-wheel-root .cw-lab{ 405 display:flex; align-items:center; justify-content:space-between; gap:11px; 406 background:var(--glass); border:1px solid var(--stroke); border-radius:var(--r-md); 407 padding:11px 13px; margin-bottom:9px; backdrop-filter:blur(8px); 408 } 409 #ctf-wheel-root .cw-lab-name{ font-size:13px; font-weight:600; } 410 #ctf-wheel-root .cw-lab-exp{ font-size:11px; color:var(--danger); margin-top:3px; } 411 #ctf-wheel-root .cw-launch{ 412 font-size:12px; font-weight:800; color:#0a0e1a; border:none; border-radius:9px; padding:9px 13px; cursor:pointer; white-space:nowrap; 413 background:linear-gradient(180deg, color-mix(in srgb, var(--accent-2) 90%, white), var(--accent-2)); 414 box-shadow:0 4px 14px color-mix(in srgb, var(--accent-2) 35%, transparent); 415 } 416 417 #ctf-wheel-root .cw-burst{ 418 position:absolute; z-index:6; top:50%; left:50%; width:10px; height:10px; border-radius:50%; 419 border:2px solid var(--lvc); transform:translate(-50%,-50%) scale(0); opacity:0; pointer-events:none; 420 } 421 #ctf-wheel-root .cw-burst.go{ animation:cw-burst .7s ease-out; } 422 @keyframes cw-burst{ 0%{transform:translate(-50%,-50%) scale(0); opacity:.9} 100%{transform:translate(-50%,-50%) scale(26); opacity:0} } 423 424 @media (prefers-reduced-motion: reduce){ 425 #ctf-wheel-root::before, 426 #ctf-wheel-root .cw-glow, 427 #ctf-wheel-root .cw-btn::after, 428 #ctf-wheel-root .cw-led, 429 #ctf-wheel-root .cw-burst.go { animation:none !important; } 430 #ctf-wheel-root .cw-wheel{ transition:transform .3s linear; } 431 } 432</style> 433`,o=` 434(function(){ 435 'use strict'; 436 437 var CONFIG = { 438 API_BASE: 'https://your-api.example.com', 439 AUTH: 'cookie', 440 TOKEN_GETTER: function(){ return (window.MY_APP && window.MY_APP.token) || ''; }, 441 SPIN_DURATION_MS: 4600, 442 DEMO_MODE: true 443 }; 444 445 function demoReq(path, method, body){ 446 return new Promise(function(resolve){ 447 setTimeout(function(){ 448 if(path.indexOf('/api/wheel/status')===0){ 449 resolve({ canSpin:true, pendingLabs:[] }); 450 } else if(path.indexOf('/api/wheel/spin')===0){ 451 var segs = state.segs || []; 452 var idx = (typeof pickWeightedIndex==='function') ? pickWeightedIndex() : Math.floor(Math.random()*segs.length); 453 var seg = segs[idx] || {label:'Mystery',cat:'Drop',discount:'30% OFF',prize:'Mystery Drop'}; 454 resolve({ segmentIndex: idx, prize:{ name: seg.prize || (seg.label+' â '+seg.cat), discount: seg.discount || seg.label } }); 455 } else { resolve({}); } 456 }, 220); 457 }); 458 } 459 460 var LEVELS = [ 461 { id:'Starter', badge:'01', desc:'' }, 462 { id:'Explorer', badge:'02', desc:'' }, 463 { id:'Operator', badge:'03', desc:'' }, 464 { id:'Elite', badge:'04', desc:'' } 465 ]; 466 467 var SEED = {"Starter":[{"label":"Break the DB","cat":"SQL Injection","labs":5,"ctf":3},{"label":"Own the Server","cat":"LFI / RCE","labs":7,"ctf":5},{"label":"Become Root","cat":"Linux PrivEsc","labs":11,"ctf":7},{"label":"Dig the Memory","cat":"Forensics","labs":8,"ctf":6},{"label":"Hunt the Logs","cat":"Event Logs","labs":5,"ctf":4},{"label":"Break the Cipher","cat":"Cryptography","labs":8,"ctf":5},{"label":"First Blood","cat":"Tooling","labs":4,"ctf":2}],"Explorer":[{"label":"Break the DB","cat":"SQL Injection","labs":5,"ctf":3},{"label":"Own the Server","cat":"LFI / RCE","labs":7,"ctf":5},{"label":"Crack the CMS","cat":"WordPress","labs":8,"ctf":5},{"label":"Dig the Memory","cat":"Forensics","labs":8,"ctf":6},{"label":"Reverse It","cat":"Malware RE","labs":7,"ctf":5},{"label":"Find the Hidden","cat":"Steganography","labs":4,"ctf":3},{"label":"Track the Target","cat":"OSINT","labs":2,"ctf":1}],"Operator":[{"label":"Break the DB","cat":"SQL Injection","labs":5,"ctf":3},{"label":"Own the Server","cat":"LFI / RCE","labs":7,"ctf":5},{"label":"Sneak a Shell","cat":"File Upload","labs":3,"ctf":2},{"label":"Crack the CMS","cat":"WordPress","labs":8,"ctf":5},{"label":"Become Root","cat":"Linux PrivEsc","labs":11,"ctf":7},{"label":"Get SYSTEM","cat":"Win PrivEsc","labs":4,"ctf":2},{"label":"Read the Wire","cat":"Network Forensics","labs":5,"ctf":3},{"label":"Dig the Memory","cat":"Forensics","labs":8,"ctf":6}],"Elite":[{"label":"Seize the Domain","cat":"AD / Kerberos","labs":2,"ctf":1},{"label":"Read the Wire","cat":"Network Forensics","labs":5,"ctf":3},{"label":"Smash the Stack","cat":"Buffer Overflow","labs":2,"ctf":1},{"label":"Break the Cipher","cat":"Cryptography","labs":8,"ctf":5},{"label":"Breach the Cloud","cat":"Cloud","labs":1,"ctf":0},{"label":"Hack the Plant","cat":"ICS / OT","labs":2,"ctf":1},{"label":"Poison the Model","cat":"AI / ML","labs":3,"ctf":2}]}; 468 469 var SEG_COLORS = ['#ef2222','#1a1a1a','#ff5252','#2a1414','#c81e1e','#0f0f0f','#ff7575','#8a0f0f']; 470 var LV_VAR = { Starter:'--lv-starter', Explorer:'--lv-explorer', Operator:'--lv-operator', Elite:'--lv-elite' }; 471 472 var root = document.getElementById('ctf-wheel-root'); 473 if(!root) return; 474 var state = { level:null, spinning:false, canSpin:false, segs:[] }; 475 476 function headers(){ var h={'Content-Type':'application/json'}; 477 if(CONFIG.AUTH==='token') h['Authorization']='Bearer '+CONFIG.TOKEN_GETTER(); return h; } 478 function req(path,method,body){ 479 if(CONFIG.DEMO_MODE) return demoReq(path, method, body); 480 return fetch(CONFIG.API_BASE+path,{ method:method||'GET', headers:headers(), 481 credentials:CONFIG.AUTH==='cookie'?'include':'same-origin', 482 body:body?JSON.stringify(body):undefined 483 }).then(function(r){ 484 if(r.status===401) throw new Error('NOT_LOGGED_IN'); 485 if(!r.ok) throw new Error('HTTP_'+r.status); return r.json(); 486 }); 487 } 488 489 // Hybrid prize set â promotes labs + CTFs, every spin wins. 490 // weight = relative odds of landing here (higher = more frequent). 491 var PRIZES = [ 492 { label:'70% OFF', cat:'CTF Bundle', discount:'70% OFF', prize:'Any CTF Bundle', weight:1 },
493 { label:'50% OFF', cat:'Labs Library', discount:'50% OFF', prize:'Labs Library', weight:3 }, 494 { label:'FREE CTF', cat:'1 Challenge', discount:'FREE', prize:'1 CTF Challenge', weight:2 }, 495 { label:'30% OFF', cat:'All-Access', discount:'30% OFF', prize:'All-Access Subscription', weight:4 }, 496 { label:'FREE LAB', cat:'24h Access', discount:'FREE', prize:'Hands-On Lab (24h)', weight:2 }, 497 { label:'40% OFF', cat:'Starter Pack', discount:'40% OFF', prize:'Starter Pack', weight:4 }, 498 { label:'20% OFF', cat:'Sitewide', discount:'20% OFF', prize:'Sitewide Purchase', weight:5 }, 499 { label:'MYSTERY', cat:'Surprise Drop', discount:'60% OFF', prize:'Mystery Drop', weight:1 } 500 ]; 501 502 function buildCombinedSegs(){ return PRIZES; } 503 504 function pickWeightedIndex(){ 505 var total = 0; 506 for(var i=0;i<PRIZES.length;i++) total += PRIZES[i].weight; 507 var r = Math.random()*total, acc = 0; 508 for(var j=0;j<PRIZES.length;j++){ 509 acc += PRIZES[j].weight; 510 if(r <= acc) return j; 511 } 512 return PRIZES.length-1; 513 } 514 515 516 function buildWheelSVG(){ 517 var segs = state.segs || []; 518 var n = segs.length || 1; 519 var cx=160, cy=160, r=160; 520 var paths='', labels=''; 521 for(var i=0;i<n;i++){ 522 var a0 = (i/n)*2*Math.PI - Math.PI/2; 523 var a1 = ((i+1)/n)*2*Math.PI - Math.PI/2; 524 var x0 = cx + r*Math.cos(a0), y0 = cy + r*Math.sin(a0); 525 var x1 = cx + r*Math.cos(a1), y1 = cy + r*Math.sin(a1); 526 var large = ((a1-a0) > Math.PI) ? 1 : 0; 527 var col = SEG_COLORS[i % SEG_COLORS.length]; 528 paths += '<path d="M'+cx+' '+cy+' L'+x0+' '+y0+' A'+r+' '+r+' 0 '+large+' 1 '+x1+' '+y1+' Z" fill="'+col+'" stroke="rgba(0,0,0,.35)" stroke-width="1.5"/>'; 529 var am = (a0+a1)/2; 530 var rot = (am*180/Math.PI) + 90; 531 var lx1 = cx + (r*0.70)*Math.cos(am); 532 var ly1 = cy + (r*0.70)*Math.sin(am); 533 var lx2 = cx + (r*0.50)*Math.cos(am); 534 var ly2 = cy + (r*0.50)*Math.sin(am); 535 var head = esc((segs[i] && segs[i].label) || ''); 536 var sub = esc((segs[i] && segs[i].cat) || ''); 537 if(head.length>10) head = head.slice(0,9)+'â¦'; 538 if(sub.length>14) sub = sub.slice(0,13)+'â¦'; 539 labels += '<text x="'+lx1+'" y="'+ly1+'" fill="#fff" font-family="Outfit, sans-serif" font-size="13" font-weight="900" text-anchor="middle" dominant-baseline="middle" transform="rotate('+rot+' '+lx1+' '+ly1+')" style="paint-order:stroke;stroke:rgba(0,0,0,.45);stroke-width:2.5px">'+head+'</text>'; 540 labels += '<text x="'+lx2+'" y="'+ly2+'" fill="rgba(255,255,255,.85)" font-family="Plus Jakarta Sans, sans-serif" font-size="9" font-weight="600" text-anchor="middle" dominant-baseline="middle" transform="rotate('+rot+' '+lx2+' '+ly2+')" style="paint-order:stroke;stroke:rgba(0,0,0,.4);stroke-width:1.8px">'+sub+'</text>'; 541 } 542 return '<svg class="cw-wheel" viewBox="0 0 320 320" xmlns="http://www.w3.org/2000/svg">'+paths+labels+'</svg>'; 543 } 544 545 function renderWheel(){ 546 state.level='All'; 547 state.segs=buildCombinedSegs(); 548 root.style.setProperty('--lvc', getComputedStyle(root).getPropertyValue('--accent-2').trim()); 549 root.innerHTML= 550 '<div class="cw-grid">'+ 551 '<div class="cw-left">'+ 552 '<div class="cw-offer">'+ 553 '<div class="cw-ribbon">'+ 554 '<span class="cw-ribbon-top">Limited Time</span>'+ 555 '<span class="cw-ribbon-main">Special Offer</span>'+ 556 '</div>'+ 557 '<p class="cw-offer-pre">For the First Time Ever</p>'+ 558 '<h3 class="cw-offer-h">Hands-On Virtual Labs<br/>& Capture The Flags</h3>'+ 559 '<div class="cw-offer-script">At Exclusive Discounts!</div>'+ 560 '<span class="cw-offer-cta">Spin the Wheel & Save Big</span>'+ 561 '</div>'+ 562 '<h1 class="cw-promo-h"><span class="cw-num">70% OFF</span> CTF Challenges & Hands-On Labs</h1>'+ 563 '<p class="cw-promo-sub">One spin. <b>Every wedge wins.</b> Unlock instant discounts — or a free lab — across our entire library of real-world cybersecurity challenges.</p>'+ 564 '<div class="cw-inv">
564'+ 565 '<div class="cw-inv-cell"><div class="cw-inv-num">500<span style="color:#ff5252">+</span></div><div class="cw-inv-lbl">Hands-On Labs</div></div>'+ 566 '<div class="cw-inv-cell"><div class="cw-inv-num">400<span style="color:#ff5252">+</span></div><div class="cw-inv-lbl">CTF Challenges</div></div>'+ 567 '<div class="cw-inv-cell"><div class="cw-inv-num is-red">70%</div><div class="cw-inv-lbl">Top Discount</div></div>'+ 568 '</div>'+ 569 '<div class="cw-perks">'+ 570 '<div class="cw-perk"><span class="cw-perk-ic">â</span><span><b>Capture The Flag</b> — web, crypto, forensics, AD & more</span></div>'+ 571 '<div class="cw-perk"><span class="cw-perk-ic">â¡</span><span><b>Hands-on Virtual Labs</b> spin up in seconds</span></div>'+ 572 '<div class="cw-perk"><span class="cw-perk-ic">ð¯</span><span>Instant coupon — <b>redeem in checkout</b></span></div>'+ 573 '</div>'+ 574 '<div class="cw-trust">'+ 575 '<span><b>2,400+</b> learners this month</span>'+ 576 '<span class="dot"></span>'+ 577 '<span>No signup needed</span>'+ 578 '<span class="dot"></span>'+ 579 '<span>Coupon valid for 10 min</span>'+ 580 '</div>'+ 581 '</div>'+ 582 '<div class="cw-right">'+ 583 '<div class="cw-stage" id="cw-stage">'+ 584 '<div class="cw-glow"></div>'+ 585 '<div class="cw-marquee">'+ 586 '<div class="cw-led"></div><div class="cw-led"></div>'+ 587 '<div class="cw-led"></div><div class="cw-led"></div>'+ 588 '<div class="cw-led"></div><div class="cw-led"></div>'+ 589 '<div class="cw-led"></div><div class="cw-led"></div>'+ 590 '</div>'+ 591 buildWheelSVG()+ 592 '<div class="cw-dome"></div>'+ 593 '<svg class="cw-pointer" id="cw-pointer" viewBox="0 0 28 44">'+ 594 '<defs><linearGradient id="pg" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#fff"/><stop offset=".5" stop-color="#c3c9dd"/><stop offset="1" stop-color="#8890a8"/></linearGradient></defs>'+ 595 '<path d="M14 44 L2 8 Q14 -4 26 8 Z" fill="url(#pg)"/>'+ 596 '<circle cx="14" cy="10" r="4" fill="rgba(10,14,26,.5)"/>'+ 597 '<rect x="12" y="0" width="4" height="8" rx="2" fill="#e2e8f0"/>'+ 598 '</svg>'+ 599 '<div class="cw-hub" id="cw-hub">SPIN</div>'+ 600 '<div class="cw-burst" id="cw-burst"></div>'+ 601 '</div>'+ 602 '<button class="cw-btn" id="cw-spin" disabled>Loadingâ¦</button>'+ 603 '<p class="cw-msg" id="cw-msg"></p>'+ 604 '<div class="cw-pending" id="cw-pending" hidden></div>'+ 605 '</div>'+ 606 '</div>'; 607 608 root.querySelector('#cw-spin').addEventListener('click', onSpin); 609 var hub=root.querySelector('#cw-hub'); 610 if(hub) hub.addEventListener('click', onSpin); 611 renderPending([]); 612 } 613
614 function renderStatus(s){ 615 state.canSpin=!!s.canSpin; 616 var btn=root.querySelector('#cw-spin'), msg=root.querySelector('#cw-msg'); 617 if(!btn) return; msg.className='cw-msg'; 618 if(s.canSpin){ btn.disabled=false; btn.textContent='SPIN NOW'; msg.textContent=''; } 619 else{ 620 btn.disabled=true; 621 if(s.blockedReason==='UNLAUNCHED_LAB'){ btn.textContent='Launch yours first'; 622 msg.className='cw-msg is-warn'; msg.textContent='You have one waiting. Launch it to earn your next spin.'; } 623 else if(s.blockedReason==='OUT_OF_STOCK'){ btn.textContent='All claimed'; 624 msg.className='cw-msg is-warn'; msg.textContent='Everything at this level is taken right now â check back soon.'; } 625 else if(s.nextSpinInSeconds>0){ startCooldown(s.nextSpinInSeconds); } 626 else{ btn.textContent='SPIN NOW'; } 627 } 628 renderPending(s.pendingLabs||[]); 629 } 630 631 function renderPending(labs){ 632 var box=root.querySelector('#cw-pending'); if(!box) return; 633 if(!labs.length){ box.hidden=true; box.innerHTML=''; return; } 634 box.hidden=false; 635 var h='<h4>Your challenges</h4>'; 636 labs.forEach(function(l){ 637 var exp=l.expiresInHours!=null?(l.expiresInHours<=24?'Expires in '+l.expiresInHours+'h â use it!':'Expires in '+Math.ceil(l.expiresInHours/24)+' days'):''; 638 h+='<div class="cw-lab"><div><div class="cw-lab-name">'+esc(l.name)+'</div>'+(exp?'<div class="cw-lab-exp">'+exp+'</div>':'')+'</div>'+ 639 '<button class="cw-launch" data-url="'+esc(l.launchUrl)+'">Launch</button></div>'; 640 }); 641 box.innerHTML=h; 642 Array.prototype.forEach.call(box.querySelectorAll('.cw-launch'),function(b){ 643 b.addEventListener('click',function(){ var u=b.getAttribute('data-url'); if(u) window.open(u,'_blank','noopener'); }); 644 }); 645 } 646 647 var cd=null; 648 function startCooldown(sec){ 649 var btn=root.querySelector('#cw-spin'); if(cd) clearInterval(cd); 650 function tick(){ if(sec<=0){ clearInterval(cd); loadStatus(); return; } 651 var hh=Math.floor(sec/3600), m=Math.floor((sec%3600)/60), s=sec%60; 652 btn.textContent='Next spin in '+(hh?hh+'h ':'')+(m<10?'0':'')+m+'m '+(s<10?'0':'')+s+'s'; sec--; } 653 tick(); cd=setInterval(tick,1000); 654 } 655 656 function onSpin(){ 657 if(state.spinning||!state.canSpin) return; 658 state.spinning=true; 659 var btn=root.querySelector('#cw-spin'), msg=root.querySelector('#cw-msg'), stage=root.querySelector('#cw-stage'); 660 btn.disabled=true; btn.textContent='SPINNINGâ¦'; msg.className='cw-msg'; msg.textContent=''; 661 stage.classList.add('is-spinning'); 662 req('/api/wheel/spin','POST',{ level:state.level }).then(function(res){ 663 animateTo(res.segmentIndex, function(){ 664 stage.classList.remove('is-spinning'); 665 burst(); 666 msg.className='cw-msg is-win pop'; 667 msg.innerHTML='ð You unlocked: '+esc(res.prize.name)+' â redirectingâ¦'; 668 var d = res.prize.discount || '30% OFF'; 669 setTimeout(function(){ 670 window.location.href='/spin-the-wheel/result?discount='+encodeURIComponent(d)+'&prize='+encodeURIComponent(res.prize.name); 671 }, 900); 672 state.spinning=false; 673 }); 674 }).catch(function(err){ 675 stage.classList.remove('is-spinning'); state.spinning=false; 676 msg.className='cw-msg is-warn'; 677 msg.textContent= err.message==='NOT_LOGGED_IN'?'Please log in to spin.':'Something went wrong. Try again.'; 678 btn.disabled=false; btn.textContent='SPIN NOW'; 679 }); 680 } 681 682 function animateTo(index, done){ 683 var wheel=root.querySelector('.cw-wheel'), pointer=root.querySelector('#cw-pointer'); 684 var n=state.segs.length, step=360/n; 685 var target=360*6-(index*step+step/2); 686 wheel.style.transform='rotate('+target+'deg)'; 687 var dur=CONFIG.SPIN_DURATION_MS, start=performance.now(); 688 function eased(t){ return 1-Math.pow(1-t,3); } 689 var lastWedge=-1; 690 function frame(now){ 691 var t=Math.min(1,(now-start)/dur); 692 var deg=eased(t)*target; 693 var wedge=Math.floor((deg%360)/step); 694 if(wedge!==lastWedge){ lastWedge=wedge; flickPointer(pointer); } 695 if(t<1) requestAnimationFrame(frame); 696 } 697 requestAnimationFrame(frame); 698 setTimeout(done, dur+120); 699 } 700 701 function flickPointer(pointer){ 702 pointer.classList.remove('tick'); void pointer.offsetWidth; pointer.classList.add('tick'); 703 if(navigator.vibrate){ try{ navigator.vibrate(8); }catch(e){} } 704 } 705 706 function burst(){ 707 var b=root.querySelector('#cw-burst'); if(!b) return; 708 b.classList.remove('go'); void b.offsetWidth; b.classList.add('go'); 709 } 710 711 function loadStatus(){
712 req('/api/wheel/status?level='+encodeURIComponent(state.level)).then(renderStatus).catch(function(err){ 713 var msg=root.querySelector('#cw-msg'), btn=root.querySelector('#cw-spin'); if(!msg) return; 714 msg.className='cw-msg is-warn'; 715 msg.textContent= err.message==='NOT_LOGGED_IN'?'Please log in to spin.':'Couldnât load the wheel. Refresh to retry.'; 716 btn.textContent='Unavailable'; btn.disabled=true; 717 }); 718 } 719 720 function esc(s){ return String(s==null?'':s).replace(/[&<>"']/g,function(c){ 721 return ({'&':'&','<':'<','>':'>','"':'"',"'":'''})[c]; }); } 722 723 renderWheel(); 724 loadStatus(); 725})(); 726`;function i(){return r.useEffect(()=>{document.title="Spin the Wheel";const e=document.createElement("script");return e.textContent=o,document.body.appendChild(e),()=>{document.body.removeChild(e)}},[]),t.jsx("div",{style:{minHeight:"100vh",background:"hsl(var(--brand-dark))",display:"flex",alignItems:"center",justifyContent:"center",padding:"24px"},children:t.jsx("div",{style:{width:"100%",maxWidth:1240},dangerouslySetInnerHTML:{__html:a}})})}export{i as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.