Refond l'application en parcours multi-pages
This commit is contained in:
@@ -5,12 +5,14 @@ Application web mobile-first pour téléphone et tablette, pensée comme applica
|
|||||||
## Ce que fait cette première version
|
## Ce que fait cette première version
|
||||||
|
|
||||||
- configure une rencontre `Twice` ou `Time`
|
- configure une rencontre `Twice` ou `Time`
|
||||||
|
- sépare l'application en pages dédiées : configuration, phase chrono, phase cube
|
||||||
- gère les blocks de 180 secondes et le temps par coup de 20 secondes
|
- gère les blocks de 180 secondes et le temps par coup de 20 secondes
|
||||||
- suit les quotas `FAST`, `FREEZE` et `MASTERS`
|
- suit les quotas `FAST`, `FREEZE` et `MASTERS`
|
||||||
- orchestre la phase cube avec désignation du cube, capture des temps et préparation du block suivant
|
- orchestre la phase cube avec désignation du cube, capture des temps et préparation du block suivant
|
||||||
- applique la logique du double coup V2 en `Twice`
|
- applique la logique du double coup V2 en `Twice`
|
||||||
- applique les ajustements `bloc -` et `bloc +` en `Time` avec plafond de 120 s pris en compte
|
- applique les ajustements `bloc -` et `bloc +` en `Time` avec plafond de 120 s pris en compte
|
||||||
- conserve un historique local dans le navigateur
|
- conserve un historique local dans le navigateur
|
||||||
|
- propose une page chrono pensée pour le téléphone avec deux grandes zones tactiles, une par joueur
|
||||||
|
|
||||||
## Hypothèse de produit
|
## Hypothèse de produit
|
||||||
|
|
||||||
@@ -27,7 +29,9 @@ L'application est ensuite disponible sur `http://localhost:8080`.
|
|||||||
|
|
||||||
## Fichiers clés
|
## Fichiers clés
|
||||||
|
|
||||||
- `index.html` : structure de l'interface
|
- `index.html` : page de configuration et reprise de match
|
||||||
|
- `chrono.html` : page dédiée à la phase chrono
|
||||||
|
- `cube.html` : page dédiée à la phase cube
|
||||||
- `styles.css` : design mobile/tablette
|
- `styles.css` : design mobile/tablette
|
||||||
- `app.js` : logique de match et arbitrage
|
- `app.js` : logique de match et arbitrage
|
||||||
- `docker-compose.yml` + `Dockerfile` : exécution locale
|
- `docker-compose.yml` + `Dockerfile` : exécution locale
|
||||||
|
|||||||
143
chrono.html
Normal file
143
chrono.html
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Phase chrono de ChessCubing Arena avec gros boutons face-à-face."
|
||||||
|
/>
|
||||||
|
<title>ChessCubing Arena | Phase Chrono</title>
|
||||||
|
<link rel="stylesheet" href="styles.css" />
|
||||||
|
</head>
|
||||||
|
<body data-page="chrono" class="phase-body">
|
||||||
|
<main class="phase-shell">
|
||||||
|
<header class="phase-header">
|
||||||
|
<a class="brand-link" href="index.html">Configuration</a>
|
||||||
|
<div class="phase-title">
|
||||||
|
<p class="eyebrow">Phase chrono</p>
|
||||||
|
<h1 id="chronoTitle">Block 1</h1>
|
||||||
|
<p id="chronoSubtitle" class="phase-subtitle"></p>
|
||||||
|
</div>
|
||||||
|
<button class="button ghost small utility-button" id="openArbiterButton" type="button">
|
||||||
|
Arbitre
|
||||||
|
</button>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="status-strip">
|
||||||
|
<article class="status-card">
|
||||||
|
<span>Temps block</span>
|
||||||
|
<strong id="blockTimer">03:00</strong>
|
||||||
|
</article>
|
||||||
|
<article class="status-card">
|
||||||
|
<span>Temps coup</span>
|
||||||
|
<strong id="moveTimer">00:20</strong>
|
||||||
|
</article>
|
||||||
|
<article class="status-card wide">
|
||||||
|
<span id="chronoCenterLabel">Trait</span>
|
||||||
|
<strong id="chronoCenterValue">Blanc</strong>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="faceoff-board">
|
||||||
|
<article class="player-zone opponent-zone" id="blackZone">
|
||||||
|
<div class="zone-inner mirrored-mobile">
|
||||||
|
<div class="zone-head">
|
||||||
|
<div>
|
||||||
|
<span class="seat-tag dark-seat">Noir</span>
|
||||||
|
<h2 id="blackNameChrono">Noir</h2>
|
||||||
|
</div>
|
||||||
|
<div class="zone-stats">
|
||||||
|
<strong id="blackMovesChrono">0 / 6</strong>
|
||||||
|
<span id="blackClockChrono"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="zone-button dark-button" id="blackMoveButton" type="button">
|
||||||
|
En attente
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<p class="zone-foot" id="blackHintChrono"></p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="phase-spine">
|
||||||
|
<div class="spine-card">
|
||||||
|
<p class="micro-label" id="spineLabel">État du block</p>
|
||||||
|
<strong id="spineHeadline">Prêt à démarrer</strong>
|
||||||
|
<p id="spineText"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="button primary spine-button" id="primaryChronoButton" type="button">
|
||||||
|
Démarrer le block
|
||||||
|
</button>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="player-zone" id="whiteZone">
|
||||||
|
<div class="zone-inner">
|
||||||
|
<div class="zone-head">
|
||||||
|
<div>
|
||||||
|
<span class="seat-tag light-seat">Blanc</span>
|
||||||
|
<h2 id="whiteNameChrono">Blanc</h2>
|
||||||
|
</div>
|
||||||
|
<div class="zone-stats">
|
||||||
|
<strong id="whiteMovesChrono">0 / 6</strong>
|
||||||
|
<span id="whiteClockChrono"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="zone-button light-button" id="whiteMoveButton" type="button">
|
||||||
|
En attente
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<p class="zone-foot" id="whiteHintChrono"></p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<section class="modal hidden" id="arbiterModal" aria-hidden="true">
|
||||||
|
<div class="modal-backdrop" data-close-modal="true"></div>
|
||||||
|
<div class="modal-card">
|
||||||
|
<div class="modal-head">
|
||||||
|
<div>
|
||||||
|
<p class="eyebrow">Outils arbitre</p>
|
||||||
|
<h2>Contrôles avancés</h2>
|
||||||
|
</div>
|
||||||
|
<button class="button ghost small" id="closeArbiterButton" type="button">Fermer</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="section-copy" id="arbiterStatus"></p>
|
||||||
|
|
||||||
|
<div class="modal-actions">
|
||||||
|
<button class="button secondary" id="arbiterPauseButton" type="button">
|
||||||
|
Pause / reprise
|
||||||
|
</button>
|
||||||
|
<button class="button secondary" id="arbiterCloseBlockButton" type="button">
|
||||||
|
Clore le block
|
||||||
|
</button>
|
||||||
|
<button class="button secondary" id="arbiterTimeoutButton" type="button">
|
||||||
|
Dépassement 20 s
|
||||||
|
</button>
|
||||||
|
<button class="button secondary" id="arbiterSwitchTurnButton" type="button">
|
||||||
|
Corriger le trait
|
||||||
|
</button>
|
||||||
|
<button class="button ghost" id="arbiterWhiteWinButton" type="button">
|
||||||
|
Blanc gagne
|
||||||
|
</button>
|
||||||
|
<button class="button ghost" id="arbiterBlackWinButton" type="button">
|
||||||
|
Noir gagne
|
||||||
|
</button>
|
||||||
|
<button class="button ghost danger" id="arbiterStopButton" type="button">
|
||||||
|
Abandon / arrêt
|
||||||
|
</button>
|
||||||
|
<button class="button ghost" id="arbiterResetButton" type="button">
|
||||||
|
Réinitialiser le match
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<script type="module" src="app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
127
cube.html
Normal file
127
cube.html
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Phase cube de ChessCubing Arena avec gros boutons de fin."
|
||||||
|
/>
|
||||||
|
<title>ChessCubing Arena | Phase Cube</title>
|
||||||
|
<link rel="stylesheet" href="styles.css" />
|
||||||
|
</head>
|
||||||
|
<body data-page="cube" class="phase-body">
|
||||||
|
<main class="phase-shell cube-shell">
|
||||||
|
<header class="phase-header">
|
||||||
|
<a class="brand-link" href="index.html">Configuration</a>
|
||||||
|
<div class="phase-title">
|
||||||
|
<p class="eyebrow">Phase cube</p>
|
||||||
|
<h1 id="cubeTitle">Cube n°1</h1>
|
||||||
|
<p id="cubeSubtitle" class="phase-subtitle"></p>
|
||||||
|
</div>
|
||||||
|
<button class="button ghost small utility-button" id="openCubeHelpButton" type="button">
|
||||||
|
Arbitre
|
||||||
|
</button>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="status-strip">
|
||||||
|
<article class="status-card">
|
||||||
|
<span>Block</span>
|
||||||
|
<strong id="cubeBlockLabel">1</strong>
|
||||||
|
</article>
|
||||||
|
<article class="status-card">
|
||||||
|
<span>Chrono cube</span>
|
||||||
|
<strong id="cubeElapsed">00:00.0</strong>
|
||||||
|
</article>
|
||||||
|
<article class="status-card wide">
|
||||||
|
<span id="cubeCenterLabel">État</span>
|
||||||
|
<strong id="cubeCenterValue">Prêt</strong>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="faceoff-board">
|
||||||
|
<article class="player-zone opponent-zone" id="blackCubeZone">
|
||||||
|
<div class="zone-inner mirrored-mobile">
|
||||||
|
<div class="zone-head">
|
||||||
|
<div>
|
||||||
|
<span class="seat-tag dark-seat">Noir</span>
|
||||||
|
<h2 id="blackNameCube">Noir</h2>
|
||||||
|
</div>
|
||||||
|
<div class="zone-stats">
|
||||||
|
<strong id="blackCubeResult">--</strong>
|
||||||
|
<span id="blackCubeCap"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="zone-button dark-button" id="blackCubeButton" type="button">
|
||||||
|
Prêt
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<p class="zone-foot" id="blackHintCube"></p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="phase-spine">
|
||||||
|
<div class="spine-card">
|
||||||
|
<p class="micro-label" id="cubeSpineLabel">Blocage</p>
|
||||||
|
<strong id="cubeSpineHeadline">Lancer la phase cube</strong>
|
||||||
|
<p id="cubeSpineText"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="button primary spine-button" id="primaryCubeButton" type="button">
|
||||||
|
Démarrer la phase cube
|
||||||
|
</button>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="player-zone" id="whiteCubeZone">
|
||||||
|
<div class="zone-inner">
|
||||||
|
<div class="zone-head">
|
||||||
|
<div>
|
||||||
|
<span class="seat-tag light-seat">Blanc</span>
|
||||||
|
<h2 id="whiteNameCube">Blanc</h2>
|
||||||
|
</div>
|
||||||
|
<div class="zone-stats">
|
||||||
|
<strong id="whiteCubeResult">--</strong>
|
||||||
|
<span id="whiteCubeCap"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="zone-button light-button" id="whiteCubeButton" type="button">
|
||||||
|
Prêt
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<p class="zone-foot" id="whiteHintCube"></p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<section class="modal hidden" id="cubeHelpModal" aria-hidden="true">
|
||||||
|
<div class="modal-backdrop" data-close-cube-modal="true"></div>
|
||||||
|
<div class="modal-card">
|
||||||
|
<div class="modal-head">
|
||||||
|
<div>
|
||||||
|
<p class="eyebrow">Outils arbitre</p>
|
||||||
|
<h2>Phase cube</h2>
|
||||||
|
</div>
|
||||||
|
<button class="button ghost small" id="closeCubeHelpButton" type="button">
|
||||||
|
Fermer
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="section-copy" id="cubeHelpStatus"></p>
|
||||||
|
|
||||||
|
<div class="modal-actions">
|
||||||
|
<button class="button secondary" id="replayCubeButton" type="button">
|
||||||
|
Rejouer la phase cube
|
||||||
|
</button>
|
||||||
|
<button class="button ghost danger" id="cubeResetButton" type="button">
|
||||||
|
Réinitialiser le match
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<script type="module" src="app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
332
index.html
332
index.html
@@ -5,72 +5,62 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Application officielle de suivi de match pour ChessCubing Twice et ChessCubing Time."
|
content="Configuration de match pour ChessCubing Arena sur téléphone et tablette."
|
||||||
/>
|
/>
|
||||||
<title>ChessCubing Arena</title>
|
<title>ChessCubing Arena | Configuration</title>
|
||||||
<link rel="stylesheet" href="styles.css" />
|
<link rel="stylesheet" href="styles.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body data-page="setup">
|
||||||
<div class="ambient ambient-left"></div>
|
<div class="ambient ambient-left"></div>
|
||||||
<div class="ambient ambient-right"></div>
|
<div class="ambient ambient-right"></div>
|
||||||
<div class="layout">
|
|
||||||
<header class="hero">
|
<div class="setup-shell">
|
||||||
|
<header class="hero hero-setup">
|
||||||
<div class="hero-copy">
|
<div class="hero-copy">
|
||||||
<p class="eyebrow">Application officielle de match</p>
|
<p class="eyebrow">Application officielle de match</p>
|
||||||
<h1>ChessCubing Arena</h1>
|
<h1>ChessCubing Arena</h1>
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
Une web app pensée pour l'arbitrage sur téléphone et tablette,
|
Une version mobile et tablette organisée par phases : configuration,
|
||||||
directement dérivée des règlements de
|
page chrono ultra lisible, puis page cube dédiée.
|
||||||
<strong>ChessCubing Twice</strong> et
|
|
||||||
<strong>ChessCubing Time</strong>.
|
|
||||||
</p>
|
</p>
|
||||||
<div class="hero-actions">
|
|
||||||
<button class="button primary" data-scroll-target="setupPanel">
|
|
||||||
Configurer une rencontre
|
|
||||||
</button>
|
|
||||||
<button class="button secondary" data-scroll-target="rulesPanel">
|
|
||||||
Voir la synthèse du règlement
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="hero-pills">
|
<div class="hero-pills">
|
||||||
<span>Mobile-first</span>
|
<span>Pages séparées</span>
|
||||||
|
<span>Face-à-face téléphone</span>
|
||||||
<span>Twice + Time</span>
|
<span>Twice + Time</span>
|
||||||
<span>Arbitrage en direct</span>
|
<span>Arbitrage tactile</span>
|
||||||
<span>Fonctionne hors build</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<aside class="hero-preview">
|
<aside class="hero-preview">
|
||||||
<div class="preview-card">
|
<div class="preview-card">
|
||||||
<p class="preview-label">Ce que l'application gère</p>
|
<p class="micro-label">Flux de match</p>
|
||||||
<ul class="preview-list">
|
<ol class="phase-list">
|
||||||
<li>Blocks de 180 s et quotas FAST / FREEZE / MASTERS</li>
|
<li>Configurer la rencontre</li>
|
||||||
<li>Temps par coup de 20 s</li>
|
<li>Passer à la page chrono</li>
|
||||||
<li>Phase cube, égalité, gagnant et block suivant</li>
|
<li>Basculer automatiquement sur la page cube</li>
|
||||||
<li>Mode Time avec chronos cumulés et blocs - / +</li>
|
<li>Revenir sur la page chrono pour le block suivant</li>
|
||||||
</ul>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
<div class="preview-banner">
|
<div class="preview-banner">
|
||||||
<span class="mini-chip">Block 1</span>
|
<span class="mini-chip">Téléphone</span>
|
||||||
<strong id="heroModeHint">Twice ou Time, selon la configuration</strong>
|
<strong>Un joueur en haut, un joueur en bas</strong>
|
||||||
<p>
|
<p>
|
||||||
L'app sert de chef d'orchestre pendant la partie sans imposer un
|
La zone du haut s'inverse automatiquement pour que les deux
|
||||||
échiquier numérique.
|
joueurs se fassent face autour de l'appareil.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="workspace">
|
<main class="setup-grid">
|
||||||
<section class="panel" id="setupPanel">
|
<section class="panel">
|
||||||
<div class="section-heading">
|
<div class="section-heading">
|
||||||
<div>
|
<div>
|
||||||
<p class="eyebrow">Préparer la rencontre</p>
|
<p class="eyebrow">Nouvelle rencontre</p>
|
||||||
<h2>Configuration de match</h2>
|
<h2>Configuration</h2>
|
||||||
</div>
|
</div>
|
||||||
<p class="section-copy">
|
<p class="section-copy">
|
||||||
Lancement rapide pour club, démo ou tournoi. Les choix pilotent le
|
Les réglages ci-dessous préparent les pages chrono et cube.
|
||||||
tableau d'arbitrage en direct.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -92,16 +82,16 @@
|
|||||||
<input type="radio" name="mode" value="twice" checked />
|
<input type="radio" name="mode" value="twice" checked />
|
||||||
<strong>ChessCubing Twice</strong>
|
<strong>ChessCubing Twice</strong>
|
||||||
<span>
|
<span>
|
||||||
Le gagnant du cube commence le block suivant et peut obtenir
|
Le gagnant du cube ouvre le block suivant et peut obtenir un
|
||||||
un double coup selon la règle V2.
|
double coup V2.
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="option-card">
|
<label class="option-card">
|
||||||
<input type="radio" name="mode" value="time" />
|
<input type="radio" name="mode" value="time" />
|
||||||
<strong>ChessCubing Time</strong>
|
<strong>ChessCubing Time</strong>
|
||||||
<span>
|
<span>
|
||||||
Même structure de blocks, avec deux chronos cumulés et un
|
Même structure de blocks, avec chronos cumulés et alternance
|
||||||
impact cube en bloc - / +.
|
bloc - / bloc +.
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -113,41 +103,29 @@
|
|||||||
<label class="option-card">
|
<label class="option-card">
|
||||||
<input type="radio" name="preset" value="fast" checked />
|
<input type="radio" name="preset" value="fast" checked />
|
||||||
<strong>FAST</strong>
|
<strong>FAST</strong>
|
||||||
<span>6 coups par joueur et par block</span>
|
<span>6 coups par joueur</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="option-card">
|
<label class="option-card">
|
||||||
<input type="radio" name="preset" value="freeze" />
|
<input type="radio" name="preset" value="freeze" />
|
||||||
<strong>FREEZE</strong>
|
<strong>FREEZE</strong>
|
||||||
<span>8 coups par joueur et par block</span>
|
<span>8 coups par joueur</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="option-card">
|
<label class="option-card">
|
||||||
<input type="radio" name="preset" value="masters" />
|
<input type="radio" name="preset" value="masters" />
|
||||||
<strong>MASTERS</strong>
|
<strong>MASTERS</strong>
|
||||||
<span>10 coups par joueur et par block</span>
|
<span>10 coups par joueur</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<label class="field">
|
<label class="field">
|
||||||
<span>Joueur blanc</span>
|
<span>Joueur blanc</span>
|
||||||
<input
|
<input name="whiteName" type="text" maxlength="40" placeholder="Blanc" required />
|
||||||
name="whiteName"
|
|
||||||
type="text"
|
|
||||||
maxlength="40"
|
|
||||||
placeholder="Blanc"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="field">
|
<label class="field">
|
||||||
<span>Joueur noir</span>
|
<span>Joueur noir</span>
|
||||||
<input
|
<input name="blackName" type="text" maxlength="40" placeholder="Noir" required />
|
||||||
name="blackName"
|
|
||||||
type="text"
|
|
||||||
maxlength="40"
|
|
||||||
placeholder="Noir"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="field">
|
<label class="field">
|
||||||
@@ -166,243 +144,77 @@
|
|||||||
name="eventName"
|
name="eventName"
|
||||||
type="text"
|
type="text"
|
||||||
maxlength="60"
|
maxlength="60"
|
||||||
placeholder="Club local, tournoi, démonstration"
|
placeholder="Club, tournoi, démonstration"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="field span-2">
|
<label class="field span-2">
|
||||||
<span>Notes de mise en place</span>
|
<span>Notes</span>
|
||||||
<textarea
|
<textarea
|
||||||
name="notes"
|
name="notes"
|
||||||
rows="3"
|
rows="3"
|
||||||
placeholder="Tirage au sort effectué, app lancée, cubes vérifiés..."
|
placeholder="Tirage au sort effectué, 8 cubes vérifiés, variante prête..."
|
||||||
></textarea>
|
></textarea>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="setup-summary span-2" id="setupSummary"></div>
|
<div id="setupSummary" class="setup-summary span-2"></div>
|
||||||
|
|
||||||
<div class="setup-actions span-2">
|
<div class="setup-actions span-2">
|
||||||
<button class="button primary" type="submit">
|
<button class="button primary" type="submit">
|
||||||
Lancer le match
|
Ouvrir la page chrono
|
||||||
</button>
|
</button>
|
||||||
<button class="button ghost" type="button" id="loadDemoButton">
|
<button class="button secondary" id="loadDemoButton" type="button">
|
||||||
Charger une démo
|
Charger une démo
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="panel live-panel hidden" id="livePanel">
|
<aside class="panel side-panel">
|
||||||
<div class="section-heading">
|
<div class="section-heading">
|
||||||
<div>
|
<div>
|
||||||
<p class="eyebrow">Direction de match</p>
|
<p class="eyebrow">Match en mémoire</p>
|
||||||
<h2 id="matchTitle">Rencontre en direct</h2>
|
<h2>Reprise rapide</h2>
|
||||||
</div>
|
|
||||||
<div class="status-badge" id="phaseBadge">Prêt</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="live-grid">
|
|
||||||
<article class="panel inset score-panel">
|
|
||||||
<div class="score-head">
|
|
||||||
<div>
|
|
||||||
<p class="micro-label" id="blockLabel">Block 1</p>
|
|
||||||
<h3 id="modeLabel">ChessCubing Twice</h3>
|
|
||||||
<p class="section-copy" id="blockMeta">
|
|
||||||
Les Blancs commencent le block 1.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<button class="button ghost small" id="resetMatchButton">
|
|
||||||
Réinitialiser
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="timer-grid">
|
|
||||||
<div class="timer-card emphasized">
|
|
||||||
<span>Chrono du block</span>
|
|
||||||
<strong id="blockTimer">03:00</strong>
|
|
||||||
<p id="blockStatusText">En attente du démarrage.</p>
|
|
||||||
</div>
|
|
||||||
<div class="timer-card">
|
|
||||||
<span>Temps par coup</span>
|
|
||||||
<strong id="moveTimer">00:20</strong>
|
|
||||||
<p id="turnLabel">Trait : Blanc</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="player-grid">
|
<div id="resumeCard" class="resume-card empty">
|
||||||
<section class="player-card white-seat" id="whiteCard">
|
<p>Aucun match en cours pour l'instant.</p>
|
||||||
<div class="player-name-row">
|
|
||||||
<span class="player-color">Blanc</span>
|
|
||||||
<strong id="whiteNameDisplay">Blanc</strong>
|
|
||||||
</div>
|
|
||||||
<p id="whiteMoveCount">0 / 6 coups</p>
|
|
||||||
<p id="whiteClockLabel" class="muted"></p>
|
|
||||||
<p id="whiteCubeLabel" class="muted"></p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="player-card black-seat" id="blackCard">
|
|
||||||
<div class="player-name-row">
|
|
||||||
<span class="player-color">Noir</span>
|
|
||||||
<strong id="blackNameDisplay">Noir</strong>
|
|
||||||
</div>
|
|
||||||
<p id="blackMoveCount">0 / 6 coups</p>
|
|
||||||
<p id="blackClockLabel" class="muted"></p>
|
|
||||||
<p id="blackCubeLabel" class="muted"></p>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="panel inset">
|
|
||||||
<h3>Commandes d'arbitrage</h3>
|
|
||||||
<div class="action-grid">
|
|
||||||
<button class="button primary" id="startPauseButton">
|
|
||||||
Démarrer le block
|
|
||||||
</button>
|
|
||||||
<button class="button secondary" id="confirmBlockButton">
|
|
||||||
Clore le block
|
|
||||||
</button>
|
|
||||||
<button class="button secondary" id="moveActionButton">
|
|
||||||
Coup compté
|
|
||||||
</button>
|
|
||||||
<button class="button secondary" id="reliefMoveButton">
|
|
||||||
Coup hors quota
|
|
||||||
</button>
|
|
||||||
<button class="button secondary" id="timeoutMoveButton">
|
|
||||||
Dépassement 20 s
|
|
||||||
</button>
|
|
||||||
<button class="button ghost" id="switchTurnButton">
|
|
||||||
Corriger le trait
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="notice-card" id="contextNotice"></div>
|
<div class="rules-stack">
|
||||||
<div class="double-card" id="doubleCard"></div>
|
<article class="rule-card">
|
||||||
|
<span class="micro-label">Page chrono</span>
|
||||||
<div class="result-grid">
|
<strong>Gros boutons uniquement</strong>
|
||||||
<button class="button ghost" id="whiteWinButton">
|
|
||||||
Blanc gagne
|
|
||||||
</button>
|
|
||||||
<button class="button ghost" id="blackWinButton">
|
|
||||||
Noir gagne
|
|
||||||
</button>
|
|
||||||
<button class="button ghost danger" id="drawStopButton">
|
|
||||||
Abandon / arrêt
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="panel inset">
|
|
||||||
<h3>Phase cube</h3>
|
|
||||||
<div class="cube-head">
|
|
||||||
<div>
|
|
||||||
<span class="micro-label">Cube désigné</span>
|
|
||||||
<strong id="cubeNumber">-</strong>
|
|
||||||
</div>
|
|
||||||
<button class="button secondary" id="startCubeButton">
|
|
||||||
Démarrer la phase cube
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="cube-clock">
|
|
||||||
<strong id="cubeElapsed">00:00.0</strong>
|
|
||||||
<p id="cubeStatusText">
|
|
||||||
La phase cube se déclenche à la fin du block.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="capture-grid">
|
|
||||||
<button class="button capture" id="captureWhiteCubeButton">
|
|
||||||
Arrêt Blanc
|
|
||||||
</button>
|
|
||||||
<button class="button capture" id="captureBlackCubeButton">
|
|
||||||
Arrêt Noir
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="cube-results">
|
|
||||||
<div>
|
|
||||||
<span>Blanc</span>
|
|
||||||
<strong id="whiteCubeResult">--</strong>
|
|
||||||
<small id="whiteCubeCap"></small>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<span>Noir</span>
|
|
||||||
<strong id="blackCubeResult">--</strong>
|
|
||||||
<small id="blackCubeCap"></small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="action-grid compact">
|
|
||||||
<button class="button primary" id="applyCubeButton">
|
|
||||||
Appliquer et préparer le block suivant
|
|
||||||
</button>
|
|
||||||
<button class="button ghost" id="redoCubeButton">
|
|
||||||
Rejouer la phase cube
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="panel inset">
|
|
||||||
<h3>Historique</h3>
|
|
||||||
<ul class="history-list" id="historyList"></ul>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="panel inset" id="rulesPanel">
|
|
||||||
<h3>Synthèse règlementaire</h3>
|
|
||||||
<div class="rules-grid">
|
|
||||||
<div class="rule-card">
|
|
||||||
<span class="micro-label">Twice</span>
|
|
||||||
<strong>Blocks et cube</strong>
|
|
||||||
<p>
|
<p>
|
||||||
Block de 180 s, 20 s max par coup, phase cube obligatoire
|
Chaque joueur dispose d'une grande zone tactile pour signaler la
|
||||||
entre chaque block, gagnant du cube au départ suivant.
|
fin de son coup, avec le haut de l'écran inversé sur téléphone.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
|
||||||
<div class="rule-card">
|
|
||||||
<span class="micro-label">Twice</span>
|
|
||||||
<strong>Double coup V2</strong>
|
|
||||||
<p>
|
|
||||||
Accordé si le gagnant du cube n'a pas joué le dernier coup
|
|
||||||
du block précédent. Premier coup gratuit sans échec,
|
|
||||||
deuxième coup compté.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="rule-card">
|
|
||||||
<span class="micro-label">Time</span>
|
|
||||||
<strong>Impact cube</strong>
|
|
||||||
<p>
|
|
||||||
Block impair : le temps cube est retiré de son propre
|
|
||||||
chrono. Block pair : il est ajouté au chrono adverse, avec
|
|
||||||
plafond de 120 s pris en compte.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="rule-card">
|
|
||||||
<span class="micro-label">Arbitrage</span>
|
|
||||||
<strong>Vérifications clés</strong>
|
|
||||||
<p>
|
|
||||||
Huit cubes, caches numérotés, mélanges identiques,
|
|
||||||
application lancée, variante choisie, tirage au sort fait,
|
|
||||||
aucun coup pendant la phase cube.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</article>
|
</article>
|
||||||
</div>
|
<article class="rule-card">
|
||||||
</section>
|
<span class="micro-label">Page cube</span>
|
||||||
</main>
|
<strong>Une page dédiée</strong>
|
||||||
|
<p>
|
||||||
<footer class="footer">
|
Le cube désigné, le chrono commun et les arrêts Blanc / Noir
|
||||||
|
sont isolés sur leur propre écran.
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
<article class="rule-card">
|
||||||
|
<span class="micro-label">Sources</span>
|
||||||
|
<strong>Règlements intégrés</strong>
|
||||||
<p>
|
<p>
|
||||||
Sources intégrées :
|
|
||||||
<a href="ChessCubing_Twice_Reglement_Officiel_V2-1.pdf" target="_blank"
|
<a href="ChessCubing_Twice_Reglement_Officiel_V2-1.pdf" target="_blank"
|
||||||
>règlement ChessCubing Twice</a
|
>Règlement ChessCubing Twice</a
|
||||||
>
|
>
|
||||||
et
|
<br />
|
||||||
<a href="ChessCubing_Time_Reglement_Officiel_V1-1.pdf" target="_blank"
|
<a href="ChessCubing_Time_Reglement_Officiel_V1-1.pdf" target="_blank"
|
||||||
>règlement ChessCubing Time</a
|
>Règlement ChessCubing Time</a
|
||||||
>.
|
>
|
||||||
</p>
|
</p>
|
||||||
</footer>
|
</article>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="module" src="app.js"></script>
|
<script type="module" src="app.js"></script>
|
||||||
|
|||||||
913
styles.css
913
styles.css
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user