Le domaine donne le dernier coup demi-coup par demi-coup (plateaux intermédiaires du moteur, pions frappés lus sur la barre) ; l'interface fait glisser les pions puis laisse flèches, pions entourés et fantômes jusqu'à l'action suivante. Scénario « Voir le coup de l'ordinateur », tests unitaires et test dans le navigateur. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
345 lines
6.4 KiB
CSS
345 lines
6.4 KiB
CSS
/* Style de l'application. Palette provisoire et sobre (bois, ivoire, un
|
|
* accent vert), en attendant l'identité définitive : toutes les couleurs et
|
|
* tailles sont des variables, redéfinies pour le thème sombre. */
|
|
|
|
:root {
|
|
--text: #2b211a;
|
|
--muted: #6b5d50;
|
|
--background: #f7f2e8;
|
|
--accent: #2e6b4f;
|
|
--on-accent: #ffffff;
|
|
--border: #cbbfae;
|
|
--error: #a3261b;
|
|
|
|
--frame: #6b4426;
|
|
--bed: #e6cfa6;
|
|
--bar: #5c3a20;
|
|
--tray: #57371e;
|
|
--point-a: #9a6439;
|
|
--point-b: #c79b69;
|
|
--point-number: #f3e7d0;
|
|
--checker-player: #fbf6ea;
|
|
--checker-player-edge: #7d6a52;
|
|
--checker-computer: #2b221c;
|
|
--checker-computer-edge: #0d0a08;
|
|
--count-player: #2b211a;
|
|
--count-computer: #fbf6ea;
|
|
--die-player: #fbf6ea;
|
|
--pip-player: #2b211a;
|
|
--die-computer: #2b221c;
|
|
--pip-computer: #fbf6ea;
|
|
--cube: #fbf6ea;
|
|
--cube-text: #2b211a;
|
|
--highlight: #2e6b4f;
|
|
--target: rgba(46, 107, 79, 0.35);
|
|
--last-move: #d9822b;
|
|
|
|
--font-size: 17px;
|
|
--button-height: 48px;
|
|
--radius: 8px;
|
|
--page-width: 40rem;
|
|
}
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
:root {
|
|
--text: #ece4d6;
|
|
--muted: #b3a796;
|
|
--background: #1b1714;
|
|
--accent: #6fc3a0;
|
|
--on-accent: #10221a;
|
|
--border: #4d443b;
|
|
--error: #f08a7e;
|
|
|
|
--frame: #3a2616;
|
|
--bed: #6d5136;
|
|
--bar: #2f1f12;
|
|
--tray: #2c1d11;
|
|
--point-a: #4a3120;
|
|
--point-b: #8b6943;
|
|
--point-number: #d9cbb4;
|
|
--checker-player: #efe6d2;
|
|
--checker-player-edge: #8e7c64;
|
|
--checker-computer: #17110d;
|
|
--checker-computer-edge: #a8957d;
|
|
--highlight: #7fd6b0;
|
|
--target: rgba(127, 214, 176, 0.35);
|
|
--last-move: #f0a050;
|
|
}
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
margin: 0 auto;
|
|
max-width: var(--page-width);
|
|
padding: 0 0.5rem 1rem;
|
|
font: var(--font-size) / 1.45 system-ui, sans-serif;
|
|
color: var(--text);
|
|
background: var(--background);
|
|
}
|
|
|
|
[hidden] {
|
|
display: none !important;
|
|
}
|
|
|
|
.topbar {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
align-items: center;
|
|
padding: 0.5rem 0;
|
|
}
|
|
|
|
.topbar h1 {
|
|
flex: 1;
|
|
margin: 0;
|
|
font-size: 1.25rem;
|
|
}
|
|
|
|
button {
|
|
min-height: var(--button-height);
|
|
padding: 0 1rem;
|
|
font: inherit;
|
|
font-weight: 600;
|
|
color: var(--on-accent);
|
|
background: var(--accent);
|
|
border: 1px solid var(--accent);
|
|
border-radius: var(--radius);
|
|
}
|
|
|
|
button.secondary {
|
|
color: var(--text);
|
|
background: transparent;
|
|
border-color: var(--border);
|
|
}
|
|
|
|
.topbar button {
|
|
min-height: 40px;
|
|
padding: 0 0.75rem;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
button:disabled {
|
|
opacity: 0.45;
|
|
}
|
|
|
|
.actions {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.actions button {
|
|
flex: 1;
|
|
}
|
|
|
|
.pips {
|
|
margin: 0.25rem 0 0;
|
|
font-size: 0.85rem;
|
|
color: var(--muted);
|
|
text-align: center;
|
|
}
|
|
|
|
.info,
|
|
.prompt {
|
|
min-height: 1.45em;
|
|
margin: 0.4rem 0;
|
|
}
|
|
|
|
.info {
|
|
color: var(--muted);
|
|
}
|
|
|
|
.prompt {
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* L'ordinateur réfléchit : trois points qui apparaissent l'un après l'autre. */
|
|
.prompt.thinking::after {
|
|
content: "";
|
|
animation: thinking 1.2s steps(4, end) infinite;
|
|
}
|
|
|
|
@keyframes thinking {
|
|
0% { content: ""; }
|
|
25% { content: "."; }
|
|
50% { content: ".."; }
|
|
75% { content: "..."; }
|
|
}
|
|
|
|
/* ------------------------------------------------------------ Plateau */
|
|
|
|
.board {
|
|
display: block;
|
|
width: 100%;
|
|
height: auto;
|
|
aspect-ratio: 640 / 520;
|
|
user-select: none;
|
|
-webkit-tap-highlight-color: transparent;
|
|
}
|
|
|
|
.board-frame { fill: var(--frame); }
|
|
.board-bed { fill: var(--bed); }
|
|
.board-bar { fill: var(--bar); }
|
|
.board-tray { fill: var(--tray); }
|
|
.point-a { fill: var(--point-a); }
|
|
.point-b { fill: var(--point-b); }
|
|
|
|
.point-number {
|
|
fill: var(--muted);
|
|
font-size: 13px;
|
|
text-anchor: middle;
|
|
}
|
|
|
|
.checker {
|
|
stroke-width: 2;
|
|
}
|
|
|
|
.checker-player {
|
|
fill: var(--checker-player);
|
|
stroke: var(--checker-player-edge);
|
|
}
|
|
|
|
.checker-computer {
|
|
fill: var(--checker-computer);
|
|
stroke: var(--checker-computer-edge);
|
|
}
|
|
|
|
.checker.movable {
|
|
stroke: var(--highlight);
|
|
stroke-width: 4;
|
|
}
|
|
|
|
.checker.selected {
|
|
stroke: var(--highlight);
|
|
stroke-width: 7;
|
|
}
|
|
|
|
.checker-count {
|
|
font-size: 18px;
|
|
font-weight: 700;
|
|
text-anchor: middle;
|
|
}
|
|
|
|
.count-player { fill: var(--count-player); }
|
|
.count-computer { fill: var(--count-computer); }
|
|
|
|
.target-zone { fill: var(--target); }
|
|
/* Le dernier coup de l'ordinateur (couleur laiton, charte) : une flèche par
|
|
* demi-coup, les pions arrivés et frappés entourés, un pion fantôme là où
|
|
* un pion est parti. */
|
|
.trace-arrow {
|
|
stroke: var(--last-move);
|
|
stroke-width: 5;
|
|
stroke-linecap: round;
|
|
opacity: 0.85;
|
|
}
|
|
|
|
.trace-head { fill: var(--last-move); }
|
|
|
|
.trace-landed,
|
|
.trace-hit {
|
|
fill: none;
|
|
stroke: var(--last-move);
|
|
stroke-width: 4;
|
|
}
|
|
|
|
.trace-hit { stroke-dasharray: 6 4; }
|
|
|
|
.trace-ghost {
|
|
fill: none;
|
|
stroke: var(--last-move);
|
|
stroke-width: 2.5;
|
|
stroke-dasharray: 5 4;
|
|
}
|
|
|
|
.die-player { fill: var(--die-player); stroke: var(--checker-player-edge); }
|
|
.die-computer { fill: var(--die-computer); stroke: var(--checker-computer-edge); }
|
|
.pip-player { fill: var(--pip-player); }
|
|
.pip-computer { fill: var(--pip-computer); }
|
|
|
|
.cube-face { fill: var(--cube); stroke: var(--checker-player-edge); stroke-width: 2; }
|
|
|
|
.cube-value {
|
|
fill: var(--cube-text);
|
|
font-size: 17px;
|
|
font-weight: 700;
|
|
text-anchor: middle;
|
|
}
|
|
|
|
.hit {
|
|
fill: transparent;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* --------------------------------------------------------------- Aide */
|
|
|
|
.help h2 {
|
|
margin-top: 1.5rem;
|
|
font-size: 1.2rem;
|
|
}
|
|
|
|
.help h3 {
|
|
margin-bottom: 0.25rem;
|
|
font-size: 1rem;
|
|
}
|
|
|
|
.steps {
|
|
padding-left: 1.25rem;
|
|
}
|
|
|
|
.glossary dt {
|
|
margin-top: 0.6rem;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.glossary dd {
|
|
margin: 0;
|
|
}
|
|
|
|
.about {
|
|
margin-top: 2rem;
|
|
font-size: 0.85rem;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.about a {
|
|
color: var(--accent);
|
|
}
|
|
|
|
/* ------------------------------------------------------- Mode paysage */
|
|
|
|
/* Téléphone tourné : le plateau prend toute la hauteur disponible, et les
|
|
* messages et boutons passent dans une colonne à sa droite. */
|
|
@media (orientation: landscape) and (max-height: 40rem) {
|
|
body {
|
|
max-width: none;
|
|
}
|
|
|
|
.topbar {
|
|
padding: 0.25rem 0;
|
|
}
|
|
|
|
#game {
|
|
display: grid;
|
|
grid-template-columns: auto minmax(12rem, 1fr);
|
|
grid-template-rows: auto auto auto 1fr;
|
|
column-gap: 1rem;
|
|
align-items: start;
|
|
}
|
|
|
|
.board {
|
|
grid-row: 1 / 5;
|
|
width: auto;
|
|
/* Hauteur de l'écran moins la barre du haut (boutons de 40 px). */
|
|
height: calc(100vh - 3.5rem);
|
|
height: calc(100dvh - 3.5rem);
|
|
max-width: 70vw;
|
|
}
|
|
|
|
.pips {
|
|
text-align: left;
|
|
}
|
|
}
|