324 lines
12 KiB
HTML
324 lines
12 KiB
HTML
<!doctype html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
|
<meta name="theme-color" content="#140700" />
|
|
<meta name="application-name" content="ChessCubing Arena" />
|
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
|
<meta name="apple-mobile-web-app-title" content="ChessCubing" />
|
|
<meta
|
|
name="description"
|
|
content="Application officielle de match pour ChessCubing Arena sur téléphone et tablette."
|
|
/>
|
|
<title>ChessCubing Arena | Application</title>
|
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
|
<link rel="shortcut icon" href="/favicon.png" />
|
|
<link rel="apple-touch-icon" href="logo.png" />
|
|
<link rel="manifest" href="site.webmanifest" />
|
|
<script>
|
|
(() => {
|
|
const assetTokenStorageKey = "chesscubing-arena-asset-token";
|
|
const pageUrl = new URL(window.location.href);
|
|
const refreshToken = pageUrl.searchParams.get("refresh");
|
|
if (refreshToken) {
|
|
try {
|
|
window.sessionStorage.setItem(assetTokenStorageKey, refreshToken);
|
|
} catch {
|
|
// Ignore storage failures in restricted browsers.
|
|
}
|
|
pageUrl.searchParams.delete("refresh");
|
|
window.history.replaceState(null, "", pageUrl.toString());
|
|
}
|
|
|
|
let assetToken = "";
|
|
try {
|
|
assetToken = window.sessionStorage.getItem(assetTokenStorageKey) || "";
|
|
} catch {
|
|
assetToken = "";
|
|
}
|
|
|
|
window.__CHESSCUBING_ASSET_TOKEN__ = assetToken;
|
|
window.__CHESSCUBING_ASSET_URL__ = (path) => {
|
|
if (!assetToken) {
|
|
return path;
|
|
}
|
|
|
|
const assetUrl = new URL(path, window.location.href);
|
|
assetUrl.searchParams.set("v", assetToken);
|
|
return `${assetUrl.pathname}${assetUrl.search}${assetUrl.hash}`;
|
|
};
|
|
|
|
const stylesheet = document.createElement("link");
|
|
stylesheet.rel = "stylesheet";
|
|
stylesheet.href = window.__CHESSCUBING_ASSET_URL__("styles.css");
|
|
document.head.append(stylesheet);
|
|
})();
|
|
</script>
|
|
</head>
|
|
<body data-page="setup">
|
|
<div class="ambient ambient-left"></div>
|
|
<div class="ambient ambient-right"></div>
|
|
|
|
<div class="setup-shell">
|
|
<header class="hero hero-setup">
|
|
<div class="hero-copy">
|
|
<a class="logo-lockup" href="index.html" aria-label="Accueil ChessCubing">
|
|
<img class="hero-logo-icon" src="logo.png" alt="Icône ChessCubing" />
|
|
<img class="hero-logo" src="transparent.png" alt="Logo ChessCubing" />
|
|
</a>
|
|
<p class="eyebrow">Application officielle de match</p>
|
|
<h1>ChessCubing Arena</h1>
|
|
<div class="hero-actions">
|
|
<a class="button ghost" href="index.html">Accueil du site</a>
|
|
<a class="button secondary" href="reglement.html">Consulter le règlement</a>
|
|
</div>
|
|
</div>
|
|
|
|
<aside class="hero-preview">
|
|
<div class="preview-card">
|
|
<p class="micro-label">Flux de match</p>
|
|
<ol class="phase-list">
|
|
<li>Configurer la rencontre</li>
|
|
<li>Passer à la page chrono</li>
|
|
<li>Basculer automatiquement sur la page cube</li>
|
|
<li>Revenir sur la page chrono pour le Block suivant</li>
|
|
</ol>
|
|
</div>
|
|
</aside>
|
|
</header>
|
|
|
|
<main class="setup-grid">
|
|
<section class="panel">
|
|
<div class="section-heading">
|
|
<div>
|
|
<p class="eyebrow">Nouvelle rencontre</p>
|
|
<h2>Configuration</h2>
|
|
</div>
|
|
<p class="section-copy">
|
|
Les réglages ci-dessous préparent les pages chrono et cube.
|
|
</p>
|
|
</div>
|
|
|
|
<form id="setupForm" class="setup-form">
|
|
<label class="option-card competition-option span-2">
|
|
<input id="competitionMode" name="competitionMode" type="checkbox" />
|
|
<strong>Mode compétition</strong>
|
|
<span>
|
|
Affiche le nom de la rencontre, l'arbitre, le club ou l'événement
|
|
et les notes d'organisation.
|
|
</span>
|
|
</label>
|
|
|
|
<label class="field span-2" id="matchLabelField" data-competition-field hidden>
|
|
<span>Nom de la rencontre</span>
|
|
<input
|
|
name="matchLabel"
|
|
type="text"
|
|
maxlength="80"
|
|
placeholder="Open ChessCubing de Paris"
|
|
/>
|
|
</label>
|
|
|
|
<fieldset class="field span-2">
|
|
<legend>Mode officiel</legend>
|
|
<div class="option-grid mode-grid">
|
|
<label class="option-card">
|
|
<input type="radio" name="mode" value="twice" checked />
|
|
<strong>ChessCubing Twice</strong>
|
|
<span>
|
|
Le gagnant du cube ouvre la partie suivante et peut obtenir un
|
|
double coup V2.
|
|
</span>
|
|
</label>
|
|
<label class="option-card">
|
|
<input type="radio" name="mode" value="time" />
|
|
<strong>ChessCubing Time</strong>
|
|
<span>
|
|
Même structure de Blocks, avec chronos cumulés et alternance
|
|
bloc - / bloc +.
|
|
</span>
|
|
</label>
|
|
</div>
|
|
</fieldset>
|
|
|
|
<fieldset class="field span-2">
|
|
<legend>Cadence du match</legend>
|
|
<div class="option-grid preset-grid">
|
|
<label class="option-card">
|
|
<input type="radio" name="preset" value="fast" checked />
|
|
<strong>FAST</strong>
|
|
<span>6 coups par joueur</span>
|
|
</label>
|
|
<label class="option-card">
|
|
<input type="radio" name="preset" value="freeze" />
|
|
<strong>FREEZE</strong>
|
|
<span>8 coups par joueur</span>
|
|
</label>
|
|
<label class="option-card">
|
|
<input type="radio" name="preset" value="masters" />
|
|
<strong>MASTERS</strong>
|
|
<span>10 coups par joueur</span>
|
|
</label>
|
|
</div>
|
|
</fieldset>
|
|
|
|
<fieldset class="field span-2">
|
|
<legend>Temps personnalisés</legend>
|
|
<div class="timing-grid">
|
|
<label class="field">
|
|
<span id="blockSecondsLabel">Temps partie (secondes)</span>
|
|
<input
|
|
name="blockSeconds"
|
|
type="number"
|
|
min="30"
|
|
max="1800"
|
|
step="5"
|
|
value="180"
|
|
/>
|
|
</label>
|
|
<label class="field" id="timeInitialField" hidden>
|
|
<span>Temps de chaque joueur (minutes)</span>
|
|
<input
|
|
name="timeInitialMinutes"
|
|
type="number"
|
|
min="1"
|
|
max="180"
|
|
step="1"
|
|
value="10"
|
|
/>
|
|
</label>
|
|
<label class="field" id="moveSecondsField">
|
|
<span>Temps coup (secondes)</span>
|
|
<input
|
|
name="moveSeconds"
|
|
type="number"
|
|
min="5"
|
|
max="300"
|
|
step="1"
|
|
value="20"
|
|
/>
|
|
</label>
|
|
</div>
|
|
</fieldset>
|
|
|
|
<label class="field">
|
|
<span>Joueur blanc</span>
|
|
<input name="whiteName" type="text" maxlength="40" placeholder="Blanc" value="Blanc" />
|
|
</label>
|
|
|
|
<label class="field">
|
|
<span>Joueur noir</span>
|
|
<input name="blackName" type="text" maxlength="40" placeholder="Noir" value="Noir" />
|
|
</label>
|
|
|
|
<label class="field" id="arbiterField" data-competition-field hidden>
|
|
<span>Arbitre</span>
|
|
<input
|
|
name="arbiterName"
|
|
type="text"
|
|
maxlength="40"
|
|
placeholder="Arbitre principal"
|
|
/>
|
|
</label>
|
|
|
|
<label class="field" id="eventField" data-competition-field hidden>
|
|
<span>Club / événement</span>
|
|
<input
|
|
name="eventName"
|
|
type="text"
|
|
maxlength="60"
|
|
placeholder="Club, tournoi, démonstration"
|
|
/>
|
|
</label>
|
|
|
|
<label class="field span-2" id="notesField" data-competition-field hidden>
|
|
<span>Notes</span>
|
|
<textarea
|
|
name="notes"
|
|
rows="3"
|
|
placeholder="Tirage au sort effectué, 8 cubes vérifiés, variante prête..."
|
|
></textarea>
|
|
</label>
|
|
|
|
<div id="setupSummary" class="setup-summary span-2"></div>
|
|
|
|
<div class="setup-actions span-2">
|
|
<button class="button primary" type="submit">
|
|
Ouvrir la page chrono
|
|
</button>
|
|
<button class="button secondary" id="loadDemoButton" type="button">
|
|
Charger une démo
|
|
</button>
|
|
<a class="button ghost" href="reglement.html">Consulter le règlement</a>
|
|
</div>
|
|
</form>
|
|
</section>
|
|
|
|
<aside class="panel side-panel">
|
|
<div class="section-heading">
|
|
<div>
|
|
<p class="eyebrow">Match en mémoire</p>
|
|
<h2>Reprise rapide</h2>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="resumeCard" class="resume-card empty">
|
|
<p>Aucun match en cours pour l'instant.</p>
|
|
</div>
|
|
|
|
<div class="rules-stack">
|
|
<article class="rule-card">
|
|
<span class="micro-label">Page chrono</span>
|
|
<strong>Gros boutons uniquement</strong>
|
|
<p>
|
|
Chaque joueur dispose d'une grande zone tactile pour signaler la
|
|
fin de son coup, puis l'app ouvre automatiquement la phase cube
|
|
quand le Block d'échecs est terminé.
|
|
</p>
|
|
</article>
|
|
<article class="rule-card">
|
|
<span class="micro-label">Page cube</span>
|
|
<strong>Une page dédiée</strong>
|
|
<p>
|
|
Les deux joueurs lancent et arrêtent leur propre chrono cube sur
|
|
un écran séparé, toujours en face-à-face sur mobile.
|
|
</p>
|
|
</article>
|
|
<article class="rule-card">
|
|
<span class="micro-label">Sources</span>
|
|
<strong>Règlements intégrés</strong>
|
|
<p>
|
|
<a href="reglement.html">Page règlement du site</a>
|
|
<br />
|
|
<a href="ChessCubing_Twice_Reglement_Officiel_V2-1.pdf" target="_blank"
|
|
>Règlement ChessCubing Twice</a
|
|
>
|
|
<br />
|
|
<a href="ChessCubing_Time_Reglement_Officiel_V1-1.pdf" target="_blank"
|
|
>Règlement ChessCubing Time</a
|
|
>
|
|
</p>
|
|
</article>
|
|
</div>
|
|
</aside>
|
|
</main>
|
|
|
|
<div class="setup-refresh-footer">
|
|
<button class="refresh-link-button" id="refreshAppButton" type="button">
|
|
Rafraîchir l'app
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const appScript = document.createElement("script");
|
|
appScript.type = "module";
|
|
appScript.src = window.__CHESSCUBING_ASSET_URL__("app.js");
|
|
document.body.append(appScript);
|
|
</script>
|
|
</body>
|
|
</html>
|