feat: modalità estesa controller con dashboard landscape
Aggiunge una seconda modalità dashboard per schermi orizzontali, rilevata automaticamente dall'orientamento (landscape → estesa, portrait → mobile) tramite resize/orientationchange listener. Layout estesa: due pannelli affiancati con stripe colorata in cima (giallo/blu per identità squadra), score grande come elemento eroe, diagramma campo in verde scuro, SET button a colori pieni in fondo. Barra azioni compatta (40px) con tutti i controlli secondari. Il pannello usa position:fixed ancorato al viewport per impedire qualsiasi scroll, con @wheel.prevent e @touchmove.prevent.
This commit is contained in:
@@ -6,66 +6,147 @@
|
||||
{{ wsConnected ? 'Connesso' : 'Connessione...' }}
|
||||
</div>
|
||||
|
||||
<!-- 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" />
|
||||
<!-- ══════════════════ 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>
|
||||
<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" />
|
||||
|
||||
<!-- 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-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 e-act--danger" @click="confirmReset = true">Reset</button>
|
||||
</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-danger" @click="confirmReset = true">
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
<!-- ══════════════════ DIALOGS (condivisi) ══════════════════ -->
|
||||
|
||||
<!-- Finestra conferma reset -->
|
||||
<div class="overlay" v-if="confirmReset" @click.self="confirmReset = false">
|
||||
@@ -213,9 +294,11 @@ export default {
|
||||
formHome: ["1", "2", "3", "4", "5", "6"],
|
||||
formGuest: ["1", "2", "3", "4", "5", "6"],
|
||||
},
|
||||
isLandscape: window.innerWidth > window.innerHeight,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isEstesa() { return this.isLandscape },
|
||||
primaSquadra() { return this.state.order ? 'home' : 'guest' },
|
||||
secondaSquadra() { return this.state.order ? 'guest' : 'home' },
|
||||
isPunteggioZeroZero() {
|
||||
@@ -255,6 +338,15 @@ export default {
|
||||
}
|
||||
},
|
||||
},
|
||||
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)
|
||||
},
|
||||
methods: {
|
||||
onWsMessage(msg) {
|
||||
if (msg.type === 'error') this.showErrorFeedback(msg.message)
|
||||
@@ -370,6 +462,7 @@ export default {
|
||||
font-family: 'Inter', system-ui, sans-serif;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* Barra stato connessione */
|
||||
@@ -400,7 +493,8 @@ export default {
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* Anteprima punteggio */
|
||||
/* ── MODALITÀ MOBILE ── */
|
||||
|
||||
.score-preview {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
@@ -459,7 +553,6 @@ export default {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* Riga annulla punto */
|
||||
.undo-row {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
@@ -478,7 +571,6 @@ export default {
|
||||
background: rgba(255,100,50,0.2);
|
||||
}
|
||||
|
||||
/* Pulsanti set */
|
||||
.action-row {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
@@ -498,7 +590,6 @@ export default {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
/* Griglia controlli */
|
||||
.controls {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
@@ -529,6 +620,7 @@ export default {
|
||||
opacity: 0.35;
|
||||
}
|
||||
|
||||
|
||||
.btn-danger {
|
||||
background: rgba(198, 40, 40, 0.25);
|
||||
border: 1px solid rgba(239, 83, 80, 0.4);
|
||||
@@ -542,7 +634,195 @@ export default {
|
||||
background: rgba(198, 40, 40, 0.45);
|
||||
}
|
||||
|
||||
/* Overlay e finestre modali */
|
||||
/* ── 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;
|
||||
@@ -608,6 +888,9 @@ export default {
|
||||
border-radius: 12px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.btn-confirm {
|
||||
@@ -618,12 +901,14 @@ export default {
|
||||
border-radius: 12px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
}
|
||||
.btn-confirm:disabled {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
/* Gruppi form */
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
@@ -667,7 +952,6 @@ export default {
|
||||
border-color: #64b5f6;
|
||||
}
|
||||
|
||||
/* Griglia formazione */
|
||||
.form-grid {
|
||||
background: rgba(205, 133, 63, 0.15);
|
||||
border: 2px solid rgba(255,255,255,0.15);
|
||||
@@ -685,7 +969,6 @@ export default {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
/* Pulsanti modalita */
|
||||
.mode-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
@@ -699,13 +982,15 @@ export default {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
transition: all 0.15s;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
}
|
||||
.btn-mode.active {
|
||||
background: #2e7d32;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Sezione cambi */
|
||||
.cambi-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user