.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
+1
-1
@@ -21,7 +21,7 @@
|
||||
<h1>Liste de karaokés - 2026</h1>
|
||||
<p>Vous pouvez télécharger la liste des karaokés entière. Ou effectuer une recherche dans la liste tout en bas.</p>
|
||||
<div class="nav">
|
||||
<a href="Liste karaoké 2026.pdf" target="_BLANK">Liste Karaoké 2026</a>
|
||||
<a href="Liste karaoké 2026 v2.pdf" target="_BLANK">Liste Karaoké 2026</a>
|
||||
</div>
|
||||
<br>
|
||||
<hr>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const resultsList = document.getElementById('results');
|
||||
|
||||
// Charger le fichier CSV
|
||||
fetch('Liste karaoké 2026.csv')
|
||||
fetch('Liste karaoké 2026 v2.csv')
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
const lines = data.split('\n');
|
||||
|
||||
@@ -0,0 +1,616 @@
|
||||
:root {
|
||||
--poker-green: #1a5e33;
|
||||
--poker-border: #3e2723;
|
||||
--gold: #d4af37;
|
||||
--dark-bg: #0a0a0a;
|
||||
--panel-bg: #1a1a1a;
|
||||
--white: #ffffff;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-bg);
|
||||
color: var(--white);
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
margin: 0;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.game-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 1. Barre de stats */
|
||||
.stats-bar {
|
||||
background: rgba(0,0,0,0.8);
|
||||
padding: 15px 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 2px solid var(--poker-border);
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
font-size: 1.2rem;
|
||||
color: var(--gold);
|
||||
}
|
||||
|
||||
/* 2. Table de jeu */
|
||||
.table-container {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding: 60px; /* Espace pour les noms des joueurs */
|
||||
}
|
||||
|
||||
.poker-table {
|
||||
width: 800px;
|
||||
height: 400px;
|
||||
background-color: var(--poker-green);
|
||||
border: 15px solid var(--poker-border);
|
||||
border-radius: 200px;
|
||||
position: relative;
|
||||
box-shadow: inset 0 0 80px rgba(0,0,0,0.8), 0 10px 30px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.pot-area {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.total-pot {
|
||||
font-size: 3rem;
|
||||
font-weight: bold;
|
||||
color: var(--white);
|
||||
text-shadow: 2px 2px 10px rgba(0,0,0,0.8);
|
||||
}
|
||||
|
||||
.current-bet-display {
|
||||
font-size: 1.2rem;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* 3. Positionnement des joueurs (8 slots) */
|
||||
.player-slot {
|
||||
position: absolute;
|
||||
width: 140px;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.player-info {
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
border: 2px solid var(--gold);
|
||||
border-radius: 12px;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.player-info.active {
|
||||
box-shadow: 0 0 25px var(--gold);
|
||||
transform: scale(1.1);
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
.player-name {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
color: var(--gold);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.player-money {
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Coordonnées autour de l'ovale */
|
||||
.slot-0 { top: -60px; left: 50%; transform: translateX(-50%); }
|
||||
.slot-1 { top: 0%; right: -110px; }
|
||||
.slot-2 { top: 50%; right: -150px; transform: translateY(-50%); }
|
||||
.slot-3 { bottom: 0%; right: -110px; }
|
||||
.slot-4 { bottom: -60px; left: 50%; transform: translateX(-50%); }
|
||||
.slot-5 { bottom: 0%; left: -110px; }
|
||||
.slot-6 { top: 50%; left: -150px; transform: translateY(-50%); }
|
||||
.slot-7 { top: 0%; left: -110px; }
|
||||
|
||||
/* 4. Panneau d'action */
|
||||
.action-panel {
|
||||
background: var(--panel-bg);
|
||||
border-top: 4px solid var(--gold);
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.turn-info {
|
||||
margin: 0 0 15px 0;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 15px 30px;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
text-transform: uppercase;
|
||||
transition: 0.2s;
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.btn-fold { background: #444; color: white; }
|
||||
.btn-call { background: var(--poker-green); color: white; border: 1px solid var(--gold); }
|
||||
.btn-raise { background: #1e88e5; color: white; }
|
||||
.btn-allin {
|
||||
background: linear-gradient(45deg, #d4af37, #f9e27d);
|
||||
color: #3e2723;
|
||||
box-shadow: 0 4px 15px rgba(212, 175, 55, 0.4);
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-5px);
|
||||
filter: brightness(1.2);
|
||||
}
|
||||
|
||||
/* --- Styles pour le bloc Augmenter --- */
|
||||
.raise-group {
|
||||
display: flex;
|
||||
align-items: stretch; /* Pour que l'input et le bouton aient la même hauteur */
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
#raise-amount {
|
||||
width: 100px;
|
||||
padding: 10px;
|
||||
border: 2px solid var(--gold);
|
||||
border-right: none; /* On retire la bordure droite pour coller au bouton */
|
||||
border-radius: 8px 0 0 8px; /* Arrondi seulement à gauche */
|
||||
background: #222;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.btn-validate {
|
||||
padding: 10px 15px;
|
||||
background: var(--gold);
|
||||
color: var(--poker-border);
|
||||
border: 2px solid var(--gold);
|
||||
border-radius: 0 8px 8px 0; /* Arrondi seulement à droite */
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
text-transform: uppercase;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.btn-validate:hover {
|
||||
background: #f9e27d;
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
/* Suppression des flèches par défaut de l'input number pour un look plus propre */
|
||||
#raise-amount::-webkit-inner-spin-button,
|
||||
#raise-amount::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.guide-overlay {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
border: 2px solid var(--gold);
|
||||
padding: 20px;
|
||||
border-radius: 15px;
|
||||
z-index: 1000;
|
||||
text-align: center;
|
||||
box-shadow: 0 0 30px rgba(212, 175, 55, 0.5);
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
.guide-content h2 {
|
||||
margin: 0 0 15px 0;
|
||||
color: white;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#guide-btn {
|
||||
background: var(--gold);
|
||||
color: black;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 5px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.dealer-badge {
|
||||
position: absolute;
|
||||
top: -15px;
|
||||
right: -15px;
|
||||
background: linear-gradient(45deg, #ffd700, #b8860b);
|
||||
color: #000;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
border: 2px solid #fff;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.5);
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
/* On peut aussi ajouter un effet d'ombre sur le joueur qui commence */
|
||||
.player-info.is-dealer {
|
||||
border-color: #ffd700;
|
||||
}
|
||||
|
||||
.btn-next-round {
|
||||
margin-top: 15px;
|
||||
padding: 10px 20px;
|
||||
background: var(--gold);
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
|
||||
transition: 0.3s;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.btn-next-round:hover {
|
||||
transform: scale(1.1);
|
||||
background: #fff;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.player-bet {
|
||||
font-size: 0.9rem;
|
||||
color: rgb(141, 141, 141);
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.btn-spaction {
|
||||
background: transparent;
|
||||
color: var(--gold);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid var(--gold);
|
||||
border-radius: 5px;
|
||||
transition: background 0.3s, color 0.3s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Le panneau qui contient tout le message de fin */
|
||||
/* Le rideau qui floute l'arrière-plan */
|
||||
.win-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.7); /* Fond noir semi-transparent */
|
||||
backdrop-filter: blur(8px); /* C'est ici qu'on met le flou ! */
|
||||
z-index: 9998; /* Juste en dessous du panel */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* On ajuste le win-panel pour qu'il soit propre à l'intérieur */
|
||||
.win-panel {
|
||||
position: relative; /* Plus besoin de fixed ici car l'overlay l'est déjà */
|
||||
background: #1a1a1a;
|
||||
padding: 40px;
|
||||
border-radius: 20px;
|
||||
border: 3px solid #ffd700;
|
||||
box-shadow: 0 0 50px rgba(0, 0, 0, 1);
|
||||
z-index: 9999;
|
||||
text-align: center;
|
||||
min-width: 400px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 25px;
|
||||
}
|
||||
|
||||
/* Le titre dans le panel */
|
||||
.win-panel h2 {
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
font-family: 'Arial Black', sans-serif;
|
||||
text-transform: uppercase;
|
||||
line-height: 1.4;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
/* Zone qui contient les boutons des joueurs */
|
||||
#winner-buttons-area {
|
||||
display: flex;
|
||||
flex-wrap: wrap; /* Si beaucoup de joueurs, ils vont à la ligne */
|
||||
justify-content: center;
|
||||
gap: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Tes boutons .btn-win (on réutilise le style Or précédent) */
|
||||
.btn-win {
|
||||
background: linear-gradient(to bottom, #ffd700, #b8860b);
|
||||
border: 2px solid #8b4513;
|
||||
color: #000;
|
||||
padding: 15px 30px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
border-radius: 8px;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.btn-win:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.btn-win:active {
|
||||
transform: translateY(3px);
|
||||
box-shadow: 0 1px 0 #5d2e0a;
|
||||
}
|
||||
|
||||
/* Base commune pour tous les boutons de l'interface */
|
||||
.btn-back, .btn-replay, .btn-spaction {
|
||||
text-decoration: none;
|
||||
border-radius: 8px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
padding: 10px 20px;
|
||||
text-transform: uppercase;
|
||||
transition: all 0.2s ease;
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
/* Style spécifique : Rejouer (Style Action / Casino) */
|
||||
.btn-replay {
|
||||
padding: 10px 20px;
|
||||
background: linear-gradient(to bottom, #5bc0de, #2aabd2); /* Bleu électrique */
|
||||
box-shadow: 0 4px 0 #1b728c;
|
||||
}
|
||||
|
||||
.btn-replay:hover {
|
||||
filter: brightness(1.1);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 0 #1b728c;
|
||||
}
|
||||
|
||||
/* Animation au clic pour les deux */
|
||||
.btn-back:active, .btn-replay:active, .btn-spaction:active {
|
||||
transform: translateY(3px);
|
||||
box-shadow: 0 1px 0 rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
/* Style spécifique : Retour (Style plus sobre / Alerte) */
|
||||
.btn-back {
|
||||
background: linear-gradient(to bottom, #d9534f, #a94442); /* Rouge profond */
|
||||
box-shadow: 0 4px 0 #7b2e2c;
|
||||
}
|
||||
|
||||
.btn-back:hover, .btn-spaction:hover {
|
||||
filter: brightness(1.1);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 0 #7b2e2c;
|
||||
}
|
||||
|
||||
.blur-effect {
|
||||
filter: blur(5px);
|
||||
pointer-events: none; /* Empêche de cliquer sur la table derrière */
|
||||
}
|
||||
|
||||
.All-in-Blur {
|
||||
filter: blur(1px);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Le conteneur avec la bordure dorée fine */
|
||||
.money-group {
|
||||
display: inline-flex;
|
||||
align-items: stretch; /* Force le bouton à prendre toute la hauteur */
|
||||
background: #1e1e1e; /* Fond très sombre pour faire ressortir l'or */
|
||||
border: 1px solid #c5a059; /* Bordure Or mat (plus sobre que le jaune brillant) */
|
||||
border-radius: 8px;
|
||||
overflow: hidden; /* Pour que le bouton épouse l'arrondi de la bordure */
|
||||
height: 40px; /* Hauteur fixe pour un look plus pro */
|
||||
}
|
||||
|
||||
/* Le champ de saisie */
|
||||
#money-amount {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: #ffffff;
|
||||
font-size: 1rem;
|
||||
padding: 0 15px;
|
||||
width: 100px; /* Ajustable selon tes besoins */
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Le bouton OK qui occupe tout l'espace à droite */
|
||||
.btn-money {
|
||||
background: linear-gradient(45deg, #d4af37, #f9e27d); /* Fond Or mat */
|
||||
border: none;
|
||||
color: #1e1e1e; /* Texte sombre pour le contraste */
|
||||
cursor: pointer;
|
||||
font-weight: 800;
|
||||
padding: 0 20px; /* Largeur du bouton */
|
||||
text-transform: uppercase;
|
||||
transition: background 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center; /* Centre le texte "OK" verticalement */
|
||||
}
|
||||
|
||||
.btn-money:hover {
|
||||
filter: brightness(1.2); /* Or un peu plus clair au survol */
|
||||
}
|
||||
|
||||
.btn-money:active {
|
||||
filter: brightness(0.8); /* Or plus sombre au clic */
|
||||
}
|
||||
|
||||
/* Suppression des flèches de l'input */
|
||||
#money-amount::-webkit-inner-spin-button,
|
||||
#money-amount::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* --- Mode Mobile (pour les petits écrans) --- */
|
||||
/* --- ADAPTATION MOBILE --- */
|
||||
@media (max-width: 900px) {
|
||||
|
||||
/* 1. On permet au corps de défiler si besoin, mais on réduit les espaces */
|
||||
body {
|
||||
height: auto;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* 2. Barre de stats plus compacte */
|
||||
.stats-bar {
|
||||
padding: 10px;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* 3. LA TABLE : On la réduit pour qu'elle tienne en largeur */
|
||||
.table-container {
|
||||
padding: 40px 10px; /* Moins d'espace autour */
|
||||
min-height: 450px;
|
||||
}
|
||||
|
||||
.poker-table {
|
||||
width: 100%; /* Elle prend toute la largeur dispo */
|
||||
max-width: 350px; /* Mais pas trop non plus */
|
||||
height: 300px;
|
||||
border-width: 8px;
|
||||
border-radius: 100px; /* Plus arrondie pour le format portrait */
|
||||
}
|
||||
|
||||
.total-pot {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
/* 4. POSITION DES JOUEURS : On resserre tout */
|
||||
.player-slot {
|
||||
width: 100px; /* Joueurs plus petits sur mobile */
|
||||
}
|
||||
|
||||
.player-name { font-size: 0.7rem; }
|
||||
.player-money { font-size: 0.9rem; }
|
||||
.player-bet { font-size: 0.7rem; }
|
||||
|
||||
/* Ajustement des positions pour que ça ne sorte pas de l'écran */
|
||||
.slot-0 { top: -45px; }
|
||||
.slot-1 { right: -20px; top: 10%; }
|
||||
.slot-2 { right: -40px; }
|
||||
.slot-3 { right: -20px; bottom: 10%; }
|
||||
.slot-4 { bottom: -45px; }
|
||||
.slot-5 { left: -20px; bottom: 10%; }
|
||||
.slot-6 { left: -40px; }
|
||||
.slot-7 { left: -20px; top: 10%; }
|
||||
|
||||
/* 5. PANNEAU D'ACTION : On empile les boutons */
|
||||
.action-panel {
|
||||
padding: 15px 10px;
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr; /* 2 colonnes de boutons */
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 12px 5px;
|
||||
min-width: 0; /* On laisse la grille gérer la largeur */
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
/* Le groupe de relance prend toute la largeur sur une ligne de la grille */
|
||||
.raise-group {
|
||||
grid-column: span 2;
|
||||
margin: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#raise-amount {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.btn-allin {
|
||||
grid-column: span 2; /* Le tapis prend toute la largeur pour bien le voir */
|
||||
}
|
||||
|
||||
/* 6. Guide de bienvenue */
|
||||
.guide-overlay {
|
||||
width: 90%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
/* Optionnel : Pour les très petits écrans (iPhone SE, etc.) */
|
||||
@media (max-width: 380px) {
|
||||
.poker-table {
|
||||
height: 250px;
|
||||
}
|
||||
.player-slot {
|
||||
width: 85px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.win-panel {
|
||||
padding: 20px;
|
||||
width: 95%;
|
||||
}
|
||||
.win-panel h2 {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,622 @@
|
||||
:root {
|
||||
--poker-green: #1a5e33;
|
||||
--poker-border: #3e2723;
|
||||
--gold: #d4af37;
|
||||
--dark-bg: #0a0a0a;
|
||||
--panel-bg: #1a1a1a;
|
||||
--white: #ffffff;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-bg);
|
||||
color: var(--white);
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
margin: 0;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.game-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 1. Barre de stats */
|
||||
.stats-bar {
|
||||
background: rgba(0,0,0,0.8);
|
||||
padding: 15px 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 2px solid var(--poker-border);
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
font-size: 1.2rem;
|
||||
color: var(--gold);
|
||||
}
|
||||
|
||||
/* 2. Table de jeu */
|
||||
.table-container {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding: 60px; /* Espace pour les noms des joueurs */
|
||||
}
|
||||
|
||||
.poker-table {
|
||||
width: 800px;
|
||||
height: 400px;
|
||||
background-color: var(--poker-green);
|
||||
border: 15px solid var(--poker-border);
|
||||
border-radius: 200px;
|
||||
position: relative;
|
||||
box-shadow: inset 0 0 80px rgba(0,0,0,0.8), 0 10px 30px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.pot-area {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.total-pot {
|
||||
font-size: 3rem;
|
||||
font-weight: bold;
|
||||
color: var(--white);
|
||||
text-shadow: 2px 2px 10px rgba(0,0,0,0.8);
|
||||
}
|
||||
|
||||
.current-bet-display {
|
||||
font-size: 1.2rem;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* 3. Positionnement des joueurs (8 slots) */
|
||||
.player-slot {
|
||||
position: absolute;
|
||||
width: 140px;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.player-info {
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
border: 2px solid var(--gold);
|
||||
border-radius: 12px;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.player-info.active {
|
||||
box-shadow: 0 0 25px var(--gold);
|
||||
transform: scale(1.1);
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
.player-name {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
color: var(--gold);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.player-money {
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Coordonnées autour de l'ovale */
|
||||
.slot-0 { top: -60px; left: 50%; transform: translateX(-50%); }
|
||||
.slot-1 { top: 0%; right: -110px; }
|
||||
.slot-2 { top: 50%; right: -150px; transform: translateY(-50%); }
|
||||
.slot-3 { bottom: 0%; right: -110px; }
|
||||
.slot-4 { bottom: -60px; left: 50%; transform: translateX(-50%); }
|
||||
.slot-5 { bottom: 0%; left: -110px; }
|
||||
.slot-6 { top: 50%; left: -150px; transform: translateY(-50%); }
|
||||
.slot-7 { top: 0%; left: -110px; }
|
||||
|
||||
/* 4. Panneau d'action */
|
||||
.action-panel {
|
||||
background: var(--panel-bg);
|
||||
border-top: 4px solid var(--gold);
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.turn-info {
|
||||
margin: 0 0 15px 0;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 15px 30px;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
text-transform: uppercase;
|
||||
transition: 0.2s;
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.btn-fold { background: #444; color: white; }
|
||||
.btn-call { background: var(--poker-green); color: white; border: 1px solid var(--gold); }
|
||||
.btn-raise { background: #1e88e5; color: white; }
|
||||
.btn-allin {
|
||||
background: linear-gradient(45deg, #d4af37, #f9e27d);
|
||||
color: #3e2723;
|
||||
box-shadow: 0 4px 15px rgba(212, 175, 55, 0.4);
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-5px);
|
||||
filter: brightness(1.2);
|
||||
}
|
||||
|
||||
/* --- Styles pour le bloc Augmenter --- */
|
||||
.raise-group {
|
||||
display: flex;
|
||||
align-items: stretch; /* Pour que l'input et le bouton aient la même hauteur */
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
#raise-amount {
|
||||
width: 100px;
|
||||
padding: 10px;
|
||||
border: 2px solid var(--gold);
|
||||
border-right: none; /* On retire la bordure droite pour coller au bouton */
|
||||
border-radius: 8px 0 0 8px; /* Arrondi seulement à gauche */
|
||||
background: #222;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.btn-validate {
|
||||
padding: 10px 15px;
|
||||
background: var(--gold);
|
||||
color: var(--poker-border);
|
||||
border: 2px solid var(--gold);
|
||||
border-radius: 0 8px 8px 0; /* Arrondi seulement à droite */
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
text-transform: uppercase;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.btn-validate:hover {
|
||||
background: #f9e27d;
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
/* Suppression des flèches par défaut de l'input number pour un look plus propre */
|
||||
#raise-amount::-webkit-inner-spin-button,
|
||||
#raise-amount::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.guide-overlay {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
border: 2px solid var(--gold);
|
||||
padding: 20px;
|
||||
border-radius: 15px;
|
||||
z-index: 1000;
|
||||
text-align: center;
|
||||
box-shadow: 0 0 30px rgba(212, 175, 55, 0.5);
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
.guide-content h2 {
|
||||
margin: 0 0 15px 0;
|
||||
color: white;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#guide-btn {
|
||||
background: var(--gold);
|
||||
color: black;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 5px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.dealer-badge {
|
||||
position: absolute;
|
||||
top: -15px;
|
||||
right: -15px;
|
||||
background: linear-gradient(45deg, #ffd700, #b8860b);
|
||||
color: #000;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
border: 2px solid #fff;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.5);
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
/* On peut aussi ajouter un effet d'ombre sur le joueur qui commence */
|
||||
.player-info.is-dealer {
|
||||
border-color: #ffd700;
|
||||
}
|
||||
|
||||
.btn-next-round {
|
||||
margin-top: 15px;
|
||||
padding: 10px 20px;
|
||||
background: var(--gold);
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
|
||||
transition: 0.3s;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.btn-next-round:hover {
|
||||
transform: scale(1.1);
|
||||
background: #fff;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.player-bet {
|
||||
font-size: 0.9rem;
|
||||
color: rgb(141, 141, 141);
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.btn-spaction {
|
||||
color: var(--white);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid var(--poker-border);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.btn-spaction {
|
||||
background: transparent;
|
||||
border: 1px solid var(--gold);
|
||||
color: var(--gold);
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
font-size: 0.9rem;
|
||||
transition: background 0.3s, color 0.3s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Le panneau qui contient tout le message de fin */
|
||||
/* Le rideau qui floute l'arrière-plan */
|
||||
.win-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.7); /* Fond noir semi-transparent */
|
||||
backdrop-filter: blur(8px); /* C'est ici qu'on met le flou ! */
|
||||
z-index: 9998; /* Juste en dessous du panel */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* On ajuste le win-panel pour qu'il soit propre à l'intérieur */
|
||||
.win-panel {
|
||||
position: relative; /* Plus besoin de fixed ici car l'overlay l'est déjà */
|
||||
background: #1a1a1a;
|
||||
padding: 40px;
|
||||
border-radius: 20px;
|
||||
border: 3px solid #ffd700;
|
||||
box-shadow: 0 0 50px rgba(0, 0, 0, 1);
|
||||
z-index: 9999;
|
||||
text-align: center;
|
||||
min-width: 400px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 25px;
|
||||
}
|
||||
|
||||
/* Le titre dans le panel */
|
||||
.win-panel h2 {
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
font-family: 'Arial Black', sans-serif;
|
||||
text-transform: uppercase;
|
||||
line-height: 1.4;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
/* Zone qui contient les boutons des joueurs */
|
||||
#winner-buttons-area {
|
||||
display: flex;
|
||||
flex-wrap: wrap; /* Si beaucoup de joueurs, ils vont à la ligne */
|
||||
justify-content: center;
|
||||
gap: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Tes boutons .btn-win (on réutilise le style Or précédent) */
|
||||
.btn-win {
|
||||
background: linear-gradient(to bottom, #ffd700, #b8860b);
|
||||
border: 2px solid #8b4513;
|
||||
color: #000;
|
||||
padding: 15px 30px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
border-radius: 8px;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.btn-win:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.btn-win:active {
|
||||
transform: translateY(3px);
|
||||
box-shadow: 0 1px 0 #5d2e0a;
|
||||
}
|
||||
|
||||
/* Base commune pour tous les boutons de l'interface */
|
||||
.btn-back, .btn-replay .btn-spaction {
|
||||
text-decoration: none;
|
||||
border-radius: 8px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
padding: 10px 20px;
|
||||
text-transform: uppercase;
|
||||
transition: all 0.2s ease;
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
/* Style spécifique : Retour (Style plus sobre / Alerte) */
|
||||
.btn-back {
|
||||
background: linear-gradient(to bottom, #d9534f, #a94442); /* Rouge profond */
|
||||
box-shadow: 0 4px 0 #7b2e2c;
|
||||
}
|
||||
|
||||
.btn-back:hover, .btn-spaction:hover {
|
||||
filter: brightness(1.1);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 0 #7b2e2c;
|
||||
}
|
||||
|
||||
/* Style spécifique : Rejouer (Style Action / Casino) */
|
||||
.btn-replay {
|
||||
background: linear-gradient(to bottom, #5bc0de, #2aabd2); /* Bleu électrique */
|
||||
box-shadow: 0 4px 0 #1b728c;
|
||||
}
|
||||
|
||||
.btn-replay:hover {
|
||||
filter: brightness(1.1);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 0 #1b728c;
|
||||
}
|
||||
|
||||
/* Animation au clic pour les deux */
|
||||
.btn-back:active, .btn-replay:active, .btn-spaction:active {
|
||||
transform: translateY(3px);
|
||||
box-shadow: 0 1px 0 rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.blur-effect {
|
||||
filter: blur(5px);
|
||||
pointer-events: none; /* Empêche de cliquer sur la table derrière */
|
||||
}
|
||||
|
||||
.All-in-Blur {
|
||||
filter: blur(1px);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Le conteneur avec la bordure dorée fine */
|
||||
.money-group {
|
||||
display: inline-flex;
|
||||
align-items: stretch; /* Force le bouton à prendre toute la hauteur */
|
||||
background: #1e1e1e; /* Fond très sombre pour faire ressortir l'or */
|
||||
border: 1px solid #c5a059; /* Bordure Or mat (plus sobre que le jaune brillant) */
|
||||
border-radius: 8px;
|
||||
overflow: hidden; /* Pour que le bouton épouse l'arrondi de la bordure */
|
||||
height: 40px; /* Hauteur fixe pour un look plus pro */
|
||||
}
|
||||
|
||||
/* Le champ de saisie */
|
||||
#money-amount {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: #ffffff;
|
||||
font-size: 1rem;
|
||||
padding: 0 15px;
|
||||
width: 100px; /* Ajustable selon tes besoins */
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Le bouton OK qui occupe tout l'espace à droite */
|
||||
.btn-money {
|
||||
background: linear-gradient(45deg, #d4af37, #f9e27d); /* Fond Or mat */
|
||||
border: none;
|
||||
color: #1e1e1e; /* Texte sombre pour le contraste */
|
||||
cursor: pointer;
|
||||
font-weight: 800;
|
||||
padding: 0 20px; /* Largeur du bouton */
|
||||
text-transform: uppercase;
|
||||
transition: background 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center; /* Centre le texte "OK" verticalement */
|
||||
}
|
||||
|
||||
.btn-money:hover {
|
||||
filter: brightness(1.2); /* Or un peu plus clair au survol */
|
||||
}
|
||||
|
||||
.btn-money:active {
|
||||
filter: brightness(0.8); /* Or plus sombre au clic */
|
||||
}
|
||||
|
||||
/* Suppression des flèches de l'input */
|
||||
#money-amount::-webkit-inner-spin-button,
|
||||
#money-amount::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* --- Mode Mobile (pour les petits écrans) --- */
|
||||
/* --- ADAPTATION MOBILE --- */
|
||||
@media (max-width: 900px) {
|
||||
|
||||
/* 1. On permet au corps de défiler si besoin, mais on réduit les espaces */
|
||||
body {
|
||||
height: auto;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* 2. Barre de stats plus compacte */
|
||||
.stats-bar {
|
||||
padding: 10px;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* 3. LA TABLE : On la réduit pour qu'elle tienne en largeur */
|
||||
.table-container {
|
||||
padding: 40px 10px; /* Moins d'espace autour */
|
||||
min-height: 450px;
|
||||
}
|
||||
|
||||
.poker-table {
|
||||
width: 100%; /* Elle prend toute la largeur dispo */
|
||||
max-width: 350px; /* Mais pas trop non plus */
|
||||
height: 300px;
|
||||
border-width: 8px;
|
||||
border-radius: 100px; /* Plus arrondie pour le format portrait */
|
||||
}
|
||||
|
||||
.total-pot {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
/* 4. POSITION DES JOUEURS : On resserre tout */
|
||||
.player-slot {
|
||||
width: 100px; /* Joueurs plus petits sur mobile */
|
||||
}
|
||||
|
||||
.player-name { font-size: 0.7rem; }
|
||||
.player-money { font-size: 0.9rem; }
|
||||
.player-bet { font-size: 0.7rem; }
|
||||
|
||||
/* Ajustement des positions pour que ça ne sorte pas de l'écran */
|
||||
.slot-0 { top: -45px; }
|
||||
.slot-1 { right: -20px; top: 10%; }
|
||||
.slot-2 { right: -40px; }
|
||||
.slot-3 { right: -20px; bottom: 10%; }
|
||||
.slot-4 { bottom: -45px; }
|
||||
.slot-5 { left: -20px; bottom: 10%; }
|
||||
.slot-6 { left: -40px; }
|
||||
.slot-7 { left: -20px; top: 10%; }
|
||||
|
||||
/* 5. PANNEAU D'ACTION : On empile les boutons */
|
||||
.action-panel {
|
||||
padding: 15px 10px;
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr; /* 2 colonnes de boutons */
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 12px 5px;
|
||||
min-width: 0; /* On laisse la grille gérer la largeur */
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
/* Le groupe de relance prend toute la largeur sur une ligne de la grille */
|
||||
.raise-group {
|
||||
grid-column: span 2;
|
||||
margin: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#raise-amount {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.btn-allin {
|
||||
grid-column: span 2; /* Le tapis prend toute la largeur pour bien le voir */
|
||||
}
|
||||
|
||||
/* 6. Guide de bienvenue */
|
||||
.guide-overlay {
|
||||
width: 90%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
/* Optionnel : Pour les très petits écrans (iPhone SE, etc.) */
|
||||
@media (max-width: 380px) {
|
||||
.poker-table {
|
||||
height: 250px;
|
||||
}
|
||||
.player-slot {
|
||||
width: 85px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.win-panel {
|
||||
padding: 20px;
|
||||
width: 95%;
|
||||
}
|
||||
.win-panel h2 {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/* index.css */
|
||||
:root {
|
||||
--poker-green: #0e5d32;
|
||||
--gold: #d4af37;
|
||||
--wood: #3e2723;
|
||||
--white: #ffffff;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #121212;
|
||||
background-image: radial-gradient(circle, #1a1a1a 0%, #000000 100%);
|
||||
color: var(--white);
|
||||
font-family: 'Segoe UI', sans-serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.welcome-container {
|
||||
background-color: var(--poker-green);
|
||||
padding: 50px;
|
||||
border-radius: 80px;
|
||||
border: 15px solid var(--wood);
|
||||
box-shadow: 0 0 60px rgba(0,0,0,0.9), inset 0 0 30px rgba(0,0,0,0.5);
|
||||
text-align: center;
|
||||
width: 90%;
|
||||
max-width: 450px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: var(--gold);
|
||||
text-transform: uppercase;
|
||||
font-size: 2.2rem;
|
||||
margin-bottom: 40px;
|
||||
text-shadow: 3px 3px 6px rgba(0,0,0,0.7);
|
||||
}
|
||||
|
||||
/* Style pour le lien "Démarrer une partie" */
|
||||
.btn-start {
|
||||
display: inline-block;
|
||||
background: linear-gradient(135deg, #d4af37 0%, #f9e27d 50%, #d4af37 100%);
|
||||
color: var(--wood);
|
||||
text-decoration: none;
|
||||
padding: 15px 30px;
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
border-radius: 40px;
|
||||
margin-bottom: 40px;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
box-shadow: 0 5px 15px rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.btn-start:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 0 20px rgba(212, 175, 55, 0.6);
|
||||
}
|
||||
|
||||
/* Section rejoindre */
|
||||
.join-section {
|
||||
border-top: 1px solid rgba(255,255,255,0.2);
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
color: var(--gold);
|
||||
margin-bottom: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border: 2px solid var(--gold);
|
||||
border-radius: 5px;
|
||||
padding: 12px;
|
||||
width: 60%;
|
||||
font-size: 1rem;
|
||||
margin-bottom: 15px;
|
||||
outline: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: var(--wood);
|
||||
color: var(--gold);
|
||||
border: 2px solid var(--gold);
|
||||
padding: 10px 20px;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #5d3a3a;
|
||||
}
|
||||
|
||||
.btn-join-list{
|
||||
background-color: transparent;
|
||||
color: var(--gold);
|
||||
padding-left: 12px;
|
||||
border: 1px solid var(--gold);
|
||||
padding: 8px 12px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.btn-join-list:hover {
|
||||
background-color: var(--gold);
|
||||
color: var(--wood);
|
||||
}
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* --- Mode Mobile --- */
|
||||
/* --- ADAPTATION MOBILE POUR L'ACCUEIL --- */
|
||||
@media (max-width: 600px) {
|
||||
|
||||
body {
|
||||
/* On permet le scroll si le contenu est plus haut que l'écran */
|
||||
height: auto;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.welcome-container {
|
||||
/* On réduit les bordures massives et le padding */
|
||||
padding: 30px 20px;
|
||||
border-width: 8px; /* Bordure en bois moins épaisse */
|
||||
border-radius: 40px; /* Moins arrondi pour gagner de la place */
|
||||
width: 85%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.6rem; /* Titre plus petit */
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
/* Le bouton principal doit être bien large pour le pouce */
|
||||
.btn-start {
|
||||
width: 100%;
|
||||
box-sizing: border-box; /* Pour que le padding n'agrandisse pas la largeur */
|
||||
padding: 18px 20px;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* Section rejoindre */
|
||||
input[type="text"] {
|
||||
width: 100%; /* L'input prend toute la largeur */
|
||||
box-sizing: border-box;
|
||||
padding: 15px;
|
||||
font-size: 1.1rem; /* Évite le zoom auto de l'iPhone sur les inputs */
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%; /* Les boutons de validation passent en pleine largeur */
|
||||
padding: 15px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* Pour la liste des parties */
|
||||
li {
|
||||
flex-direction: column; /* On empile le nom et le bouton */
|
||||
gap: 10px;
|
||||
background: rgba(0,0,0,0.2);
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.btn-join-list {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Conteneur principal */
|
||||
.mon-accordeon {
|
||||
max-width: 600px;
|
||||
width: 100%;
|
||||
margin: 20px auto;
|
||||
font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background-color: #1a1a1a; /* Noir anthracite */
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.5);
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.container-parent {
|
||||
display: flex;
|
||||
justify-content: space-between; /* Pousse les éléments aux extrémités */
|
||||
align-items: center; /* Aligne verticalement au centre (optionnel) */
|
||||
width: 100%; /* S'assure que le container prend toute la largeur */
|
||||
}
|
||||
|
||||
/* L'élément details */
|
||||
details {
|
||||
border-bottom: 1px solid #333;
|
||||
}
|
||||
|
||||
details:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Le titre (Summary) */
|
||||
summary {
|
||||
padding: 15px 20px;
|
||||
background-color: #1a1a1a;
|
||||
color: #d4af37; /* Doré sobre */
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
list-style: none; /* Cache la flèche par défaut sur certains navigateurs */
|
||||
transition: background 0.3s ease;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Style de survol */
|
||||
summary:hover {
|
||||
background-color: #252525;
|
||||
color: #f0c644;
|
||||
}
|
||||
|
||||
/* Flèche personnalisée à droite */
|
||||
summary::after {
|
||||
content: '♣'; /* Trèfle discret */
|
||||
font-size: 1.2rem;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
/* Rotation du trèfle quand c'est ouvert */
|
||||
details[open] summary::after {
|
||||
transform: rotate(180deg);
|
||||
color: #2e7d32; /* Vert poker au clic */
|
||||
}
|
||||
|
||||
/* Contenu de l'accordéon */
|
||||
.contenu {
|
||||
padding: 15px 20px;
|
||||
background-color: #0d3b2e; /* Vert tapis de table sombre */
|
||||
color: #e0e0e0;
|
||||
line-height: 1.6;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
/* Petit effet de bordure gauche pour marquer l'ouverture */
|
||||
details[open] {
|
||||
border-left: 4px solid #2e7d32;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<title>Configuration Poker</title>
|
||||
<style>
|
||||
.player-row { margin-bottom: 10px; }
|
||||
</style>
|
||||
<link rel="stylesheet" href="../Css/Config.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<button onclick="window.location.href='../index.html'" class="btn-back">⬅ Accueil</button>
|
||||
<h1>Configuration de la partie</h1>
|
||||
|
||||
<form id="create_game_form">
|
||||
<label>Nom de partie :</label>
|
||||
<input type="text" name="game_name" placeholder="Nom de partie" required><br><br>
|
||||
|
||||
<label>Somme de départ :</label>
|
||||
<input type="number" name="start_money" value="1000" required><br><br>
|
||||
|
||||
<label>Blind :</label>
|
||||
<input type="number" name="blind" value="20" required><br><br>
|
||||
|
||||
<label>Joueurs :</label>
|
||||
<label class="info">(Maximum 8 joueurs)</label><br>
|
||||
<div id="players_container">
|
||||
<div class="player-row">
|
||||
<p>1</p><input type="text" name="players[]" placeholder="Nom du joueur" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<button type="button" onclick="addPlayer()">➕ Ajouter un joueur</button>
|
||||
<br>
|
||||
|
||||
<input type="submit" value="Démarrer la partie">
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
<script src="../Js/Config.js"></script>
|
||||
</html>
|
||||
@@ -0,0 +1,55 @@
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||
<title id="title_page"></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel='stylesheet' type='text/css' href='../Css/Game.css' deffer>
|
||||
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.5.1/dist/confetti.browser.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="game-container">
|
||||
<div class="stats-bar">
|
||||
<div class="money-group">
|
||||
<input type="number" id="money-amount" placeholder="Montant">
|
||||
<button class="btn-money" onclick="addMoney()">OK</button>
|
||||
</div>
|
||||
|
||||
<div class="stat-item">MISE ACTUELLE: <strong id="current-bet"></strong></div>
|
||||
<button onclick="deleteGame()" class="btn-spaction">Fermer la table</button>
|
||||
<button onclick="changePlayer()" class="btn-spaction">Joueur suivant</button>
|
||||
<button onclick="endGame()" class="btn-spaction">Terminer la partie</button>
|
||||
<a href="../index.html" class="btn-back">⬅ Quitter</a>
|
||||
</div>
|
||||
|
||||
<div class="table-container">
|
||||
<div class="poker-table" id="table">
|
||||
<div class="pot-area">
|
||||
<div class="total-pot"></div>
|
||||
<div id="Mise" class="current-bet-display">Mise: </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-panel">
|
||||
<p class="turn-info">Au tour de : <strong id="active-player-name"></strong></p>
|
||||
|
||||
<div class="action-buttons">
|
||||
<button class="btn btn-fold" onclick="playerFold()">Se coucher</button>
|
||||
<button class="btn btn-call" onclick="playerFollow()">Suivre</button>
|
||||
<div class="raise-group">
|
||||
<input type="number" id="raise-amount" placeholder="Mise" min="0">
|
||||
<button class="btn-validate" onclick="playerRaise()">OK</button>
|
||||
</div>
|
||||
<button class="btn btn-allin" onclick="playerAllIn()">TAPIS</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="../Js/Game.js"></script>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
|
||||
// Fonction et variables essentiel
|
||||
|
||||
async function SqlRequest(action, params = {}) {
|
||||
try {
|
||||
const response = await fetch('../Php/RequestsHandler.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action: action,
|
||||
params: params
|
||||
})
|
||||
});
|
||||
|
||||
const resultat = await response.json();
|
||||
|
||||
if (resultat.success) {
|
||||
return resultat;
|
||||
} else {
|
||||
console.error("Erreur :", resultat.error);
|
||||
}
|
||||
} catch (erreur) {
|
||||
console.error("Erreur de communication :", erreur);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
|
||||
function addPlayer() {
|
||||
// 1. On récupère le conteneur
|
||||
const container = document.getElementById('players_container');
|
||||
|
||||
// 2. On crée une nouvelle ligne
|
||||
const newRow = document.createElement('div');
|
||||
newRow.className = 'player-row';
|
||||
|
||||
console.log(container.children.length); // Affiche le nombre de joueurs actuels (pour le debug)
|
||||
// 3. On met le HTML dedans (avec le bouton supprimer intégré)
|
||||
newRow.innerHTML = `
|
||||
<p>${container.children.length+1}</p>
|
||||
<input type="text" name="players[]" placeholder="Nom du joueur" required>
|
||||
<button type="button" onclick="removePlayer(this)">🗑️</button>
|
||||
`;
|
||||
|
||||
// 4. On l'ajoute au conteneur
|
||||
container.appendChild(newRow);
|
||||
}
|
||||
|
||||
function removePlayer(btn) {
|
||||
// On supprime le parent du bouton (la div 'player-row')
|
||||
btn.parentElement.remove();
|
||||
}
|
||||
|
||||
function deleteGame(idPartie) {
|
||||
if (confirm("Êtes-vous sûr de vouloir supprimer cette partie ? Tous les joueurs associés seront effacés.")) {
|
||||
|
||||
// On prépare les données à envoyer
|
||||
let formData = new FormData();
|
||||
formData.append('game_id', idPartie);
|
||||
|
||||
fetch('delete_game.php', {
|
||||
method: 'POST',
|
||||
body: formData // On envoie l'ID au PHP
|
||||
})
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
alert(data);
|
||||
// Au lieu de reload, on peut rediriger vers l'accueil
|
||||
window.location.href = 'index.php';
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erreur:', error);
|
||||
alert('Impossible de supprimer la partie.');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const loginForm = document.getElementById('create_game_form');
|
||||
loginForm.addEventListener('submit', async function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const start_money = parseInt(this.querySelector('input[name="start_money"]').value);
|
||||
const blind = parseInt(this.querySelector('input[name="blind"]').value);
|
||||
const name = this.querySelector('input[name="game_name"]').value;
|
||||
const players = this.querySelectorAll('input[name="players[]"]');
|
||||
let response = await SqlRequest('createGame', {name: name, start_money: start_money, blind: blind});
|
||||
console.log(response, response.success, response.game_id, parseInt(response.game_id));
|
||||
|
||||
if (response.success) {
|
||||
const gameId = parseInt(response.game_id);
|
||||
for (const player of players) {
|
||||
await SqlRequest('addPlayer', {game_id: gameId, name: player.value, money: start_money});
|
||||
}
|
||||
const result = await SqlRequest('setFirstPlayer', {game_id: gameId})
|
||||
if (result.success) {
|
||||
window.location.href = '../Html/Game.html?game_id=' + gameId;
|
||||
} else {
|
||||
console.error("Erreur lors de la définition du premier joueur :", result.error);
|
||||
}
|
||||
} else {
|
||||
console.error("Erreur lors de la création de la partie :", response.error);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,301 @@
|
||||
|
||||
|
||||
// Fonction et variables essentiel
|
||||
|
||||
const activePlayerLabel = document.getElementById('active-player-name');
|
||||
let gameData = null;
|
||||
let currentPlayer = null;
|
||||
let playersData = [];
|
||||
|
||||
async function SqlRequest(action, params = {}) {
|
||||
try {
|
||||
const response = await fetch('../Php/RequestsHandler.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action: action,
|
||||
params: params
|
||||
})
|
||||
});
|
||||
|
||||
const resultat = await response.json();
|
||||
|
||||
if (resultat.success) {
|
||||
return resultat;
|
||||
} else {
|
||||
console.error("Erreur :", resultat.error);
|
||||
}
|
||||
} catch (erreur) {
|
||||
console.error("Erreur de communication :", erreur);
|
||||
}
|
||||
}
|
||||
|
||||
// Fonctions pour démarrer la page
|
||||
window.onload = async function() {
|
||||
gameData = await getGame();
|
||||
playersData = await getPlayers();
|
||||
|
||||
document.getElementById('title_page').textContent = "Table de Poker - " + gameData.name;
|
||||
updateClientInterface();
|
||||
}
|
||||
|
||||
async function updateClientInterface() {
|
||||
setupPlayers();
|
||||
getCurrentPlayer();
|
||||
|
||||
activePlayerLabel.textContent = `${currentPlayer.name} (${currentPlayer.money} 🪙)`;
|
||||
}
|
||||
|
||||
async function setupPlayers() {
|
||||
const PokerTable = document.getElementById('table');
|
||||
PokerTable.innerHTML = ''; // Clear existing players
|
||||
let newHtml = ``;
|
||||
|
||||
newHtml += `
|
||||
<div class="pot-area">
|
||||
<div class="total-pot">${gameData.pot}</div>
|
||||
<div id="Mise" class="current-bet-display">Mise: ${gameData.last_bet}</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
playersData.forEach((player, index) => {
|
||||
newHtml += `
|
||||
<div class="player-slot slot-${index}${player.is_folded ? ' blur-effect' : ''}${player.money <= 0 ? ' All-in-Blur' : ''}" onclick="changePlayer(${player.id})" data-id="${player.id}">
|
||||
<div class="player-info${gameData.current_player_id == player.id ? ' active' : ''}">
|
||||
${player.is_dealer ? '<div class="dealer-badge">D</div>' : ''}
|
||||
|
||||
<span class="player-name">J${index + 1} : ${player.name}</span>
|
||||
<span class="player-money">${player.money} 🪙</span><br>
|
||||
<span class="player-bet">Mise: ${player.current_bet} 🪙</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
PokerTable.innerHTML = newHtml;
|
||||
}
|
||||
|
||||
async function getGame(id = null) {
|
||||
let gameId;
|
||||
if (id === null) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
gameId = urlParams.get('game_id');
|
||||
} else {
|
||||
gameId = id;
|
||||
}
|
||||
|
||||
const response = await SqlRequest('getGame', { game_id: gameId });
|
||||
if (response.success) {
|
||||
return response.game;
|
||||
} else {
|
||||
console.error("Erreur lors de la récupération du jeu :", response.error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function getPlayers() {
|
||||
const response = await SqlRequest('getPlayers', { game_id: gameData.id });
|
||||
if (response.success) {
|
||||
return response.players;
|
||||
} else {
|
||||
console.error("Erreur lors de la récupération des joueurs :", response.error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function getCurrentPlayer() {
|
||||
currentPlayer = playersData.find(player => player.id === gameData.current_player_id);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Fonctions pour les actions
|
||||
async function changePlayer(id = null) {
|
||||
if (id === null) {
|
||||
const response = await SqlRequest('next_player', { game_id: gameData.id, current_player_id: gameData.current_player_id });
|
||||
if (response.success) {
|
||||
gameData.current_player_id = response.next_player_id;
|
||||
} else {
|
||||
console.error("Erreur lors du passage au joueur suivant :", response.error);
|
||||
}
|
||||
} else {
|
||||
const response = await SqlRequest('set_current_player', { game_id: gameData.id, player_id: id });
|
||||
if (response.success) {
|
||||
gameData.current_player_id = id;
|
||||
} else {
|
||||
console.error("Erreur lors du changement de joueur :", response.error);
|
||||
}
|
||||
}
|
||||
updateClientInterface();
|
||||
}
|
||||
|
||||
async function playerFold() {
|
||||
const response = await SqlRequest('fold', { player_id: gameData.current_player_id });
|
||||
if (response.success) {
|
||||
playersData = await getPlayers();
|
||||
changePlayer();
|
||||
} else {
|
||||
console.error("Erreur lors du fold :", response.error);
|
||||
}
|
||||
}
|
||||
|
||||
async function playerRaise() {
|
||||
const betAmount = parseInt(document.getElementById('raise-amount').value);
|
||||
|
||||
if (betAmount <= 0) {
|
||||
alert("Veuillez entrer un montant de mise valide.");
|
||||
return;
|
||||
}
|
||||
const amount = betAmount + gameData.last_bet - currentPlayer.current_bet;
|
||||
|
||||
if (currentPlayer.money < amount) {
|
||||
alert("Vous n'avez pas assez d'argent pour cette mise.");
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await SqlRequest('raise', { game_id: gameData.id, player_id: gameData.current_player_id, amount: amount, current_bet: currentPlayer.current_bet });
|
||||
if (response.success) {
|
||||
gameData.last_bet = currentPlayer.current_bet + amount;
|
||||
gameData.pot += amount;
|
||||
playersData = await getPlayers();
|
||||
changePlayer();
|
||||
} else {
|
||||
console.error("Erreur lors du raise :", response.error);
|
||||
}
|
||||
}
|
||||
|
||||
async function playerFollow() {
|
||||
if (currentPlayer.current_bet >= gameData.last_bet) {
|
||||
changePlayer();
|
||||
return;
|
||||
}
|
||||
|
||||
let delta_amount = gameData.last_bet - currentPlayer.current_bet;
|
||||
if (currentPlayer.money < delta_amount) {
|
||||
delta_amount = currentPlayer.money;
|
||||
}
|
||||
|
||||
const response = await SqlRequest('follow', { game_id: gameData.id, player_id: gameData.current_player_id, amount: delta_amount });
|
||||
if (response.success) {
|
||||
gameData.pot += delta_amount;
|
||||
playersData = await getPlayers();
|
||||
changePlayer();
|
||||
} else {
|
||||
console.error("Erreur lors du follow :", response.error);
|
||||
}
|
||||
}
|
||||
|
||||
async function playerAllIn() {
|
||||
const response = await SqlRequest('all_in', { game_id: gameData.id, player_id: gameData.current_player_id });
|
||||
if (response.success) {
|
||||
gameData = await getGame(gameData.id);
|
||||
playersData = await getPlayers();
|
||||
changePlayer();
|
||||
} else {
|
||||
console.error("Erreur lors du all-in :", response.error);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Fonctions pour les actions administratives
|
||||
async function endGame() {
|
||||
const container = document.querySelector('.table-container');
|
||||
|
||||
if (!container) {
|
||||
console.error("Conteneur .table-container introuvable");
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.querySelector('.win-panel')) return;
|
||||
|
||||
const winOverlay = document.createElement('div');
|
||||
winOverlay.className = 'win-overlay';
|
||||
const winPanel = document.createElement('div');
|
||||
winPanel.className = 'win-panel';
|
||||
winPanel.innerHTML = `
|
||||
<h2>🏆 La partie est terminée ! 🏆<br>Qui a gagné ?</h2>
|
||||
<div id="winner-buttons-area"></div>
|
||||
`;
|
||||
|
||||
winOverlay.appendChild(winPanel);
|
||||
container.appendChild(winOverlay);
|
||||
|
||||
const area = document.getElementById('winner-buttons-area');
|
||||
const playerElements = document.querySelectorAll('.player-slot');
|
||||
|
||||
playerElements.forEach(slot => {
|
||||
const id = slot.getAttribute('data-id');
|
||||
const name = slot.querySelector('.player-name').textContent.split(': ')[1];
|
||||
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'btn-win';
|
||||
btn.innerText = name;
|
||||
btn.onclick = () => declareWinner(id);
|
||||
area.appendChild(btn);
|
||||
});
|
||||
|
||||
document.getElementById('end-game-screen').style.display = 'flex';
|
||||
container.classList.add('blur-effect');
|
||||
}
|
||||
|
||||
async function declareWinner(playerId) {
|
||||
const container = document.querySelector('.table-container');
|
||||
container.classList.remove('blur-effect');
|
||||
|
||||
const response = await SqlRequest('declare_winner', { game_id: gameData.id, player_id: playerId });
|
||||
if (response.success) {
|
||||
const winPanel = document.querySelector('.win-panel');
|
||||
if (winPanel) {
|
||||
winPanel.innerHTML = `
|
||||
|
||||
|
||||
<h2>${playersData.find(player => player.id == playerId).name} gagne la partie et remporte ${gameData.last_bet} 🪙 !</h2>
|
||||
<button class="btn-back" onclick="window.location.href='../index.html'">Retour à l'accueil</button>
|
||||
<button class="btn-replay" onclick="StartNewGame()">Rejouer</button>
|
||||
`;
|
||||
}
|
||||
} else {
|
||||
console.error("Erreur lors de la déclaration du gagnant :", response.error);
|
||||
}
|
||||
}
|
||||
|
||||
async function StartNewGame() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
async function addMoney() {
|
||||
let amount = parseInt(document.getElementById('money-amount').value);
|
||||
if (isNaN(amount)) {
|
||||
alert("Veuillez entrer un montant valide.");
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await SqlRequest('add_money', { player_id: gameData.current_player_id, amount: amount });
|
||||
if (response.success) {
|
||||
playersData = await getPlayers();
|
||||
updateClientInterface();
|
||||
} else {
|
||||
console.error("Erreur lors de l'ajout d'argent :", response.error);
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteGame() {
|
||||
const confirmation = confirm("Êtes-vous sûr de vouloir supprimer cette partie ? Cette action est irréversible.");
|
||||
if (!confirmation) return;
|
||||
|
||||
const response = await SqlRequest('delete_game', { game_id: gameData.id });
|
||||
if (response.success) {
|
||||
console.log("Partie supprimée avec succès.", response.success);
|
||||
window.location.replace('../index.html');
|
||||
} else {
|
||||
console.error("Erreur lors de la suppression du jeu :", response.error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
|
||||
|
||||
async function SqlRequest(action, params = {}) {
|
||||
try {
|
||||
const response = await fetch('Php/RequestsHandler.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action: action,
|
||||
params: params
|
||||
})
|
||||
});
|
||||
|
||||
const resultat = await response.json();
|
||||
|
||||
if (resultat.success) {
|
||||
return resultat;
|
||||
} else {
|
||||
console.error("Erreur :", resultat.error);
|
||||
}
|
||||
} catch (erreur) {
|
||||
console.error("Erreur de communication :", erreur);
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = async function() {
|
||||
loadData();
|
||||
};
|
||||
|
||||
async function loadData() {
|
||||
const container = document.getElementById('games_list');
|
||||
const response = await SqlRequest('get_all_games');
|
||||
const games = response.games;
|
||||
|
||||
if (Object.keys(games).length <= 0) {
|
||||
container.innerHTML = "<p>Aucune partie en cours.</p>";
|
||||
return;
|
||||
}
|
||||
|
||||
let futurHtml = "";
|
||||
|
||||
for (const game of games) {
|
||||
// 1. On récupère les joueurs de manière asynchrone AVANT de construire le HTML du jeu
|
||||
const players = await getPlayers(game.id);
|
||||
|
||||
// 2. On prépare le HTML de la liste des joueurs
|
||||
let playersHtml = "";
|
||||
players.forEach(player => {
|
||||
if (player.game_id === game.id) {
|
||||
playersHtml += `<p>${player.name}</p>`;
|
||||
}
|
||||
});
|
||||
|
||||
// 3. On assemble le tout
|
||||
futurHtml += `
|
||||
<li>
|
||||
<details class="mon-accordeon">
|
||||
<summary>${game.name}</summary>
|
||||
<div class='container-parent'>
|
||||
<div class='right'>
|
||||
<p>Start Money: ${game.start_money}</p>
|
||||
<p>Blind: ${game.start_blind}</p>
|
||||
<button class="btn-join-list" onclick="window.location.href='Html/Game.html?game_id=${game.id}'">Rejoindre</button>
|
||||
</div>
|
||||
<div class='left'>
|
||||
${playersHtml}
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</li>
|
||||
`;
|
||||
}
|
||||
|
||||
container.innerHTML = '<ul>' + futurHtml + "</ul>";
|
||||
}
|
||||
|
||||
async function getPlayers(id) {
|
||||
const response = await SqlRequest('getPlayers', {game_id: id});
|
||||
const players = response.players;
|
||||
return players;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$host = 'localhost';
|
||||
$db = 'poker_paf';
|
||||
$user = 'root';
|
||||
$pass = '';
|
||||
|
||||
$options = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
// C'est cette ligne qui fait la différence :
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
PDO::ATTR_STRINGIFY_FETCHES => false,
|
||||
];
|
||||
|
||||
// charger la BDD
|
||||
try {
|
||||
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass, $options);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} catch (Exception $e) {
|
||||
die(json_encode(['error' => 'Connexion échouée']));
|
||||
}
|
||||
|
||||
// lire les données JSON envoyées par le client
|
||||
$json = file_get_contents('php://input');
|
||||
$data = json_decode($json, true);
|
||||
|
||||
if (!$data || !isset($data['action'])) {
|
||||
echo json_encode(['error' => 'Aucune action spécifiée']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$action = $data['action'];
|
||||
$params = $data['params'] ?? [];
|
||||
|
||||
$response = [];
|
||||
|
||||
switch ($action) {
|
||||
case 'getGame':
|
||||
$stmt = $pdo->prepare("SELECT * FROM games WHERE id = ?");
|
||||
$stmt->execute([$params['game_id']]);
|
||||
$game = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($game) {
|
||||
$response = ['success' => true, 'game' => $game];
|
||||
} else {
|
||||
$response = ['error' => 'Partie non trouvée'];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'getPlayers':
|
||||
$stmt = $pdo->prepare("SELECT * FROM players WHERE game_id = ?");
|
||||
$stmt->execute([$params['game_id']]);
|
||||
$players = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$response = ['success' => true, 'players' => $players];
|
||||
break;
|
||||
|
||||
case 'createGame':
|
||||
$stmt = $pdo->prepare("INSERT INTO games (start_money, start_blind, name) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$params['start_money'], $params['blind'], $params['name']]);
|
||||
$game_id = $pdo->lastInsertId();
|
||||
$response = ['success' => true, 'game_id' => $game_id];
|
||||
break;
|
||||
|
||||
case 'addPlayer':
|
||||
$stmt = $pdo->prepare("INSERT INTO players (name, game_id, money) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$params['name'], $params['game_id'], $params['money']]);
|
||||
$player_id = $pdo->lastInsertId();
|
||||
$response = ['success' => true];
|
||||
break;
|
||||
|
||||
case 'setFirstPlayer':
|
||||
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? ORDER BY id ASC LIMIT 1");
|
||||
$stmt->execute([$params['game_id']]);
|
||||
$first_player = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($first_player) {
|
||||
$first_player_id = $first_player['id'];
|
||||
$stmt = $pdo->prepare("UPDATE games SET current_player_id = ? WHERE id = ?");
|
||||
$stmt->execute([$first_player_id, $params['game_id']]);
|
||||
$stmt = $pdo->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?");
|
||||
$stmt->execute([$first_player_id]);
|
||||
$response = ['success' => true];
|
||||
} else {
|
||||
$response = ['error' => 'Aucun joueur trouvé pour cette partie'];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'next_player':
|
||||
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? AND is_folded = 0 AND id > ? AND money <> 0 ORDER BY id ASC LIMIT 1");
|
||||
$stmt->execute([$params['game_id'], $params['current_player_id']]);
|
||||
$next_player = $stmt->fetch();
|
||||
|
||||
if (!$next_player) { // Si on est au dernier, on revient au premier pas couché
|
||||
$stmt = $pdo->prepare("SELECT id FROM players WHERE is_folded = 0 AND game_id = ? ORDER BY id ASC LIMIT 1");
|
||||
$stmt->execute([$params['game_id']]);
|
||||
$next_player = $stmt->fetch();
|
||||
}
|
||||
|
||||
// 3. Mise à jour de la BDD
|
||||
$stmt = $pdo->prepare("UPDATE games SET current_player_id = ? WHERE id = ?");
|
||||
$stmt->execute([$next_player['id'], $params['game_id']]);
|
||||
|
||||
$response = (['success' => true, 'next_player_id' => $next_player['id']]);
|
||||
break;
|
||||
|
||||
case 'set_current_player':
|
||||
$stmt = $pdo->prepare("UPDATE games SET current_player_id = ? WHERE id = ?");
|
||||
$stmt->execute([$params['player_id'], $params['game_id']]);
|
||||
$response = ['success' => true];
|
||||
break;
|
||||
|
||||
case 'fold':
|
||||
$stmt = $pdo->prepare("UPDATE players SET is_folded = 1 WHERE id = ?");
|
||||
$stmt->execute([$params['player_id']]);
|
||||
$response = ['success' => true];
|
||||
break;
|
||||
|
||||
case 'raise':
|
||||
$stmt = $pdo->prepare("UPDATE players SET money = money - ? WHERE id = ?");
|
||||
$stmt->execute([$params['amount'], $params['player_id']]);
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE players SET current_bet = current_bet + ? WHERE id = ?");
|
||||
$stmt->execute([$params['amount'], $params['player_id']]);
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE games SET pot = pot + ? WHERE id = ?");
|
||||
$stmt->execute([$params['amount'], $params['game_id']]);
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE games SET last_bet = ? WHERE id = ?");
|
||||
$stmt->execute([$params['amount'] + $params['current_bet'], $params['game_id']]);
|
||||
|
||||
$response = ['success' => true];
|
||||
break;
|
||||
|
||||
case 'follow':
|
||||
$stmt = $pdo->prepare("UPDATE players SET money = money - ? WHERE id = ?");
|
||||
$stmt->execute([$params['amount'], $params['player_id']]);
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE players SET current_bet = current_bet + ? WHERE id = ?");
|
||||
$stmt->execute([$params['amount'], $params['player_id']]);
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE games SET pot = pot + ? WHERE id = ?");
|
||||
$stmt->execute([$params['amount'], $params['game_id']]);
|
||||
|
||||
$response = ['success' => true];
|
||||
break;
|
||||
|
||||
case 'all_in':
|
||||
$stmt = $pdo->prepare("SELECT money FROM players WHERE id = ?");
|
||||
$stmt->execute([$params['player_id']]);
|
||||
$money = $stmt->fetchColumn();
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE players SET money = 0, current_bet = current_bet + ? WHERE id = ?");
|
||||
$stmt->execute([$money, $params['player_id']]);
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE games SET pot = pot + ?, last_bet = last_bet + ? WHERE id = ?");
|
||||
$stmt->execute([$money, $money, $params['game_id']]);
|
||||
|
||||
$response = ['success' => true];
|
||||
break;
|
||||
|
||||
case 'declare_winner':
|
||||
$stmt = $pdo->prepare("SELECT pot FROM games WHERE id = ?");
|
||||
$stmt->execute([$params['game_id']]);
|
||||
$pot = $stmt->fetchColumn();
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE games SET pot = 0, last_bet = 0 WHERE id = ?");
|
||||
$stmt->execute([$params['game_id']]);
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE players SET money = money + ? WHERE id = ?");
|
||||
$stmt->execute([$pot, $params['player_id']]);
|
||||
|
||||
$stmt = $pdo->prepare("SELECT * FROM players WHERE game_id = ?");
|
||||
$stmt->execute([$params['game_id']]);
|
||||
$players = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
foreach ($players as $player) {
|
||||
$stmt = $pdo->prepare("UPDATE players SET current_bet = 0, is_folded = 0 WHERE id = ?");
|
||||
$stmt->execute([$player['id']]);
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare("SELECT id FROM players WHERE is_dealer = 1 AND game_id = ?");
|
||||
$stmt->execute([$params['game_id']]);
|
||||
$current_dealer = $stmt->fetchColumn();
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE players SET is_dealer = 0 WHERE id = ?");
|
||||
$stmt->execute([$current_dealer]);
|
||||
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? AND id > ? ORDER BY id ASC LIMIT 1");
|
||||
$stmt->execute([$params['game_id'], $current_dealer]);
|
||||
$next_dealer = $stmt->fetchColumn();
|
||||
if (!$next_dealer) {
|
||||
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? ORDER BY id ASC LIMIT 1");
|
||||
$stmt->execute([$params['game_id']]);
|
||||
$next_dealer = $stmt->fetchColumn();
|
||||
}
|
||||
$stmt = $pdo->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?");
|
||||
$stmt->execute([$next_dealer]);
|
||||
|
||||
$response = ['success' => true];
|
||||
break;
|
||||
|
||||
case 'add_money':
|
||||
$stmt = $pdo->prepare("UPDATE players SET money = money + ? WHERE id = ?");
|
||||
$stmt->execute([$params['amount'], $params['player_id']]);
|
||||
$response = ['success' => true];
|
||||
break;
|
||||
|
||||
case 'delete_game':
|
||||
try {
|
||||
// Supprimer les joueurs associés d'abord (intégrité BDD)
|
||||
$stmt = $pdo->prepare("DELETE FROM players WHERE game_id = ?");
|
||||
$stmt->execute([$params['game_id']]);
|
||||
|
||||
// Supprimer la partie
|
||||
$stmt = $pdo->prepare("DELETE FROM games WHERE id = ?");
|
||||
$stmt->execute([$params['game_id']]);
|
||||
|
||||
$response = ['success' => true];
|
||||
} catch (Exception $e) {
|
||||
$response = ['success' => false, 'message' => $e->getMessage()];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'get_all_games':
|
||||
$stmt = $pdo->query("SELECT * FROM games ORDER BY id ASC");
|
||||
$games = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$response = ['success' => true, 'games' => $games];
|
||||
break;
|
||||
|
||||
default:
|
||||
$response = ['error' => 'Action inconnue'];
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||
<title>Poker PAF</title>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||
<link rel='stylesheet' type='text/css' media='screen' href='css/Index.css'>
|
||||
</head>
|
||||
<body>
|
||||
<div class="welcome-container">
|
||||
<h1>Welcome to Poker PAF</h1>
|
||||
<button onclick="window.location.href='Html/Config.html'">Créer une partie</button><br><br>
|
||||
|
||||
<h2>Parties en cours :</h2>
|
||||
<div id="games_list">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="Js/Index.js"></script>
|
||||
</html>
|
||||
@@ -0,0 +1,234 @@
|
||||
/* config.css */
|
||||
:root {
|
||||
--poker-green: #0e5d32;
|
||||
--gold: #d4af37;
|
||||
--wood: #3e2723;
|
||||
--white: #ffffff;
|
||||
--danger: #b71c1c;
|
||||
}
|
||||
|
||||
label.info {
|
||||
font-size: 0.8rem;
|
||||
color: rgb(141, 141, 141);
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #121212;
|
||||
background-image: radial-gradient(circle, #1a1a1a 0%, #000000 100%);
|
||||
color: var(--white);
|
||||
font-family: 'Segoe UI', sans-serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
background-color: var(--poker-green);
|
||||
padding: 30px 50px;
|
||||
border-radius: 60px;
|
||||
border: 12px solid var(--wood);
|
||||
box-shadow: 0 0 50px rgba(0,0,0,0.9), inset 0 0 20px rgba(0,0,0,0.5);
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: var(--gold);
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
font-size: 1.8rem;
|
||||
margin-bottom: 30px;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
color: var(--gold);
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
input[type="number"],
|
||||
input[type="text"] {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
margin-bottom: 20px;
|
||||
border: 2px solid var(--gold);
|
||||
border-radius: 8px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
box-sizing: border-box; /* Pour que le padding ne dépasse pas */
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* Style spécifique pour la ligne joueur */
|
||||
.player-row {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.player-row input {
|
||||
margin-bottom: 0; /* On annule la marge pour l'alignement */
|
||||
}
|
||||
|
||||
/* Boutons */
|
||||
button, input[type="submit"] {
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
transition: all 0.2s;
|
||||
border: none;
|
||||
}
|
||||
|
||||
button[type="button"] {
|
||||
background-color: var(--wood);
|
||||
color: var(--gold);
|
||||
border: 1px solid var(--gold);
|
||||
padding: 10px 15px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
button[type="button"]:hover {
|
||||
background-color: #4e342e;
|
||||
}
|
||||
|
||||
/* Bouton Poubelle */
|
||||
.player-row button {
|
||||
background-color: var(--danger);
|
||||
color: white;
|
||||
border: none;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Bouton Démarrer (le gros bouton doré) */
|
||||
input[type="submit"] {
|
||||
width: 100%;
|
||||
background: linear-gradient(135deg, #d4af37 0%, #f9e27d 50%, #d4af37 100%);
|
||||
color: var(--wood);
|
||||
padding: 15px;
|
||||
font-size: 1.2rem;
|
||||
border-radius: 30px;
|
||||
margin-top: 20px;
|
||||
box-shadow: 0 4px 15px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
input[type="submit"]:hover {
|
||||
transform: scale(1.02);
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
/* Bouton Debug discret en bas */
|
||||
.btn-debug {
|
||||
background: transparent !important;
|
||||
color: rgba(255,255,255,0.3) !important;
|
||||
border: 1px dashed rgba(255,255,255,0.3) !important;
|
||||
width: 100%;
|
||||
margin-top: 30px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.btn-back {
|
||||
position: absolute;
|
||||
top: 25px; /* Ajuste selon tes goûts */
|
||||
left: 35px; /* Aligné avec le bord du cadre */
|
||||
color: var(--gold);
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
font-size: 0.9rem;
|
||||
opacity: 0.7;
|
||||
transition: opacity 0.3s, transform 0.2s;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.btn-back:hover {
|
||||
opacity: 1;
|
||||
transform: translateX(-5px); /* Petit effet de glissement vers la gauche */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* --- Mode Mobile ---*/
|
||||
/* --- ADAPTATION MOBILE POUR LA CONFIGURATION --- */
|
||||
@media (max-width: 600px) {
|
||||
|
||||
body {
|
||||
padding: 10px; /* On réduit la marge extérieure */
|
||||
align-items: flex-start; /* On aligne en haut pour que le scroll soit naturel */
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 20px; /* On réduit le padding interne (30px 50px -> 20px) */
|
||||
border-width: 8px; /* Bordure bois plus fine */
|
||||
border-radius: 30px; /* Moins arrondi pour gagner de la place */
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.4rem;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Le bouton "Retour" */
|
||||
.btn-back {
|
||||
position: relative; /* On le sort de l'absolute pour qu'il ne chevauche pas le titre */
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* 1. Ligne joueur : Le plus important ! */
|
||||
.player-row {
|
||||
flex-direction: column; /* On empile Nom et Poubelle verticalement */
|
||||
align-items: stretch;
|
||||
background: rgba(0,0,0,0.1);
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(212, 175, 55, 0.3);
|
||||
}
|
||||
|
||||
.player-row input {
|
||||
width: 100%; /* Le champ de nom prend toute la largeur */
|
||||
}
|
||||
|
||||
.player-row button {
|
||||
width: 100%; /* Le bouton supprimer devient une large barre rouge */
|
||||
padding: 12px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
/* 2. Inputs plus gros pour le tactile */
|
||||
input[type="number"],
|
||||
input[type="text"] {
|
||||
padding: 15px;
|
||||
font-size: 1.1rem; /* Évite le zoom auto sur iPhone */
|
||||
}
|
||||
|
||||
/* 3. Boutons d'action */
|
||||
button[type="button"] {
|
||||
width: 100%; /* "Ajouter un joueur" prend toute la largeur */
|
||||
padding: 15px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
input[type="submit"] {
|
||||
padding: 18px;
|
||||
font-size: 1.1rem;
|
||||
border-radius: 15px; /* Un peu moins arrondi pour le look mobile */
|
||||
}
|
||||
|
||||
/* Infos de mise (les petits labels gris) */
|
||||
label.info {
|
||||
margin-left: 0;
|
||||
margin-top: -15px;
|
||||
margin-bottom: 15px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user