<template>
  <section class="controller-page">
    <!-- Barra di stato connessione -->
    <div class="conn-bar" :class="{ connected: wsConnected }">
      <span class="dot"></span>
      {{ wsConnected ? 'Connesso' : 'Connessione...' }}
    </div>

    <!-- Banner modalità time out attiva -->
    <div class="timeout-banner" v-if="state.timeout">
      TIME OUT {{ state.sp.nomi[state.timeoutTeam] }} — {{ timeoutCountdown }}
    </div>

    <!-- ══════════════════ MODALITÀ MOBILE ══════════════════ -->
    <template v-if="!isEstesa">
      <!-- Anteprima punteggio -->
      <div class="score-preview">
        <div class="team-score" :class="primaSquadra + '-bg'" @click="sendAction({ type: 'incPunt', team: primaSquadra })">
          <div class="team-name">{{ state.sp.nomi[primaSquadra] }}</div>
          <div class="team-pts">{{ punt[primaSquadra] }}</div>
          <div class="team-set">SET {{ set[primaSquadra] }}</div>
          <img v-show="primaSquadra === 'home' ? servHome : !servHome" src="/serv.png" class="serv-icon" alt="Servizio" />
        </div>
        <div class="team-score" :class="secondaSquadra + '-bg'" @click="sendAction({ type: 'incPunt', team: secondaSquadra })">
          <div class="team-name">{{ state.sp.nomi[secondaSquadra] }}</div>
          <div class="team-pts">{{ punt[secondaSquadra] }}</div>
          <div class="team-set">SET {{ set[secondaSquadra] }}</div>
          <img v-show="secondaSquadra === 'home' ? servHome : !servHome" src="/serv.png" class="serv-icon" alt="Servizio" />
        </div>
      </div>

      <!-- Riga annulla punto -->
      <div class="undo-row">
        <button class="btn btn-undo" @click="sendAction({ type: 'decPunt' })">
          ANNULLA PUNTO
        </button>
      </div>

      <!-- Pulsanti set -->
      <div class="action-row">
        <button class="btn btn-set home-bg" @click="sendAction({ type: 'incSet', team: 'home' })">
          SET {{ state.sp.nomi.home }}
        </button>
        <button class="btn btn-set guest-bg" @click="sendAction({ type: 'incSet', team: 'guest' })">
          SET {{ state.sp.nomi.guest }}
        </button>
      </div>

      <!-- Controlli principali -->
      <div class="controls">
        <button class="btn btn-ctrl" @click="sendAction({ type: 'cambiaPalla' })" :disabled="!isPunteggioZeroZero">
          Cambio Palla
        </button>
        <button class="btn btn-ctrl" @click="sendAction({ type: 'toggleFormazione' })">
          {{ state.visuForm ? 'Punteggio' : 'Formazioni' }}
        </button>
        <button class="btn btn-ctrl" @click="sendAction({ type: 'toggleStriscia' })">
          Striscia {{ state.visuStriscia ? 'ON' : 'OFF' }}
        </button>
        <button class="btn btn-ctrl" @click="sendAction({ type: 'toggleOrder' })">
          Inverti
        </button>
        <button class="btn btn-ctrl" @click="speak()">
          Voce
        </button>
        <button class="btn btn-ctrl" @click="openConfig()">
          Config
        </button>
        <button class="btn btn-ctrl" @click="openCambiTeam()">
          Cambi
        </button>
        <button class="btn btn-ctrl btn-timeout" :class="{ active: state.timeout }"
          @click="state.timeout ? terminaTimeout() : openTimeout()">
          {{ state.timeout ? timeoutCountdown : 'Time Out' }}
        </button>
        <button class="btn btn-danger" @click="confirmReset = true">
          Reset
        </button>
      </div>
    </template>

    <!-- ══════════════════ MODALITÀ ESTESA ══════════════════ -->
    <div v-else class="e-dash" @wheel.prevent @touchmove.prevent>
      <div class="e-panels">

        <!-- Prima squadra -->
        <div class="e-panel" :class="primaSquadra === 'home' ? 'e-panel--home' : 'e-panel--guest'">
          <div class="e-panel__stripe"></div>
          <div class="e-panel__body">
            <header class="e-panel__head">
              <span class="e-panel__name">{{ state.sp.nomi[primaSquadra] }}</span>
              <span class="e-panel__meta">
                <img v-show="primaSquadra === 'home' ? servHome : !servHome" src="/serv.png" class="e-panel__serv" />
                {{ set[primaSquadra] }} <span class="e-label">SET</span>
              </span>
            </header>
            <div class="e-panel__score" @click="sendAction({ type: 'incPunt', team: primaSquadra })">
              {{ punt[primaSquadra] }}
            </div>
            <div class="e-panel__court">
              <div class="e-court__row">
                <div v-for="x in [3,2,1]" :key="'pf1'+x" class="e-court__cell">{{ state.sp.form[primaSquadra][x] }}</div>
              </div>
              <div class="e-court__net"></div>
              <div class="e-court__row">
                <div v-for="x in [4,5,0]" :key="'pf2'+x" class="e-court__cell">{{ state.sp.form[primaSquadra][x] }}</div>
              </div>
            </div>
            <button class="btn e-panel__setbtn" @click="sendAction({ type: 'incSet', team: primaSquadra })">
              SET {{ state.sp.nomi[primaSquadra] }}
            </button>
          </div>
        </div>

        <!-- Seconda squadra -->
        <div class="e-panel" :class="secondaSquadra === 'home' ? 'e-panel--home' : 'e-panel--guest'">
          <div class="e-panel__stripe"></div>
          <div class="e-panel__body">
            <header class="e-panel__head">
              <span class="e-panel__name">{{ state.sp.nomi[secondaSquadra] }}</span>
              <span class="e-panel__meta">
                <img v-show="secondaSquadra === 'home' ? servHome : !servHome" src="/serv.png" class="e-panel__serv" />
                {{ set[secondaSquadra] }} <span class="e-label">SET</span>
              </span>
            </header>
            <div class="e-panel__score" @click="sendAction({ type: 'incPunt', team: secondaSquadra })">
              {{ punt[secondaSquadra] }}
            </div>
            <div class="e-panel__court">
              <div class="e-court__row">
                <div v-for="x in [3,2,1]" :key="'sf1'+x" class="e-court__cell">{{ state.sp.form[secondaSquadra][x] }}</div>
              </div>
              <div class="e-court__net"></div>
              <div class="e-court__row">
                <div v-for="x in [4,5,0]" :key="'sf2'+x" class="e-court__cell">{{ state.sp.form[secondaSquadra][x] }}</div>
              </div>
            </div>
            <button class="btn e-panel__setbtn" @click="sendAction({ type: 'incSet', team: secondaSquadra })">
              SET {{ state.sp.nomi[secondaSquadra] }}
            </button>
          </div>
        </div>
      </div>

      <!-- Barra azioni secondarie -->
      <div class="e-actions">
        <button class="btn e-act e-act--undo" @click="sendAction({ type: 'decPunt' })">Annulla</button>
        <button class="btn e-act" :disabled="!isPunteggioZeroZero" @click="sendAction({ type: 'cambiaPalla' })">Cambio Palla</button>
        <button class="btn e-act" @click="openCambiTeam()">Cambi</button>
        <button class="btn e-act" @click="sendAction({ type: 'toggleOrder' })">Inverti</button>
        <button class="btn e-act" @click="sendAction({ type: 'toggleStriscia' })">Striscia {{ state.visuStriscia ? 'ON' : 'OFF' }}</button>
        <button class="btn e-act" @click="speak()">Voce</button>
        <button class="btn e-act" @click="openConfig()">Config</button>
        <button class="btn e-act btn-timeout" :class="{ active: state.timeout }"
          @click="state.timeout ? terminaTimeout() : openTimeout()">{{ state.timeout ? timeoutCountdown : 'Time Out' }}</button>
        <button class="btn e-act e-act--danger" @click="confirmReset = true">Reset</button>
      </div>
    </div>

    <!-- ══════════════════ DIALOGS (condivisi) ══════════════════ -->

    <!-- Finestra conferma reset -->
    <div class="overlay" v-if="confirmReset" @click.self="confirmReset = false">
      <div class="dialog">
        <div class="dialog-title">Azzero punteggio?</div>
        <div class="dialog-buttons">
          <button class="btn btn-cancel" @click="confirmReset = false">NO</button>
          <button class="btn btn-confirm" @click="doReset()">SI</button>
        </div>
      </div>
    </div>

    <!-- Finestra set vinto / partita finita -->
    <div class="overlay" v-if="showSetVinto">
      <div class="dialog">
        <div class="dialog-title">{{ isPartitaFinita ? 'PARTITA FINITA' : 'SET VINTO' }}</div>
        <div class="dialog-winner">{{ state.sp.nomi[setVintoTeam] }}</div>
        <div class="dialog-subtitle" v-if="!isPartitaFinita">Configura le formazioni per il prossimo set</div>
        <div class="dialog-buttons">
          <button class="btn btn-cancel" @click="undoUltimoPoint()">INDIETRO</button>
          <button v-if="isPartitaFinita" class="btn btn-secondary" @click="generaReferto(state)">REFERTO</button>
          <button v-if="isPartitaFinita" class="btn btn-confirm" @click="showSetVinto = false">CHIUDI</button>
          <button v-else class="btn btn-confirm" @click="doNuovoSet()">VAI AL SET SUCCESSIVO</button>
        </div>
      </div>
    </div>

    <!-- Finestra configurazione -->
    <div class="overlay" v-if="showConfig" @click.self="showConfig = false">
      <div class="dialog dialog-config">
        <div class="dialog-title">Configurazione</div>

        <div class="form-group">
          <label>Nome Home</label>
          <input type="text" v-model="configData.nomeHome" class="input-field" />
        </div>
        <div class="form-group">
          <label>Nome Guest</label>
          <input type="text" v-model="configData.nomeGuest" class="input-field" />
        </div>

        <div class="form-group">
          <label>Modalità partita</label>
          <div class="mode-buttons">
            <button :class="['btn', 'btn-mode', configData.modalita === '2/3' ? 'active' : '']"
              @click="configData.modalita = '2/3'">2/3</button>
            <button :class="['btn', 'btn-mode', configData.modalita === '3/5' ? 'active' : '']"
              @click="configData.modalita = '3/5'">3/5</button>
            <button :class="['btn', 'btn-mode', configData.modalita === 'amichevole' ? 'active' : '']"
              @click="configData.modalita = 'amichevole'">Amichevole</button>
          </div>
        </div>

        <div class="form-group">
          <label>Formazione Home</label>
          <div class="form-grid">
            <div class="form-row">
              <input type="text" v-model="configData.formHome[3]" class="input-num" />
              <input type="text" v-model="configData.formHome[2]" class="input-num" />
              <input type="text" v-model="configData.formHome[1]" class="input-num" />
            </div>
            <div class="form-line"></div>
            <div class="form-row">
              <input type="text" v-model="configData.formHome[4]" class="input-num" />
              <input type="text" v-model="configData.formHome[5]" class="input-num" />
              <input type="text" v-model="configData.formHome[0]" class="input-num" />
            </div>
          </div>
        </div>

        <div class="form-group">
          <label>Formazione Guest</label>
          <div class="form-grid">
            <div class="form-row">
              <input type="text" v-model="configData.formGuest[3]" class="input-num" />
              <input type="text" v-model="configData.formGuest[2]" class="input-num" />
              <input type="text" v-model="configData.formGuest[1]" class="input-num" />
            </div>
            <div class="form-line"></div>
            <div class="form-row">
              <input type="text" v-model="configData.formGuest[4]" class="input-num" />
              <input type="text" v-model="configData.formGuest[5]" class="input-num" />
              <input type="text" v-model="configData.formGuest[0]" class="input-num" />
            </div>
          </div>
        </div>

        <div class="dialog-buttons">
          <button class="btn btn-cancel" @click="showConfig = false">Annulla</button>
          <button class="btn btn-confirm" @click="saveConfig()">OK</button>
        </div>
      </div>
    </div>

    <!-- Selezione squadra per cambi -->
    <div class="overlay" v-if="showCambiTeam" @click.self="showCambiTeam = false">
      <div class="dialog">
        <div class="dialog-title">Scegli squadra</div>
        <div class="dialog-buttons">
          <button class="btn btn-set home-bg" @click="openCambi('home')">{{ state.sp.nomi.home }}</button>
          <button class="btn btn-set guest-bg" @click="openCambi('guest')">{{ state.sp.nomi.guest }}</button>
        </div>
      </div>
    </div>

    <!-- Finestra gestione cambi -->
    <div class="overlay" v-if="showCambi" @click.self="closeCambi()">
      <div class="dialog">
        <div class="dialog-title">{{ state.sp.nomi[cambiTeam] }}: CAMBIO</div>
        <div class="cambi-container">
          <div class="cambio-row" v-for="(c, i) in cambiData" :key="i">
            <input type="text" v-model="c.in" placeholder="IN" class="input-num cambi-in-field" />
            <span class="cambio-arrow">→</span>
            <input type="text" v-model="c.out" placeholder="OUT" class="input-num cambi-out-field" />
          </div>
        </div>
        <div v-if="cambiError" class="cambi-error">{{ cambiError }}</div>
        <div class="dialog-buttons">
          <button class="btn btn-cancel" @click="closeCambi()">Annulla</button>
          <button class="btn btn-confirm" :disabled="!cambiValid" @click="confermaCambi()">CONFERMA</button>
        </div>
      </div>
    </div>

    <!-- Finestra avvio time out: squadra + scelta video -->
    <div class="overlay" v-if="showTimeoutModal" @click.self="showTimeoutModal = false">
      <div class="dialog dialog-timeout">
        <div class="dialog-title">Time Out</div>

        <div class="form-group">
          <label>Squadra che lo ha richiesto</label>
          <div class="dialog-buttons">
            <button class="btn btn-set home-bg" :class="{ 'team-sel-active': timeoutTeamSel === 'home' }"
              @click="timeoutTeamSel = 'home'">{{ state.sp.nomi.home }}</button>
            <button class="btn btn-set guest-bg" :class="{ 'team-sel-active': timeoutTeamSel === 'guest' }"
              @click="timeoutTeamSel = 'guest'">{{ state.sp.nomi.guest }}</button>
          </div>
        </div>

        <div class="form-group">
          <label>Video (30s nominali)</label>
          <div class="timeout-video-list">
            <label class="timeout-video-option" v-for="file in spotList" :key="file">
              <input type="radio" name="timeoutVideo" :value="file" v-model="timeoutVideoSel" />
              {{ file }}
              <span class="video-duration">{{ formatDurata(spotDurations[file]) }}</span>
            </label>
            <label class="timeout-video-option">
              <input type="radio" name="timeoutVideo" :value="null" v-model="timeoutVideoSel" />
              Nessun video (overlay "TIME OUT")
            </label>
          </div>
        </div>

        <div class="dialog-buttons">
          <button class="btn btn-cancel" @click="showTimeoutModal = false">Annulla</button>
          <button class="btn btn-confirm" :disabled="!timeoutTeamSel" @click="avviaTimeout()">Avvia</button>
        </div>
      </div>
    </div>
  </section>
</template>

<script>
import { createWsMixin } from '../wsMixin.js'
import { generaReferto } from '../referto.js'

export default {
  name: "ControllerPage",
  mixins: [createWsMixin('controller')],
  data() {
    return {
      confirmReset: false,
      showSetVinto: false,
      setVintoTeam: null,
      showConfig: false,
      showCambiTeam: false,
      showCambi: false,
      cambiTeam: "home",
      cambiData: [{ in: "", out: "" }, { in: "", out: "" }],
      cambiError: "",
      configData: {
        nomeHome: "", nomeGuest: "", modalita: "3/5",
        formHome: ["1", "2", "3", "4", "5", "6"],
        formGuest: ["1", "2", "3", "4", "5", "6"],
      },
      isLandscape: window.innerWidth > window.innerHeight,
      showTimeoutModal: false,
      timeoutTeamSel: null,
      timeoutVideoSel: null,
      spotList: [],
      spotDurations: {},
      nowTick: Date.now(),
      timeoutTicker: null,
    }
  },
  computed: {
    isEstesa() { return this.isLandscape },
    primaSquadra() { return this.state.order ? 'home' : 'guest' },
    secondaSquadra() { return this.state.order ? 'guest' : 'home' },
    isPunteggioZeroZero() {
      return this.state.sp.striscia.at(-1).ris === ''
    },
    squadraVincente() {
      const { home, guest } = this.punt
      const sv = this.set
      const totSet = sv.home + sv.guest
      const isSetDecisivo = this.state.modalitaPartita === '2/3' ? totSet >= 2 : totSet >= 4
      const soglia = isSetDecisivo ? 15 : 25
      if (home >= soglia && home - guest >= 2) return 'home'
      if (guest >= soglia && guest - home >= 2) return 'guest'
      return null
    },
    isPartitaFinita() {
      if (!this.setVintoTeam || this.state.modalitaPartita === 'amichevole') return false
      const setsToWin = this.state.modalitaPartita === '2/3' ? 2 : 3
      return this.set[this.setVintoTeam] + 1 >= setsToWin
    },
    cambiValid() {
      let hasComplete = false
      for (const c of this.cambiData) {
        const cin = (c.in || "").trim(), cout = (c.out || "").trim()
        if (!cin && !cout) continue
        if (!cin || !cout) return false
        hasComplete = true
      }
      return hasComplete
    },
    timeoutRemaining() {
      if (!this.state.timeout || !this.state.timeoutStartedAt) return 30
      const trascorsi = (this.nowTick - this.state.timeoutStartedAt) / 1000
      return Math.max(0, Math.ceil(30 - trascorsi))
    },
    timeoutCountdown() {
      const r = this.timeoutRemaining
      const m = String(Math.floor(r / 60)).padStart(2, '0')
      const s = String(r % 60).padStart(2, '0')
      return `${m}:${s}`
    },
  },
  watch: {
    squadraVincente(val) {
      if (val && !this.showSetVinto) {
        this.setVintoTeam = val
        this.showSetVinto = true
      }
    },
    'state.timeout': {
      immediate: true,
      handler(attivo) {
        attivo ? this.avviaTimeoutTicker() : this.fermaTimeoutTicker()
      },
    },
  },
  mounted() {
    this._resizeHandler = () => { this.isLandscape = window.innerWidth > window.innerHeight }
    window.addEventListener('resize', this._resizeHandler)
    window.addEventListener('orientationchange', this._resizeHandler)
  },
  beforeUnmount() {
    window.removeEventListener('resize', this._resizeHandler)
    window.removeEventListener('orientationchange', this._resizeHandler)
    this.fermaTimeoutTicker()
  },
  methods: {
    generaReferto,
    onWsMessage(msg) {
      if (msg.type === 'error') this.showErrorFeedback(msg.message)
    },
    sendAction(action) {
      if (!action?.type) return
      if (!this.sendWs({ type: 'action', action })) this.showErrorFeedback('Non connesso al server')
    },
    showErrorFeedback(message) {
      console.error('[Controller] Error:', message)
    },
    doReset() {
      this.sendAction({ type: 'resetta' })
      this.confirmReset = false
      this.configData = {
        nomeHome: this.state.sp.nomi.home,
        nomeGuest: this.state.sp.nomi.guest,
        modalita: this.state.modalitaPartita,
        formHome: ["1", "2", "3", "4", "5", "6"],
        formGuest: ["1", "2", "3", "4", "5", "6"],
      }
      this.showConfig = true
    },
    undoUltimoPoint() {
      this.sendAction({ type: 'decPunt' })
      this.showSetVinto = false
    },
    doNuovoSet() {
      this.sendAction({ type: 'nuovoSet', team: this.setVintoTeam })
      this.showSetVinto = false
      this.configData = {
        nomeHome: this.state.sp.nomi.home,
        nomeGuest: this.state.sp.nomi.guest,
        modalita: this.state.modalitaPartita,
        formHome: ["1", "2", "3", "4", "5", "6"],
        formGuest: ["1", "2", "3", "4", "5", "6"],
      }
      this.showConfig = true
    },
    openConfig() {
      this.configData = {
        nomeHome: this.state.sp.nomi.home,
        nomeGuest: this.state.sp.nomi.guest,
        modalita: this.state.modalitaPartita,
        formHome: [...this.state.sp.form.home],
        formGuest: [...this.state.sp.form.guest],
      }
      this.showConfig = true
    },
    saveConfig() {
      this.sendAction({ type: 'setNomi', home: this.configData.nomeHome, guest: this.configData.nomeGuest })
      this.sendAction({ type: 'setModalita', modalita: this.configData.modalita })
      this.sendAction({ type: 'setFormazione', team: 'home', form: this.configData.formHome })
      this.sendAction({ type: 'setFormazione', team: 'guest', form: this.configData.formGuest })
      this.showConfig = false
    },
    openCambiTeam() { this.showCambiTeam = true },
    openCambi(team) {
      this.showCambiTeam = false
      this.cambiTeam = team
      this.cambiData = [{ in: "", out: "" }, { in: "", out: "" }]
      this.cambiError = ""
      this.showCambi = true
    },
    closeCambi() {
      this.showCambi = false
      this.cambiData = [{ in: "", out: "" }, { in: "", out: "" }]
      this.cambiError = ""
    },
    confermaCambi() {
      if (!this.cambiValid) return
      this.cambiError = ""
      const cambi = this.cambiData
        .filter(c => (c.in || "").trim() && (c.out || "").trim())
        .map(c => ({ in: c.in.trim(), out: c.out.trim() }))
      const formSimulata = this.state.sp.form[this.cambiTeam].map(v => String(v).trim())
      for (const cambio of cambi) {
        if (!/^\d+$/.test(cambio.in) || !/^\d+$/.test(cambio.out)) {
          this.cambiError = "I numeri dei giocatori devono essere cifre"; return
        }
        if (cambio.in === cambio.out) {
          this.cambiError = `Il giocatore ${cambio.in} non può sostituire sé stesso`; return
        }
        if (formSimulata.includes(cambio.in)) {
          this.cambiError = `Il giocatore ${cambio.in} è già in formazione`; return
        }
        if (!formSimulata.includes(cambio.out)) {
          this.cambiError = `Il giocatore ${cambio.out} non è in formazione`; return
        }
        formSimulata.splice(formSimulata.indexOf(cambio.out), 1, cambio.in)
      }
      this.sendAction({ type: 'confermaCambi', team: this.cambiTeam, cambi })
      this.closeCambi()
    },
    speak() {
      const { home, guest } = this.punt
      const text = home + guest === 0 ? "zero a zero"
        : home === guest ? `${home} pari`
        : this.servHome ? `${home} a ${guest}` : `${guest} a ${home}`
      this.sendWs({ type: 'speak', text })
    },
    avviaTimeoutTicker() {
      this.fermaTimeoutTicker()
      this.nowTick = Date.now()
      this.timeoutTicker = setInterval(() => { this.nowTick = Date.now() }, 250)
    },
    fermaTimeoutTicker() {
      if (this.timeoutTicker) { clearInterval(this.timeoutTicker); this.timeoutTicker = null }
    },
    async openTimeout() {
      this.timeoutTeamSel = null
      this.timeoutVideoSel = null
      this.spotList = []
      this.spotDurations = {}
      this.showTimeoutModal = true
      try {
        const res = await fetch('/spot/list')
        this.spotList = await res.json()
      } catch {
        this.spotList = []
      }
      this.spotList.forEach(file => this.probeDurata(file))
    },
    probeDurata(file) {
      const video = document.createElement('video')
      video.preload = 'metadata'
      video.onloadedmetadata = () => {
        this.spotDurations = { ...this.spotDurations, [file]: video.duration }
      }
      video.src = '/spot/' + encodeURIComponent(file)
    },
    formatDurata(sec) {
      return typeof sec === 'number' && isFinite(sec) ? `${Math.round(sec)}s` : '…'
    },
    avviaTimeout() {
      if (!this.timeoutTeamSel) return
      this.sendAction({ type: 'startTimeout', team: this.timeoutTeamSel, video: this.timeoutVideoSel })
      this.showTimeoutModal = false
    },
    terminaTimeout() {
      this.sendAction({ type: 'stopTimeout' })
    },
  },
}
</script>

<style scoped>
.controller-page {
  min-height: 100vh;
  background: #111;
  color: #fff;
  padding: 8px;
  padding-top: 36px;
  font-family: 'Inter', system-ui, sans-serif;
  -webkit-user-select: none;
  user-select: none;
  overflow-x: hidden;
}

/* Barra stato connessione */
.conn-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  background: #c62828;
  color: white;
  z-index: 200;
  transition: background 0.3s;
}
.conn-bar.connected {
  background: #2e7d32;
}

/* Banner modalità time out */
.timeout-banner {
  background: #e65100;
  color: #fff;
  text-align: center;
  font-weight: 800;
  letter-spacing: 0.04em;
  padding: 10px;
  border-radius: 10px;
  margin-bottom: 8px;
  animation: timeout-pulse 1.2s ease-in-out infinite;
}

/* Pulsante time out evidenziato quando attivo */
.btn-timeout.active {
  background: #e65100;
  color: #fff;
  box-shadow: 0 0 0 2px rgba(255, 152, 0, 0.6);
  animation: timeout-pulse 1.2s ease-in-out infinite;
}

@keyframes timeout-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}
.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: white;
}

/* ── MODALITÀ MOBILE ── */

.score-preview {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
}
.team-score {
  flex: 1;
  border-radius: 16px;
  background: #161618;
  border: 1px solid rgba(255,255,255,0.07);
  overflow: hidden;
  padding: 14px 12px 14px;
  text-align: center;
  cursor: pointer;
  position: relative;
  transition: transform 0.1s;
  min-height: 110px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.team-score::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
}
.team-score:active { transform: scale(0.97); }

/* stripe colorata come nella versione estesa */
.home-bg::before { background: #f5c518; }
.guest-bg::before { background: #2196f3; }

.team-name {
  font-size: 13px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  color: #f0f0f0;
  margin-bottom: 4px;
}
.team-pts {
  font-size: 54px;
  font-weight: 900;
  line-height: 1;
}
.home-bg .team-pts { color: #f5c518; }
.guest-bg .team-pts { color: #2196f3; }
.team-set {
  font-size: 11px;
  font-weight: 700;
  margin-top: 4px;
  color: #888;
}
.serv-icon {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 20px;
  height: 20px;
}

.undo-row {
  margin-bottom: 8px;
}
.btn-undo {
  width: 100%;
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,171,145,0.2);
  color: #ffab91;
  padding: 10px;
  font-size: 13px;
  font-weight: 700;
  border-radius: 10px;
  cursor: pointer;
}
.btn-undo:active { background: rgba(255,100,50,0.2); }

.action-row {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
}
.btn-set {
  flex: 1;
  padding: 11px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.2px;
  border-radius: 10px;
  cursor: pointer;
  border: none;
  text-transform: uppercase;
  transition: opacity 0.1s;
}
.btn-set:active { transform: scale(0.97); opacity: 0.8; }
.btn-set.home-bg { background: #f5c518; color: #111; }
.btn-set.guest-bg { background: #2196f3; color: #fff; }

.controls {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.btn {
  border: none;
  font-family: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.btn-ctrl {
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.1);
  color: #bbb;
  padding: 14px 8px;
  font-size: 13px;
  font-weight: 600;
  border-radius: 10px;
  transition: background 0.12s;
}
.btn-ctrl:active { background: rgba(255,255,255,0.16); }
.btn-ctrl:disabled { opacity: 0.28; }

.btn-danger {
  background: rgba(180,30,30,0.2);
  border: 1px solid rgba(239,83,80,0.3);
  color: #ff6b6b;
  padding: 14px 8px;
  font-size: 13px;
  font-weight: 600;
  border-radius: 10px;
}
.btn-danger:active { background: rgba(198,40,40,0.4); }

/* ── MODALITÀ ESTESA ── */

.e-dash {
  position: fixed;
  top: 28px; /* altezza conn-bar */
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  padding: 10px;
  gap: 8px;
  box-sizing: border-box;
  overflow: hidden;
  background: #111;
}

.e-panels {
  display: flex;
  flex: 1;
  gap: 10px;
  min-height: 0;
}

/* Pannello squadra */
.e-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  border-radius: 16px;
  overflow: hidden;
  background: #161618;
  border: 1px solid rgba(255,255,255,0.07);
  min-height: 0;
}

/* Barra colorata in cima — identità squadra */
.e-panel__stripe {
  height: 5px;
  flex-shrink: 0;
}
.e-panel--home .e-panel__stripe { background: #f5c518; }
.e-panel--guest .e-panel__stripe { background: #2196f3; }

.e-panel__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 14px 16px 14px;
  min-height: 0;
}

/* Header */
.e-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}
.e-panel__name {
  font-size: 15px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  color: #f0f0f0;
}
.e-panel__meta {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 700;
}
.e-panel--home .e-panel__meta { color: #f5c518; }
.e-panel--guest .e-panel__meta { color: #2196f3; }
.e-label {
  font-size: 9px;
  letter-spacing: 1px;
  opacity: 0.6;
  font-weight: 600;
}
.e-panel__serv { width: 14px; height: 14px; }

/* Score — l'elemento eroe */
.e-panel__score {
  font-size: clamp(60px, 14vh, 110px);
  font-weight: 900;
  line-height: 1;
  text-align: center;
  cursor: pointer;
  border-radius: 12px;
  padding: 6px 0;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
  transition: opacity 0.1s, transform 0.1s;
  user-select: none;
}
.e-panel__score:active { opacity: 0.65; transform: scale(0.96); }
.e-panel--home .e-panel__score { color: #f5c518; }
.e-panel--guest .e-panel__score { color: #2196f3; }

/* Campo formazione — diagramma del campo */
.e-panel__court {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  background: rgba(34, 80, 34, 0.18);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 10px;
  padding: 8px 10px;
  height: clamp(120px, 28vh, 200px);
}
.e-court__row {
  flex: 1;
  display: flex;
  gap: 6px;
  min-height: 0;
}
.e-court__cell {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(13px, 2.4vh, 22px);
  font-weight: 700;
  color: #ddd;
  background: rgba(255,255,255,0.07);
  border-radius: 6px;
  min-height: 0;
}
.e-court__net {
  height: 2px;
  background: rgba(255,255,255,0.18);
  margin: 5px 0;
  border-radius: 1px;
  flex-shrink: 0;
}

/* SET button — pieno colore, fondo pannello */
.e-panel__setbtn {
  flex-shrink: 0;
  width: 100%;
  padding: 9px 0;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: opacity 0.1s;
}
.e-panel__setbtn:active { opacity: 0.75; transform: scale(0.98); }
.e-panel--home .e-panel__setbtn { background: #f5c518; color: #111; }
.e-panel--guest .e-panel__setbtn { background: #2196f3; color: #fff; }

/* Barra azioni secondarie */
.e-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
  height: 40px;
}
.e-act {
  flex: 1;
  height: 100%;
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2px;
  border-radius: 8px;
  border: 1px solid rgba(255,255,255,0.1);
  background: rgba(255,255,255,0.07);
  color: #bbb;
  cursor: pointer;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.12s;
}
.e-act:active { background: rgba(255,255,255,0.16); }
.e-act:disabled { opacity: 0.28; cursor: not-allowed; }
.e-act--undo { color: #ffab91; border-color: rgba(255,171,145,0.2); }
.e-act--danger { background: rgba(180,30,30,0.2); border-color: rgba(239,83,80,0.3); color: #ff6b6b; }
.e-act--danger:active { background: rgba(198,40,40,0.4); }

/* ── OVERLAY E DIALOGS ── */

.overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.75);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 300;
  padding: 16px;
}

.dialog {
  background: #1e1e1e;
  border-radius: 20px;
  padding: 24px;
  width: 100%;
  max-width: 400px;
  border: 1px solid rgba(255,255,255,0.12);
}

.dialog-winner {
  font-size: 28px;
  font-weight: 900;
  text-align: center;
  margin-bottom: 8px;
}

.dialog-subtitle {
  font-size: 13px;
  color: #aaa;
  text-align: center;
  margin-bottom: 4px;
}

.dialog-config {
  max-height: 85vh;
  overflow-y: auto;
}

.dialog-title {
  font-size: 18px;
  font-weight: 800;
  text-align: center;
  margin-bottom: 20px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(255,255,255,0.12);
}

.dialog-buttons {
  display: flex;
  gap: 12px;
  margin-top: 20px;
}

.btn-cancel {
  flex: 1;
  background: rgba(255,255,255,0.08);
  color: #aaa;
  padding: 12px;
  border-radius: 12px;
  font-size: 15px;
  font-weight: 600;
  border: none;
  cursor: pointer;
  font-family: inherit;
}

.btn-secondary {
  flex: 1;
  background: rgba(255,255,255,0.14);
  color: #ccc;
  padding: 12px;
  border-radius: 12px;
  font-size: 15px;
  font-weight: 600;
  border: 1px solid rgba(255,255,255,0.2);
  cursor: pointer;
  font-family: inherit;
}

.btn-confirm {
  flex: 1;
  background: #2e7d32;
  color: white;
  padding: 12px;
  border-radius: 12px;
  font-size: 15px;
  font-weight: 700;
  border: none;
  cursor: pointer;
  font-family: inherit;
}
.btn-confirm:disabled {
  opacity: 0.4;
}

.form-group {
  margin-bottom: 16px;
}
.form-group label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: #aaa;
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.input-field {
  width: 100%;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.2);
  color: white;
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 16px;
  box-sizing: border-box;
}
.input-field:focus {
  outline: none;
  border-color: #64b5f6;
}

.input-num {
  width: 52px;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.2);
  color: white;
  padding: 8px;
  border-radius: 8px;
  font-size: 18px;
  text-align: center;
  box-sizing: border-box;
}
.input-num:focus {
  outline: none;
  border-color: #64b5f6;
}

.form-grid {
  background: rgba(205, 133, 63, 0.15);
  border: 2px solid rgba(255,255,255,0.15);
  border-radius: 12px;
  padding: 12px;
}
.form-row {
  display: flex;
  justify-content: center;
  gap: 10px;
  padding: 8px 0;
}
.form-line {
  border-top: 1px dashed rgba(255,255,255,0.3);
  margin: 4px 0;
}

.mode-buttons {
  display: flex;
  gap: 8px;
}
.btn-mode {
  flex: 1;
  padding: 10px;
  background: rgba(255,255,255,0.08);
  color: #aaa;
  border-radius: 10px;
  font-size: 16px;
  font-weight: 700;
  transition: all 0.15s;
  border: none;
  cursor: pointer;
  font-family: inherit;
}
.btn-mode.active {
  background: #2e7d32;
  color: white;
}

.cambi-container {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 8px 0;
}
.cambio-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}
.cambio-arrow {
  font-size: 20px;
  font-weight: 700;
  color: #aaa;
}
.cambi-in-field {
  background: rgba(120, 200, 120, 0.2) !important;
  border-color: rgba(120, 200, 120, 0.4) !important;
}
.cambi-out-field {
  background: rgba(200, 120, 120, 0.2) !important;
  border-color: rgba(200, 120, 120, 0.4) !important;
}
.cambi-error {
  color: #ff6b6b;
  font-size: 14px;
  text-align: center;
  padding: 8px 0;
  font-weight: 600;
}

/* Modal avvio time out */
.dialog-timeout {
  max-height: 85vh;
  overflow-y: auto;
}
.btn-set.team-sel-active {
  box-shadow: 0 0 0 3px rgba(255,255,255,0.6) inset;
}
.timeout-video-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 40vh;
  overflow-y: auto;
}
.timeout-video-option {
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 14px;
  cursor: pointer;
}
.video-duration {
  margin-left: auto;
  color: #aaa;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
</style>
