# 03 — Interattività e Coinvolgimento

> Come trasformare l'assegnazione di ~20 persone a un set di stanze in uno **spettacolo condiviso**
> in stile scommesse / game-show / slot machine, guardato tutti insieme su un unico schermo.

Questo documento raccoglie idee di game design, meccaniche di gamification, sound design,
momenti di celebrazione e soluzioni tecniche concrete (con nomi di librerie e URL CDN reali)
per rendere la web app **massimamente divertente e coinvolgente**.

---

## 1. Il principio di base: l'attesa vale più del premio

La ricerca sul gambling e sui game-show è concorde: **l'anticipazione conta più del risultato**.
Il rilascio di dopamina è massimo *nei momenti che precedono* la rivelazione, non nella rivelazione
stessa. I "reward" imprevedibili (variable ratio reward schedule) generano una risposta emotiva
molto più forte di quelli prevedibili.

Implicazioni di design per la nostra app:

- **Non rivelare tutto insieme.** Diluire l'assegnazione nel tempo (una persona / una stanza alla
  volta) moltiplica i picchi di tensione.
- **Rallentare proprio prima del risultato.** Come la ruota della fortuna che decelera: gli ultimi
  secondi prima dello "stop" sono quelli che valgono.
- **Sfruttare il "quasi-vinto" (near-miss).** Far vedere che qualcuno stava per finire nella "stanza
  VIP" ma poi... no. Il near-miss tiene il cervello in stato di attesa e alza l'engagement di tutta
  la sala.
- **Incertezza come feature, non come bug.** Non mostrare mai l'esito prima del tempo; la sorpresa è
  il prodotto.

Questi principi guidano tutte le sezioni successive.

---

## 2. Meccaniche di engagement e gamification

### 2.1 Suspense e reveal sociale

- **Reveal una persona alla volta**: il nome della persona appare, parte lo "spin", e solo dopo si
  scopre la stanza. Ogni singola assegnazione diventa un micro-evento.
- **Spinning wheel / slot reel come metafora principale**: la ruota/rullo che gira e decelera è una
  delle meccaniche di suspense più efficaci perché il pubblico *vede tutti gli esiti possibili*
  scorrere davanti e può "tifare" per uno di essi.
- **Ordine di rivelazione studiato per il dramma** (vedi §6): non alfabetico, ma costruito a
  crescendo.
- **Countdown visibile** (3… 2… 1…) prima di ogni spin, con drumroll audio e vibrazione.

### 2.2 Scommesse / pronostici prima del reveal (il cuore "gambling")

Prima che l'algoritmo riveli le assegnazioni, si apre una **finestra di pronostici**:

- Ogni partecipante (o la sala a mano alzata, in modalità single-screen) prova a indovinare
  **in quale stanza finirà una data persona**.
- Si possono mostrare **quote/odds** fittizie accanto a ogni stanza ("Stanza VIP paga 5x", "Stanza
  Sgabuzzino paga 1.2x") per dare sapore da sala scommesse e orientare l'ironia del gruppo.
- **Punti / gettoni virtuali** da puntare: chi indovina di più sale in classifica.
- Il momento della rivelazione diventa doppiamente teso: non scopri solo dove va la persona, ma
  anche *se hai vinto la scommessa*.

Questa meccanica sfrutta esattamente la psicologia dell'incertezza del premio: la posta in gioco
personale amplifica l'attenzione di tutti.

### 2.3 Leaderboard e classifiche

- **Classifica pronosticatori**: chi ha indovinato più assegnazioni.
- Aggiornamento **live dopo ogni reveal**, con animazione di scalata (righe che si riordinano).
- Ranking individuale e/o a squadre; le squadre aumentano il tifo e le esultanze collettive.
- La leaderboard è essa stessa un momento di spettacolo: mostrarla a schermo intero tra un blocco di
  reveal e l'altro.

### 2.4 Reazioni, emoji e tifo

- **Emoji reactions in tempo reale** che volano sullo schermo condiviso (🎉 😱 🔥 👑 💀) quando esce
  un'assegnazione clamorosa.
- Se i telefoni sono connessi (vedi §7), i partecipanti "lanciano" emoji dal telefono e appaiono
  sul proiettore.
- In modalità puramente single-screen: reazioni scatenate da tasti/hotkey dell'MC, o semplicemente
  dal tifo dal vivo amplificato dagli effetti audio/visivi.

### 2.5 Streak e momenti speciali

- **Streak del pronosticatore**: 3 assegnazioni indovinate di fila → effetto "on fire" 🔥 con audio
  e confetti dedicati.
- **Streak di stanza**: se la stessa stanza riceve N persone di fila → "HOT ROOM" con luci
  lampeggianti.
- **Combo/moltiplicatori**: più la streak è lunga, più i punti valgono (moltiplicatore visibile che
  sale), come nei giochi arcade.

### 2.6 Feedback game-show generale

- **MC / annunciatore** (testo + audio): battute pre-scritte a tema per ogni tipo di reveal (vedi §6.4).
- **Barra di "hype"** che si riempie con le reazioni della sala.
- **Achievement/badge** sbloccabili ("Primo Jackpot", "Cappotto di pronostici", "Sfortunato del
  giorno").

---

## 3. Sound design

Il suono è metà dello spettacolo. Serve un piccolo **kit di effetti** riutilizzabili.

### 3.1 Gli effetti chiave da avere

| Momento | Suono | Quando parte |
|---|---|---|
| Avvio spin | *whoosh* / rullo che accelera | inizio dell'animazione della slot/ruota |
| Rotazione | tick-tick-tick dei rulli | durante lo spin (loop) |
| Decelerazione | ticchettio che rallenta | ultimi secondi prima dello stop |
| Assegnazione normale | *ding* / campanello | quando si ferma su una stanza |
| Stanza VIP / jackpot | *jackpot* + monete che cadono (coin drop) | reveal di una stanza speciale |
| Pre-reveal drammatico | *drumroll* (rullo di tamburi) | durante il countdown 3-2-1 |
| Vittoria / grande momento | *crowd cheer* (folla che esulta) | jackpot, fine evento, streak |
| Errore / near-miss | *buzz* / *sad trombone* | quando un pronostico fallisce |
| Cambio schermata | *swoosh* UI | transizioni tra i blocchi |

### 3.2 Dove trovare effetti sonori GRATIS (royalty-free)

Tutte fonti utilizzabili in progetti personali e commerciali (verificare la licenza del singolo file).

**Mixkit** — nessuna registrazione, uso libero personale e commerciale:
- Slot machine: <https://mixkit.co/free-sound-effects/slot-machine/>
- Casino: <https://mixkit.co/free-sound-effects/casino/>
- Utili qui: reel spin, coin drop, big win jingle.

**Pixabay** — royalty-free, nessuna attribuzione richiesta, download MP3:
- Slot machine: <https://pixabay.com/sound-effects/search/slot-machine/>
- Slot spin: <https://pixabay.com/sound-effects/search/slot%20spin/>
- Jackpot: <https://pixabay.com/sound-effects/search/jackpot/>
- Casino: <https://pixabay.com/sound-effects/search/casino/>
- Per gli altri effetti cercare: `drumroll`, `applause` / `crowd cheer`, `coin`, `ding`, `buzzer`,
  `whoosh`.

**Freesound** — database collaborativo Creative Commons (attenzione: alcuni file richiedono
attribuzione, controllare la licenza CC0 vs CC-BY):
- Home / ricerca: <https://freesound.org/>
- Esempio pack slot machine: <https://freesound.org/people/lukaso/packs/4497/>

Suggerimento pratico: scaricare gli MP3, **normalizzare i volumi** (un jackpot troppo forte rispetto
al ding rovina l'esperienza) e tenerli in una cartella `assets/audio/` con nomi parlanti
(`spin.mp3`, `ding.mp3`, `jackpot.mp3`, `drumroll.mp3`, `coin.mp3`, `cheer.mp3`, `buzz.mp3`).

### 3.3 Come far partire i suoni nel browser

Due strade: `<audio>` semplice, oppure la **Web Audio API** / **Howler.js** per controllo fine e
niente latenza.

**Attenzione all'autoplay policy.** I browser (da Chrome 71 in poi) **bloccano l'audio finché non
c'è un'interazione utente**. Un `AudioContext` creato prima di un gesto utente nasce in stato
`suspended`. Va **sbloccato al primo click/tap** (es. il bottone "Inizia lo show") chiamando
`resume()`. Best practice: un unico "gesto di sblocco" all'avvio dell'evento.

Sblocco base con Web Audio API:

```javascript
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();

// da chiamare dentro un handler di click/tap (es. bottone "Avvia lo show")
function unlockAudio() {
  if (audioCtx.state === 'suspended') {
    audioCtx.resume();
  }
}
document.querySelector('#start-btn').addEventListener('click', unlockAudio, { once: true });
```

**Howler.js** (consigliato: gestisce autoplay, sprite audio, volumi, fallback HTML5 in automatico).

CDN:
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.4/howler.min.js"></script>
```

Uso:
```javascript
const sfx = {
  spin:     new Howl({ src: ['assets/audio/spin.mp3'], volume: 0.6 }),
  ding:     new Howl({ src: ['assets/audio/ding.mp3'] }),
  jackpot:  new Howl({ src: ['assets/audio/jackpot.mp3'], volume: 0.9 }),
  drumroll: new Howl({ src: ['assets/audio/drumroll.mp3'] }),
  coin:     new Howl({ src: ['assets/audio/coin.mp3'] }),
  cheer:    new Howl({ src: ['assets/audio/cheer.mp3'] }),
  buzz:     new Howl({ src: ['assets/audio/buzz.mp3'] }),
};

// esempio: sequenza di un reveal
sfx.drumroll.play();
// ...al momento dello stop
sfx.ding.play();
```

Perché Howler: parte da ~7KB gzipped, usa Web Audio con **fallback su HTML5 Audio**, supporta
**audio sprite** (utile per impacchettare tutti gli effetti in un solo file e ridurre le richieste)
e semplifica volumi/fade. Docs: <https://howlerjs.com/>.

---

## 4. Momenti di celebrazione (celebration UX)

Gli effetti visivi trasformano un reveal in un evento memorabile. La regola d'oro: **scalare
l'intensità dell'effetto in base all'importanza del momento** (assegnazione normale = piccolo puff;
jackpot VIP = tutto lo schermo esplode).

### 4.1 Confetti — `canvas-confetti`

Libreria leggera (< 10KB gzip), performante, esposta come funzione globale `confetti()`.

CDN:
```html
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.4/dist/confetti.browser.min.js"></script>
<!-- alternativa cdnjs -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/canvas-confetti/1.9.3/confetti.min.js"></script> -->
```

**Burst semplice** (assegnazione normale):
```javascript
confetti({ particleCount: 120, spread: 70, origin: { y: 0.6 } });
```

**Fireworks / fuochi d'artificio** (jackpot, fine evento) — due getti laterali ripetuti:
```javascript
const duration = 4 * 1000;
const end = Date.now() + duration;
(function frame() {
  confetti({ particleCount: 7, angle: 60,  spread: 55, origin: { x: 0 } });
  confetti({ particleCount: 7, angle: 120, spread: 55, origin: { x: 1 } });
  if (Date.now() < end) requestAnimationFrame(frame);
}());
```

**Confetti a emoji/testo** (es. 👑 per la stanza VIP):
```javascript
const crown = confetti.shapeFromText({ text: '👑', scalar: 2 });
confetti({ shapes: [crown], scalar: 2, particleCount: 40, spread: 100 });
```

Opzioni utili: `particleCount`, `spread`, `angle`, `startVelocity`, `gravity`, `colors` (array HEX),
`shapes` (`square`/`circle`/`star`/custom), `origin.x/.y`, `scalar`, `ticks`.
**Accessibilità**: usare `disableForReducedMotion: true` per rispettare chi preferisce meno
animazioni.

Demo/preset ufficiali (fireworks, snow, school pride, ecc.): <https://www.kirilv.com/canvas-confetti/>

Alternativa con supporto emoji nativo: **js-confetti** — <https://github.com/loonywizard/js-confetti>.

### 4.2 Screen shake, flash e luci lampeggianti

Effetti CSS/JS a basso costo, molto d'impatto sullo schermo grande:

```css
@keyframes shake {
  0%,100% { transform: translate(0,0); }
  20% { transform: translate(-8px, 4px); }
  40% { transform: translate(8px, -4px); }
  60% { transform: translate(-6px, -6px); }
  80% { transform: translate(6px, 6px); }
}
.shake { animation: shake 0.4s ease-in-out; }

@keyframes flash {
  0%,100% { background: transparent; }
  50% { background: rgba(255,255,255,0.85); }
}
.flash { animation: flash 0.15s ease-in-out 3; } /* triplo flash */
```

- **Screen shake** sul reveal del jackpot (aggiungere/rimuovere la classe `.shake` sul container).
- **Flash bianco** al momento dello "stop" della slot.
- **Luci lampeggianti** in stile casinò: bordo dello schermo con luci che corrono
  (box-shadow animato o una fila di "bulbi" attorno al frame).

### 4.3 Winner spotlight (riflettore sul vincitore)

Al reveal di una persona in stanza speciale, o del "vincitore" dei pronostici:

- **Oscurare lo sfondo** (overlay scuro) e lasciare un **cono di luce/riflettore** (radial-gradient)
  sul nome/foto della persona.
- **Zoom-in + pop** dell'elemento (scala da 0.8 a 1.1 e ritorno) con anime.js o CSS.
- Nome grande, corona/badge, confetti a corona (§4.1) e crowd cheer (§3).

### 4.4 Anime.js per orchestrare le animazioni

Per sequenze complesse (countdown → spin → stop → celebrazione) conviene una **timeline**.

CDN:
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
```

Esempio di reveal a più elementi con **stagger** (le lettere/righe che appaiono a cascata):
```javascript
anime({
  targets: '.reveal-letter',
  translateY: [40, 0],
  opacity: [0, 1],
  delay: anime.stagger(60),   // 60ms tra un elemento e l'altro
  easing: 'easeOutBack'
});
```

Anime.js gestisce timeline, keyframes, easing e staggering: ideale per sincronizzare animazione
visiva e cue audio. Docs: <https://animejs.com/documentation/>.

---

## 5. Haptics / feedback su mobile (`navigator.vibrate`)

Se i partecipanti tengono il telefono in mano (modalità connessa, §7), la **vibrazione** aggiunge un
canale sensoriale al reveal.

API base:
```javascript
// vibrazione singola (ms)
navigator.vibrate(200);

// pattern: [vibra, pausa, vibra, ...]
navigator.vibrate([100, 50, 100]);      // doppio buzz "successo"
navigator.vibrate([300, 100, 300, 100, 300]); // jackpot
```

Idee d'uso:
- **Countdown**: micro-vibrazione a ogni tick (3-2-1).
- **Spin**: vibrazione continua/pulsata durante la rotazione.
- **Stop/assegnazione**: singolo buzz secco.
- **Pronostico indovinato**: doppio buzz "successo"; **fallito**: triplo buzz "errore".
- **Jackpot**: pattern lungo e ritmico.

Best practice (da MDN):
- Durate brevi: **50–200ms** sono ideali; una nuova `vibrate()` annulla la precedente, quindi
  evitare chiamate a raffica.
- Va invocata dentro un **gesto utente** (sticky user activation): legarla a click/tap.
- **Additiva, mai unico canale di feedback**: offrire un toggle per disattivarla (c'è chi la odia o
  non la percepisce).

Supporto: Chrome/Edge/Opera/Samsung Internet e Android. **Safari (iOS/macOS) non la supporta** e
**Firefox l'ha rimossa da v129**: fare feature-detection e degradare con grazia.
```javascript
if ('vibrate' in navigator) { navigator.vibrate(200); }
```
Riferimento: <https://developer.mozilla.org/en-US/docs/Web/API/Navigator/vibrate>

---

## 6. Idee specifiche per il reveal "persone → stanze"

Qui sta la vera anima dello spettacolo. Suggerimenti per rendere l'assegnazione un evento condiviso.

### 6.1 Struttura del reveal, una persona alla volta

1. Appare il **nome (e foto)** della persona di turno al centro.
2. Parte lo **spin** della slot/ruota con le stanze come simboli.
3. **Countdown 3-2-1** con drumroll + vibrazione.
4. La ruota **decelera** (near-miss: rallenta vicino a una stanza "clamorosa" e poi supera).
5. **Stop** su una stanza → *ding* / o *jackpot* se speciale → confetti scalati all'importanza.
6. Aggiornamento **leaderboard pronostici** e reazioni della sala.

### 6.2 Scommesse su chi va dove

- Prima del blocco, la sala pronostica: *"Dove finirà Marco?"*.
- **Quote/odds** mostrate accanto alle stanze per ironia e strategia.
- La rivelazione risolve due tensioni insieme (dove va Marco + chi ha indovinato).

### 6.3 Stanze speciali e "VIP room jackpot"

- Designare una o più stanze come **speciali**: "Stanza VIP" 👑, "Suite Presidenziale", oppure la
  temutissima "Sgabuzzino" 💀.
- Quando qualcuno ci finisce → **trattamento jackpot**: full-screen fireworks, crowd cheer, coin
  drop, screen shake, spotlight.
- Le stanze speciali possono avere **posti limitati** (scarsità = più tensione a ogni assegnazione:
  "resta un solo posto VIP!").
- **Progressive jackpot**: una stanza "misteriosa" il cui contenuto/premio cresce a ogni reveal
  finché non viene assegnata.

### 6.4 Ordine di rivelazione per il massimo dramma

- **Non alfabetico.** Costruire un crescendo: prima assegnazioni "normali", poi i colpi di scena.
- Tenere per **ultimi** i reveal più attesi (le stanze speciali, le persone-chiave, il pareggio di
  una scommessa).
- Alternare ritmo: qualche reveal veloce di fila, poi uno **rallentato al massimo** con countdown
  lungo.
- **Blocchi tematici** con schermate-ponte (leaderboard, "coming up next") per far respirare la
  tensione e ripartire.

### 6.5 Testi da MC / annunciatore

Frasi pre-scritte (testo a schermo + eventuale TTS/audio) a seconda dell'esito. Esempi:

- Apertura: *"Signore e signori, benvenuti alla GRANDE ASSEGNAZIONE! 20 persone, X stanze, un solo
  destino. Che la sorte decida!"*
- Pre-spin: *"Il prossimo concorrente è… MARCO. Dove lo manderà la ruota? Fate le vostre puntate!"*
- Near-miss: *"Ohhh! Era a un passo dalla Suite VIP… ma no!"*
- Assegnazione normale: *"E Marco va nella Stanza 3! Un applauso."*
- Jackpot: *"JACKPOT!!! Marco conquista la STANZA VIP! 👑 Che fortuna sfacciata!"*
- Sfortuna: *"Ahia… Sgabuzzino. Condoglianze, Marco. 💀"*
- Chiusura: *"E con questo le stanze sono assegnate! Applauso finale per tutti i concorrenti!"*

### 6.6 Reazioni ed emoji legate al reveal

- Set di emoji rapide (👑 😱 🔥 💀 🎉 👏) scatenabili dalla sala/telefoni al momento giusto.
- Contatore reazioni per rendere "virale" il momento in sala.

---

## 7. Multiplayer / schermo condiviso (anche senza backend)

Obiettivo: farlo funzionare bene **anche senza server**, con opzioni di upgrade se serve interazione
dai telefoni.

### 7.1 Modalità "single-screen / projector" (zero backend) — consigliata per partire

- **Un solo schermo** (proiettore o TV) mostra tutto lo show; l'MC guida con tastiera/telecomando.
- Tutta la logica gira **client-side** nel browser: l'assegnazione può essere pre-calcolata o
  generata in loco, poi il reveal è pura animazione.
- I pronostici si fanno **a voce / a mano alzata**, l'MC li registra o semplicemente la sala tifa.
- Pro: nessuna infrastruttura, nessun rischio di rete, massima affidabilità in evento dal vivo.
- Il modello dei party game (Jackbox, Kahoot) conferma che *un solo schermo condiviso* è al centro
  dell'esperienza collettiva; i telefoni sono solo controller opzionali.

### 7.2 Aggiungere i telefoni con un QR code

Come Jackbox.tv / Kahoot: a schermo appare un **QR code + codice stanza**; i partecipanti scansionano
e aprono una pagina "controller" nel browser (nessuna app da installare).

Generare il QR lato client:
```html
<script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script>
<div id="qr"></div>
<script>
  new QRCode(document.getElementById('qr'), 'https://tuo-dominio/join?room=AB12');
</script>
```
(libreria: **qrcodejs** — <https://github.com/davidshimjs/qrcodejs>)

### 7.3 Sincronizzazione telefoni ↔ schermo con backend minimale

Se vuoi che i pronostici/emoji dai telefoni appaiano in tempo reale sul proiettore, serve un piccolo
canale realtime. Opzioni leggere:

- **BroadcastChannel API** — *gratis, zero backend*, ma solo tra schede **dello stesso dispositivo/
  browser** (utile per prototipare o per setup a più finestre sullo stesso PC). Non attraversa
  dispositivi diversi.
- **WebSocket** su un piccolo server (Node) o servizio serverless.
- **Cloudflare Durable Objects** — ottimi per "stanze" realtime multiplayer con stato condiviso
  (coordinamento di una room, WebSocket, stato per-stanza) senza gestire server tradizionali.
- Servizi realtime gestiti (es. Firebase Realtime Database / Firestore, Supabase Realtime) se si
  preferisce non scrivere backend.

Raccomandazione: **partire single-screen (§7.1)**, aggiungere il **QR + controller** (§7.2) solo se
si vuole l'interazione dai telefoni, e introdurre un backend realtime **solo se** i pronostici live
diventano centrali.

---

## 8. Stack tecnico consigliato (riepilogo librerie e CDN)

| Scopo | Libreria | CDN |
|---|---|---|
| Confetti / fuochi | **canvas-confetti** | `https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.4/dist/confetti.browser.min.js` |
| Confetti con emoji (alt.) | **js-confetti** | <https://github.com/loonywizard/js-confetti> |
| Audio / SFX | **Howler.js** | `https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.4/howler.min.js` |
| Animazioni / timeline | **anime.js** | `https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js` |
| QR code join | **qrcodejs** | `https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js` |
| Haptics | **Vibration API** (nativa) | `navigator.vibrate()` |
| Sblocco/gestione audio | **Web Audio API** (nativa) | `AudioContext` + `resume()` |
| Realtime opzionale | **Cloudflare Durable Objects** / WebSocket / Firebase | — |

**Checklist di implementazione**

- [ ] Sbloccare l'audio al primo tap (bottone "Avvia lo show").
- [ ] Precaricare tutti gli SFX (Howler) e le immagini prima dell'evento.
- [ ] Scalare gli effetti (confetti/shake/audio) sull'importanza del reveal.
- [ ] Rispettare `prefers-reduced-motion` (`disableForReducedMotion`) e offrire toggle audio/haptics.
- [ ] Feature-detection per `navigator.vibrate` (assente su iOS/Safari e Firefox recenti).
- [ ] Testare su schermo grande + audio potente (l'evento è dal vivo, il volume conta).
- [ ] Curare l'ordine di reveal per il crescendo drammatico.

---

## Fonti

**Confetti / animazioni**
- canvas-confetti (GitHub): <https://github.com/catdad/canvas-confetti>
- canvas-confetti (npm): <https://www.npmjs.com/package/canvas-confetti>
- canvas-confetti (cdnjs): <https://cdnjs.com/libraries/canvas-confetti>
- canvas-confetti (jsDelivr): <https://www.jsdelivr.com/package/npm/canvas-confetti>
- Demo/preset canvas-confetti (Kiril Vatev): <https://www.kirilv.com/canvas-confetti/>
- js-confetti (emoji): <https://github.com/loonywizard/js-confetti>
- anime.js (sito): <https://animejs.com/>
- anime.js (documentazione): <https://animejs.com/documentation/>
- anime.js — stagger: <https://animejs.com/documentation/utilities/stagger/>

**Audio / Web Audio**
- Howler.js (sito): <https://howlerjs.com/>
- Howler.js (GitHub): <https://github.com/goldfire/howler.js/>
- Howler.js (cdnjs): <https://cdnjs.com/libraries/howler>
- MDN — Using the Web Audio API: <https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Using_Web_Audio_API>
- MDN — Autoplay guide: <https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Autoplay>
- MDN — Web Audio API best practices: <https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Best_practices>
- Chrome for Developers — Web Audio, Autoplay Policy and Games: <https://developer.chrome.com/blog/web-audio-autoplay>
- Chrome for Developers — Autoplay policy in Chrome: <https://developer.chrome.com/blog/autoplay>

**Effetti sonori gratuiti**
- Mixkit — Slot Machine: <https://mixkit.co/free-sound-effects/slot-machine/>
- Mixkit — Casino: <https://mixkit.co/free-sound-effects/casino/>
- Pixabay — Slot Machine: <https://pixabay.com/sound-effects/search/slot-machine/>
- Pixabay — Slot Spin: <https://pixabay.com/sound-effects/search/slot%20spin/>
- Pixabay — Jackpot: <https://pixabay.com/sound-effects/search/jackpot/>
- Pixabay — Casino: <https://pixabay.com/sound-effects/search/casino/>
- Freesound (home): <https://freesound.org/>
- Freesound — pack Slot Machine (lukaso): <https://freesound.org/people/lukaso/packs/4497/>

**Haptics**
- MDN — Vibration API: <https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API>
- MDN — Navigator.vibrate(): <https://developer.mozilla.org/en-US/docs/Web/API/Navigator/vibrate>
- WICG — Web Haptics API: <https://github.com/WICG/web-haptics>

**Gamification / game-show / psicologia**
- Yu-kai Chou — The Spinning Wheel (gamification): <https://yukaichou.com/gamification-analysis/the-spinning-wheel-a-comprehensive-guide-to-boosting-user-engagement/>
- Guidebook — Event App Gamification: <https://www.guidebook.com/post/master-event-gamification-with-these-engaging-app-features>
- Contest Factory — Gamification & Interactive Mechanics: <https://contestfactory.com/gamification-interactive-mechanics-that-drive-participation/>
- The Conversation — How gambling distorts reality and hooks your brain: <https://theconversation.com/designed-to-deceive-how-gambling-distorts-reality-and-hooks-your-brain-91052>
- NCBI/PMC — Reward anticipation and outcome evaluation in gambling: <https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3971161/>
- Near-miss effect: <https://accenteyes.com/how-near-misses-deceive-your-brain-into-persistent-betting/>

**Schermo condiviso / multiplayer**
- Jackbox — How to play remotely (QR / room code): <https://www.jackboxgames.com/blog/how-to-play-jackbox-games-with-friends-and-family-remotely>
- Kahoot — How to host a live kahoot: <https://support.kahoot.com/hc/en-us/articles/360039422694-How-to-host-a-live-kahoot>
- Kahoot — How to join (PIN / link / QR): <https://support.kahoot.com/hc/en-us/articles/360039890713-Kahoot-join-How-to-join-a-Kahoot-game>
- qrcodejs: <https://github.com/davidshimjs/qrcodejs>
- MDN — BroadcastChannel API: <https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API>
- Cloudflare Durable Objects: <https://developers.cloudflare.com/durable-objects/>
