2026-07-21 10:27:05 +02:00
<!doctype html>
2026-07-26 21:43:35 +02:00
< html lang = "en" >
2026-07-21 10:27:05 +02:00
< head >
< meta charset = "utf-8" >
2026-07-21 10:46:55 +02:00
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
2026-07-22 10:16:51 +02:00
< title > PLM Lottery</ title >
2026-07-22 15:39:47 +02:00
< link rel = "icon" type = "image/svg+xml" href = "/logo.svg" >
2026-07-22 23:20:40 +02:00
< link rel = "stylesheet" href = "/style.css" >
2026-07-21 10:27:05 +02:00
</ head >
< body >
2026-07-26 21:43:35 +02:00
< nav class = "hidden" id = "app-navbar" data-i18n-aria-label = "nav.ariaSections" aria-label = "Sezioni" >
2026-07-22 10:36:36 +02:00
< div class = "app-navbar-top" >
2026-07-22 14:50:17 +02:00
< div class = "app-navbar-top-inner" >
2026-07-22 15:39:47 +02:00
< span class = "brand" >
< img class = "brand-mark" src = "/logo.svg" alt = "" >
PLM Lottery
</ span >
2026-07-22 14:50:17 +02:00
< div class = "app-navbar-account" >
< span class = "navbar-username" id = "dash-username" ></ span >
< span class = "navbar-balance mono" >
< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< rect x = "2" y = "7" width = "20" height = "14" rx = "2" />< path d = "M16 21V5a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v16" /></ svg >
< span id = "navbar-balance" > — PLM</ span >
</ span >
2026-07-26 21:43:35 +02:00
< a class = "link icon-link" href = "/guida" target = "_blank" rel = "noopener" data-i18n-title = "nav.guideTitle" title = "Guida" data-i18n-aria-label = "nav.guideAria" aria-label = "Apri la guida utente" >
2026-07-22 14:50:17 +02:00
< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< circle cx = "12" cy = "12" r = "10" />< path d = "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 2-3 4" />< path d = "M12 17h.01" /></ svg >
</ a >
2026-07-27 08:35:47 +02:00
< a class = "link icon-link" href = "/report-bug" target = "_blank" rel = "noopener" data-i18n-title = "nav.bugReport" title = "Segnala un bug" data-i18n-aria-label = "nav.bugReport" aria-label = "Segnala un bug" >
< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< circle cx = "12" cy = "12" r = "10" />< path d = "M12 8v5" />< path d = "M12 16h.01" /></ svg >
2026-07-22 14:50:17 +02:00
</ a >
2026-07-26 21:43:35 +02:00
< button class = "link icon-link" onclick = "logout()" data-i18n-title = "nav.logoutTitle" title = "Esci" data-i18n-aria-label = "nav.logoutAria" aria-label = "Esci dall'account" >
2026-07-22 14:50:17 +02:00
< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< path d = "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />< path d = "M16 17l5-5-5-5M21 12H9" /></ svg >
</ button >
</ div >
2026-07-22 10:36:36 +02:00
</ div >
</ div >
< div class = "app-navbar-tabs" >
< button class = "navbar-tab active" id = "nav-deposit" onclick = "switchPanel('deposit')" >
< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< rect x = "2" y = "7" width = "20" height = "14" rx = "2" />< path d = "M16 21V5a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v16" /></ svg >
2026-07-26 21:43:35 +02:00
< span data-i18n = "nav.deposit" > Deposito</ span >
2026-07-22 10:36:36 +02:00
</ button >
< button class = "navbar-tab" id = "nav-bet" onclick = "switchPanel('bet')" >
< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< rect x = "2" y = "6" width = "20" height = "12" rx = "2" />< path d = "M6 12h.01M12 12h.01M18 12h.01" /></ svg >
2026-07-26 21:43:35 +02:00
< span data-i18n = "nav.bet" > Bet</ span >
2026-07-22 10:36:36 +02:00
</ button >
< button class = "navbar-tab" id = "nav-withdraw" onclick = "switchPanel('withdraw')" >
< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< path d = "M12 19V5M5 12l7-7 7 7" /></ svg >
2026-07-26 21:43:35 +02:00
< span data-i18n = "nav.withdraw" > Prelievo</ span >
2026-07-22 10:36:36 +02:00
</ button >
2026-07-22 12:00:09 +02:00
< button class = "navbar-tab" id = "nav-profile" onclick = "switchPanel('profile')" >
< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< path d = "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />< circle cx = "12" cy = "7" r = "4" /></ svg >
2026-07-26 21:43:35 +02:00
< span data-i18n = "nav.profile" > Profilo</ span >
2026-07-22 12:00:09 +02:00
</ button >
2026-07-22 10:36:36 +02:00
</ div >
</ nav >
< div class = "app-shell" >
2026-07-22 10:16:51 +02:00
< div class = "chain-bar" id = "chain-bar" >
< span class = "chain-status-pill" >
< span class = "status-dot" id = "chain-status-dot" ></ span >
2026-07-26 21:55:37 +02:00
<!-- No data-i18n on this one or on #draw-label below: both are written by
app.js from live state, and letting applyStaticTranslations() also own
them made a language switch flash (or, here, assert) a stale value. -->
< span id = "chain-status-label" > Connecting…</ span >
2026-07-26 21:43:35 +02:00
</ span >
< span class = "chain-bar-right" >
< span class = "chain-block mono" id = "chain-block" > —</ span >
<!-- Deliberately here and not in the navbar: the navbar is hidden until login,
which would leave the landing page and the login form untranslatable for
anyone who can't read the browser-detected default. -->
< select id = "lang-switcher" class = "lang-switcher" onchange = "setLanguage(this.value)" aria-label = "Language" >
< option value = "en" > English</ option >
< option value = "it" > Italiano</ option >
< option value = "es" > Español</ option >
< option value = "fr" > Français</ option >
< option value = "de" > Deutsch</ option >
< option value = "ru" > Русский</ option >
< option value = "zh" > 中文</ option >
</ select >
2026-07-22 10:16:51 +02:00
</ span >
</ div >
2026-07-22 10:36:36 +02:00
< div class = "maintenance-banner hidden" id = "maintenance-banner" >
< span > ⚠️</ span >
2026-07-26 21:43:35 +02:00
< span data-i18n = "maintenance.banner" > Manutenzione in programma: il round in corso viene completato regolarmente (vincitore incluso), ma il round successivo non si aprirà finché la manutenzione non sarà terminata.</ span >
2026-07-22 10:36:36 +02:00
</ div >
2026-07-22 10:16:51 +02:00
< section id = "landing-hero" class = "hero" >
2026-07-21 10:46:55 +02:00
< h1 > PLM Lottery</ h1 >
2026-07-26 21:43:35 +02:00
< p class = "lead" data-i18n = "hero.lead" > Deposita PLM, entra nel round con una quota fissa, e se viene estratto il tuo numero vinci il montepremi.</ p >
2026-07-22 10:16:51 +02:00
< div class = "hero-steps" >
< div class = "hero-step" >
< div class = "step-icon" >< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< rect x = "2" y = "7" width = "20" height = "14" rx = "2" />< path d = "M16 21V5a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v16" /></ svg ></ div >
2026-07-26 21:43:35 +02:00
< div class = "step-title" data-i18n = "hero.step1.title" > 1. Deposita</ div >
< div class = "step-hint" data-i18n = "hero.step1.hint" > Ricevi un indirizzo PLM personale, tuo per sempre</ div >
2026-07-22 10:16:51 +02:00
</ div >
< div class = "hero-step" >
< div class = "step-icon" >< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< rect x = "2" y = "6" width = "20" height = "12" rx = "2" />< path d = "M6 12h.01M12 12h.01M18 12h.01" /></ svg ></ div >
2026-07-26 21:43:35 +02:00
< div class = "step-title" data-i18n = "hero.step2.title" > 2. Gioca</ div >
< div class = "step-hint" data-i18n = "hero.step2.hint" > Una bet a quota fissa per entrare nel round corrente</ div >
2026-07-22 10:16:51 +02:00
</ div >
< div class = "hero-step" >
< div class = "step-icon" >< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< path d = "M8 21h8M12 17v4M7 4h10v4a5 5 0 0 1-10 0V4Z" />< path d = "M7 5H4a1 1 0 0 0-1 1v1a4 4 0 0 0 4 4M17 5h3a1 1 0 0 1 1 1v1a4 4 0 0 1-4 4" /></ svg ></ div >
2026-07-26 21:43:35 +02:00
< div class = "step-title" data-i18n = "hero.step3.title" > 3. Vinci</ div >
< div class = "step-hint" data-i18n = "hero.step3.hint" > Estrazione dal blocco, montepremi accreditato subito</ div >
2026-07-22 10:16:51 +02:00
</ div >
</ div >
< div class = "trust-row" >
2026-07-26 21:43:35 +02:00
< span class = "trust-pill" >< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< path d = "M20 6 9 17l-5-5" /></ svg >< span data-i18n = "trust.fixedRate" > Quota fissa dichiarata</ span ></ span >
< span class = "trust-pill" >< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< path d = "M20 6 9 17l-5-5" /></ svg >< span data-i18n = "trust.blockHash" > Estrazione da hash di blocco</ span ></ span >
< span class = "trust-pill" >< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< path d = "M20 6 9 17l-5-5" /></ svg >< span data-i18n = "trust.freeWithdraw" > Prelievo libero in ogni momento</ span ></ span >
2026-07-22 10:16:51 +02:00
</ div >
</ section >
2026-07-21 10:27:05 +02:00
2026-07-21 10:46:55 +02:00
< section id = "auth-section" class = "card" >
< div class = "tabs" >
2026-07-26 21:43:35 +02:00
< div class = "tab active" id = "tab-login" onclick = "switchTab('login')" data-i18n = "auth.tabLogin" > Login</ div >
< div class = "tab" id = "tab-register" onclick = "switchTab('register')" data-i18n = "auth.tabRegister" > Registrati</ div >
2026-07-21 10:46:55 +02:00
</ div >
< div class = "tab-panel active" id = "panel-login" >
2026-07-26 21:43:35 +02:00
< label for = "login-username" data-i18n = "auth.username" > Username</ label >
2026-07-21 10:46:55 +02:00
< input id = "login-username" autocomplete = "username" >
2026-07-26 21:43:35 +02:00
< label for = "login-password" data-i18n = "auth.password" > Password</ label >
2026-07-21 10:46:55 +02:00
< input id = "login-password" type = "password" autocomplete = "current-password" >
2026-07-26 21:43:35 +02:00
< button onclick = "login()" id = "login-btn" data-i18n = "auth.loginBtn" > Accedi</ button >
2026-07-21 10:46:55 +02:00
</ div >
< div class = "tab-panel" id = "panel-register" >
2026-07-26 21:43:35 +02:00
< label for = "reg-username" data-i18n = "auth.username" > Username</ label >
2026-07-27 00:35:14 +02:00
< input id = "reg-username" autocomplete = "username" minlength = "3" maxlength = "32" pattern = "[A-Za-z0-9_.\-]+" required >
2026-07-26 21:43:35 +02:00
< label for = "reg-password" data-i18n = "auth.password" > Password</ label >
2026-07-27 00:35:14 +02:00
< input id = "reg-password" type = "password" autocomplete = "new-password" minlength = "8" required >
2026-07-26 21:43:35 +02:00
< label for = "reg-password-confirm" data-i18n = "auth.passwordConfirm" > Conferma password</ label >
2026-07-27 00:35:14 +02:00
< input id = "reg-password-confirm" type = "password" autocomplete = "new-password" minlength = "8" required >
2026-07-26 21:43:35 +02:00
< button onclick = "register()" id = "register-btn" data-i18n = "auth.registerBtn" > Crea account</ button >
2026-07-21 10:27:05 +02:00
</ div >
</ section >
< section id = "dashboard-section" class = "hidden" >
2026-07-22 14:50:17 +02:00
< div class = "card round-card" id = "round-card" >
2026-07-21 16:03:42 +02:00
< div class = "row-between" id = "round-normal-row" >
2026-07-21 10:57:39 +02:00
< h2 id = "round-title" > Round —</ h2 >
< span class = "mono" id = "round-timer" style = "font-size:1.1rem;font-weight:700" > --:--</ span >
</ div >
2026-07-21 16:03:42 +02:00
< div class = "row-between" style = "margin-top:10px" id = "round-stats-row" >
2026-07-21 10:57:39 +02:00
< div >
2026-07-26 21:43:35 +02:00
< div class = "hint" style = "margin-bottom:2px" data-i18n = "round.players" > Giocatori</ div >
2026-07-21 10:57:39 +02:00
< span class = "mono" id = "round-players" > —</ span >
</ div >
< div style = "text-align:right" >
2026-07-26 21:43:35 +02:00
< div class = "hint" style = "margin-bottom:2px" data-i18n = "round.jackpot" > Jackpot</ div >
2026-07-21 10:57:39 +02:00
< span class = "mono" id = "round-jackpot" > —</ span > < span class = "balance-unit" > PLM</ span >
</ div >
</ div >
2026-07-21 16:03:42 +02:00
< div class = "draw-state" id = "draw-state" >
< div class = "draw-spinner" ></ div >
2026-07-26 21:55:37 +02:00
< div class = "draw-label" id = "draw-label" > Drawing the winner…</ div >
2026-07-21 16:03:42 +02:00
</ div >
< div class = "hidden" id = "draw-result" ></ div >
2026-07-21 10:57:39 +02:00
</ div >
2026-07-21 10:52:06 +02:00
< div class = "dash-panel active" id = "panel-deposit" >
< div class = "card" >
2026-07-26 21:43:35 +02:00
< h2 data-i18n = "deposit.balanceTitle" > Saldo interno</ h2 >
< p class = "hint" data-i18n = "deposit.balanceHint" > Aggiornato dopo 1 conferma sulla rete</ p >
2026-07-21 10:52:06 +02:00
< div class = "row-between" >
< div >< span class = "balance-value mono" id = "dash-balance" > —</ span > < span class = "balance-unit" > PLM</ span ></ div >
2026-07-26 21:43:35 +02:00
< button class = "secondary" onclick = "refreshMe()" id = "refresh-btn" data-i18n-aria-label = "deposit.refreshAria" aria-label = "Aggiorna saldo" >
2026-07-21 10:52:06 +02:00
< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< path d = "M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6" /></ svg >
2026-07-26 21:43:35 +02:00
< span data-i18n = "deposit.refreshBtn" > Aggiorna</ span >
2026-07-21 10:52:06 +02:00
</ button >
</ div >
</ div >
< div class = "card" >
2026-07-26 21:43:35 +02:00
< h2 data-i18n = "deposit.addressTitle" > Indirizzo di deposito</ h2 >
< p class = "hint" data-i18n = "deposit.addressHint" > È anche l'indirizzo su cui ricevi eventuali vincite</ p >
2026-07-21 10:52:06 +02:00
< div class = "address-box" >
< span class = "mono" id = "dash-address" ></ span >
2026-07-26 21:43:35 +02:00
< button class = "secondary" onclick = "copyAddress()" data-i18n-aria-label = "deposit.copyAria" aria-label = "Copia indirizzo" >
2026-07-21 10:52:06 +02:00
< svg class = "icon" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< rect x = "9" y = "9" width = "13" height = "13" rx = "2" />< path d = "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" /></ svg >
</ button >
</ div >
< div class = "qr-box" >
2026-07-26 21:43:35 +02:00
< img id = "dash-qr" data-i18n-alt = "deposit.qrAlt" alt = "QR code dell'indirizzo di deposito" >
2026-07-21 10:52:06 +02:00
</ div >
2026-07-21 10:46:55 +02:00
</ div >
</ div >
2026-07-21 10:52:06 +02:00
< div class = "dash-panel" id = "panel-bet" >
< div class = "card" >
2026-07-26 21:43:35 +02:00
< h2 data-i18n = "bet.title" > Bet</ h2 >
< p class = "hint" data-i18n = "bet.hint" > Ingresso fisso al round corrente</ p >
<!-- No data-i18n here: the label carries the live bet amount, which is
admin-configurable, so it's rendered by renderBetButton() in app.js. -->
< button onclick = "placeBet()" id = "bet-btn" > Place bet</ button >
2026-07-21 10:46:55 +02:00
</ div >
</ div >
2026-07-21 10:52:06 +02:00
< div class = "dash-panel" id = "panel-withdraw" >
< div class = "card" >
2026-07-26 21:43:35 +02:00
< h2 data-i18n = "withdraw.title" > Withdrawal</ h2 >
< p class = "hint" data-i18n = "withdraw.hint" > Invia fondi a un indirizzo PLM esterno</ p >
< label for = "wd-address" data-i18n = "withdraw.addressLabel" > Indirizzo esterno</ label >
2026-07-21 10:52:06 +02:00
< input id = "wd-address" class = "mono" placeholder = "plm1q..." >
2026-07-26 21:43:35 +02:00
< p class = "hint" data-i18n-html = "withdraw.addressHint" > Solo indirizzi P2WPKH bech32 (quelli che iniziano con < code > plm1q...</ code > ). Indirizzi legacy (< code > P...</ code > ) o P2SH non sono supportati.</ p >
< label for = "wd-amount" data-i18n = "withdraw.amountLabel" > Importo (PLM)</ label >
< input id = "wd-amount" inputmode = "decimal" data-i18n-placeholder = "withdraw.amountPlaceholder" placeholder = "es. 2" >
2026-07-22 14:59:02 +02:00
< label class = "checkbox-row" >
< input type = "checkbox" id = "wd-full-amount" onchange = "toggleWithdrawFullAmount()" >
2026-07-26 21:43:35 +02:00
< span data-i18n = "withdraw.fullAmountPrefix" > Preleva l'intero importo (</ span >< span class = "mono" id = "wd-full-amount-value" > —</ span >< span data-i18n = "withdraw.fullAmountSuffix" > PLM)</ span >
2026-07-22 14:59:02 +02:00
</ label >
2026-07-26 21:43:35 +02:00
< button onclick = "withdraw()" id = "withdraw-btn" data-i18n = "withdraw.button" > Preleva</ button >
2026-07-21 10:52:06 +02:00
</ div >
2026-07-21 10:46:55 +02:00
</ div >
2026-07-21 10:27:05 +02:00
2026-07-22 12:00:09 +02:00
< div class = "dash-panel" id = "panel-profile" >
< div class = "card" >
2026-07-26 21:43:35 +02:00
< h2 data-i18n = "profile.title" > Profilo</ h2 >
< p class = "hint" data-i18n = "profile.hint" > Le tue informazioni account</ p >
< label data-i18n = "profile.usernameLabel" > Username</ label >
2026-07-22 12:00:09 +02:00
< div class = "address-box" >< span id = "profile-username" > —</ span ></ div >
2026-07-26 21:43:35 +02:00
< label data-i18n = "profile.addressLabel" > Indirizzo di deposito</ label >
2026-07-22 12:00:09 +02:00
< div class = "address-box" >< span class = "mono" id = "profile-address" > —</ span ></ div >
2026-07-26 21:43:35 +02:00
< label data-i18n = "profile.balanceLabel" > Saldo interno</ label >
2026-07-22 12:00:09 +02:00
< div class = "address-box" >< span class = "mono" id = "profile-balance" > —</ span > < span class = "balance-unit" > PLM</ span ></ div >
2026-07-26 21:43:35 +02:00
< label data-i18n = "profile.createdLabel" > Utente dal</ label >
2026-07-22 12:00:09 +02:00
< div class = "address-box" >< span id = "profile-created-at" > —</ span ></ div >
</ div >
< div class = "card" >
2026-07-26 21:43:35 +02:00
< h2 data-i18n = "settings.title" > Impostazioni</ h2 >
< p class = "hint" data-i18n = "settings.hint" > Cambia la password del tuo account</ p >
< label for = "settings-current-password" data-i18n = "settings.currentPasswordLabel" > Password attuale</ label >
2026-07-22 12:00:09 +02:00
< input id = "settings-current-password" type = "password" autocomplete = "current-password" >
2026-07-26 21:43:35 +02:00
< label for = "settings-new-password" data-i18n = "settings.newPasswordLabel" > Nuova password</ label >
2026-07-22 12:00:09 +02:00
< input id = "settings-new-password" type = "password" autocomplete = "new-password" >
2026-07-26 21:43:35 +02:00
< label for = "settings-new-password-confirm" data-i18n = "settings.newPasswordConfirmLabel" > Conferma nuova password</ label >
2026-07-22 12:00:09 +02:00
< input id = "settings-new-password-confirm" type = "password" autocomplete = "new-password" >
2026-07-26 21:43:35 +02:00
< button onclick = "changePassword()" id = "change-password-btn" data-i18n = "settings.updateBtn" > Aggiorna password</ button >
2026-07-22 12:00:09 +02:00
</ div >
</ div >
2026-07-21 10:27:05 +02:00
</ section >
2026-07-22 10:36:36 +02:00
</ div >
2026-07-21 10:46:55 +02:00
< div id = "toast-container" aria-live = "polite" ></ div >
2026-07-21 10:27:05 +02:00
2026-07-26 21:43:35 +02:00
< script src = "/i18n.js" ></ script >
2026-07-23 11:05:38 +02:00
< script src = "/app.js" ></ script >
2026-07-21 10:27:05 +02:00
</ body >
</ html >