Bilan de fin de partie et écran d'analyse : courbe des chances, visualiseur, liste filtrable, rejouer d'ici
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
a657d7d7a9
commit
006fd62704
+500
@@ -2892,3 +2892,503 @@ html.landscape .explain-sheet > .explain-body {
|
||||
grid-column: 1;
|
||||
grid-row: 1 / span 8;
|
||||
}
|
||||
|
||||
/* ------------------------------------------ Bilan de fin de partie (1e) */
|
||||
|
||||
/* Maquette « Bilan de fin de partie » (charte, ecrans-etape-1.md) : un
|
||||
* panneau centré, à la place du panneau de fin de partie ; il défile si
|
||||
* l'écran est trop bas. */
|
||||
.summary-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
width: min(26rem, 100%);
|
||||
max-height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.summary-panel p {
|
||||
margin: 0;
|
||||
font-size: 17px;
|
||||
line-height: 25px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.summary-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 44px;
|
||||
margin: calc(-1 * var(--space-2)) 0;
|
||||
}
|
||||
|
||||
.summary-title {
|
||||
margin: 0;
|
||||
font-size: 28px;
|
||||
line-height: 34px;
|
||||
}
|
||||
|
||||
.summary-panel .summary-status {
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
/* Trois cases : bons coups, imprécisions, erreurs. */
|
||||
.summary-counts {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.summary-count {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: var(--space-2) var(--space-1);
|
||||
background: var(--surface-sunken);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
.summary-number {
|
||||
font-size: 28px;
|
||||
line-height: 34px;
|
||||
font-weight: 800;
|
||||
font-variant-numeric: tabular-nums lining-nums;
|
||||
}
|
||||
|
||||
.summary-word {
|
||||
display: inline-flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.summary-word .icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
[data-verdict="good"] > .summary-word,
|
||||
.summary-verdict[data-verdict="good"],
|
||||
.row-word[data-verdict="good"],
|
||||
.viewer-phrase[data-verdict="good"] strong { color: var(--verdict-good); }
|
||||
[data-verdict="doubtful"] > .summary-word,
|
||||
.summary-verdict[data-verdict="doubtful"],
|
||||
.row-word[data-verdict="doubtful"],
|
||||
.viewer-phrase[data-verdict="doubtful"] strong { color: var(--verdict-doubtful); }
|
||||
[data-verdict="bad"] > .summary-word,
|
||||
.summary-verdict[data-verdict="bad"],
|
||||
.summary-verdict[data-verdict="veryBad"],
|
||||
.row-word[data-verdict="bad"],
|
||||
.row-word[data-verdict="veryBad"],
|
||||
.viewer-phrase[data-verdict="bad"] strong,
|
||||
.viewer-phrase[data-verdict="veryBad"] strong { color: var(--verdict-bad); }
|
||||
|
||||
/* Deux jauges sur une ligne chacune : votre jeu (niveau), les dés. */
|
||||
.summary-gauges {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
|
||||
.gauge {
|
||||
display: grid;
|
||||
grid-template-columns: 5.5rem minmax(3rem, 1fr) auto;
|
||||
gap: var(--space-2);
|
||||
align-items: center;
|
||||
min-height: 28px;
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.gauge-name {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.gauge-value {
|
||||
color: var(--muted);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.gauge-track {
|
||||
position: relative;
|
||||
height: 8px;
|
||||
overflow: hidden;
|
||||
background: var(--surface-sunken);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.gauge-fill {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: var(--verdict-good);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.gauge-fill.level-1 { width: 16.7%; }
|
||||
.gauge-fill.level-2 { width: 33.3%; }
|
||||
.gauge-fill.level-3 { width: 50%; }
|
||||
.gauge-fill.level-4 { width: 66.7%; }
|
||||
.gauge-fill.level-5 { width: 83.3%; }
|
||||
.gauge-fill.level-6 { width: 100%; }
|
||||
|
||||
/* La chance : jauge centrée, à droite si elle vous a aidé. */
|
||||
.gauge-track.centred::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: calc(50% - 1px);
|
||||
width: 2px;
|
||||
background: var(--muted);
|
||||
}
|
||||
|
||||
.gauge-fill.dice { background: var(--border-strong); border-radius: 0; }
|
||||
.gauge-fill.dice.for-1 { left: 50%; width: 25%; }
|
||||
.gauge-fill.dice.for-2 { left: 50%; width: 50%; }
|
||||
.gauge-fill.dice.against-1 { left: 25%; width: 25%; }
|
||||
.gauge-fill.dice.against-2 { left: 0; width: 50%; }
|
||||
.gauge-fill.dice.even { left: calc(50% - 6px); width: 12px; }
|
||||
|
||||
.summary-glossary {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
align-self: flex-start;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
/* Le coup à revoir : mini-plateau, mot, votre coup, celui du maître. */
|
||||
.summary-review {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2);
|
||||
padding-top: var(--space-3);
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.summary-review-body {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 9rem) minmax(0, 1fr);
|
||||
gap: var(--space-3);
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.summary-panel .summary-verdict {
|
||||
display: inline-flex;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.summary-verdict .icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.summary-panel .summary-played,
|
||||
.summary-panel .summary-master {
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.summary-panel .summary-master {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.summary-review-actions,
|
||||
.viewer-actions {
|
||||
display: flex;
|
||||
gap: var(--space-2);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* L'emplacement de « Demander à une IA » (étape 1f) : réservé, vide. */
|
||||
.ask-ai-slot {
|
||||
flex: 1 1 0;
|
||||
min-height: 44px;
|
||||
}
|
||||
|
||||
.summary-actions > * {
|
||||
flex: 1 1 0;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
/* En paysage : deux colonnes, le résultat et les mesures à gauche, le
|
||||
* coup à revoir et les actions à droite. */
|
||||
html.landscape .summary-panel {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
||||
grid-auto-flow: row dense;
|
||||
column-gap: var(--space-6);
|
||||
align-content: start;
|
||||
width: min(52rem, 100%);
|
||||
}
|
||||
|
||||
html.landscape .summary-panel > * {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
html.landscape .summary-panel > .summary-review,
|
||||
html.landscape .summary-panel > .summary-actions,
|
||||
html.landscape .summary-panel > .panel-link {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
html.landscape .summary-panel > .summary-review {
|
||||
grid-row: 1 / span 4;
|
||||
padding-top: 0;
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------- Analyse d'une partie (1e) */
|
||||
|
||||
/* Maquette interactive « Analyse » : une page qui défile. */
|
||||
.analysis {
|
||||
max-width: var(--page-width);
|
||||
margin: 0 auto;
|
||||
padding-bottom: var(--space-6);
|
||||
}
|
||||
|
||||
.analysis-head {
|
||||
display: flex;
|
||||
gap: var(--space-3);
|
||||
align-items: center;
|
||||
margin: var(--space-3) 0;
|
||||
}
|
||||
|
||||
.analysis-title {
|
||||
margin: 0;
|
||||
font-size: 24px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.analysis-message:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.analysis-card {
|
||||
margin: 0 0 var(--space-4);
|
||||
padding: var(--space-3);
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
|
||||
.analysis-card > .overline {
|
||||
margin-bottom: var(--space-2);
|
||||
}
|
||||
|
||||
/* La courbe de vos chances de gagner : on la parcourt du doigt. */
|
||||
.analysis-curve {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 168px;
|
||||
touch-action: pan-y;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
font-family: var(--font-sans);
|
||||
}
|
||||
|
||||
.analysis-curve:focus-visible {
|
||||
outline: 2px solid var(--focus);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.curve-axis { stroke: var(--border); stroke-width: 1; }
|
||||
.curve-half { stroke: var(--border-strong); stroke-width: 1; stroke-dasharray: 4 4; }
|
||||
.curve-label { fill: var(--muted); font-size: 12px; }
|
||||
.curve-area { fill: var(--accent-soft); }
|
||||
.curve-line { fill: none; stroke: var(--text); stroke-width: 2; stroke-linejoin: round; }
|
||||
.curve-dot.other { fill: var(--text); }
|
||||
.curve-dot.verdict-good { fill: var(--verdict-good); }
|
||||
.curve-dot.verdict-doubtful { fill: var(--verdict-doubtful); }
|
||||
.curve-dot.verdict-bad,
|
||||
.curve-dot.verdict-veryBad { fill: var(--verdict-bad); }
|
||||
.curve-cursor { stroke: var(--accent); stroke-width: 2; }
|
||||
.curve-ring { fill: none; stroke: var(--accent); stroke-width: 2; }
|
||||
.curve-band { fill: transparent; cursor: pointer; }
|
||||
.curve-band.selected { fill: var(--accent); fill-opacity: 0.08; }
|
||||
|
||||
/* Le visualiseur : « ‹ Coup 7 sur 24 · 6-1 › », le plateau d'avant le
|
||||
* coup, la phrase du maître, votre coup contre celui du maître. */
|
||||
.viewer-nav {
|
||||
display: flex;
|
||||
gap: var(--space-2);
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#analysis-prev .icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.viewer-step[aria-disabled="true"] {
|
||||
opacity: 0.35;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.viewer-turn {
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
font-variant-numeric: tabular-nums lining-nums;
|
||||
}
|
||||
|
||||
.viewer-body,
|
||||
.viewer-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.viewer-phrase {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.viewer-phrase strong {
|
||||
display: inline-flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.viewer-phrase strong .icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.viewer-legend {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.viewer-chance {
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.viewer-chance:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.viewer-text .segment {
|
||||
min-height: 44px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.analysis-board[data-move="mine"] { --last-move: var(--text); }
|
||||
.analysis-board[data-move="best"] { --last-move: var(--verdict-good); }
|
||||
|
||||
/* Les coups à revoir : filtres en pastilles, une ligne par coup. */
|
||||
.filters {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-2);
|
||||
margin-bottom: var(--space-2);
|
||||
}
|
||||
|
||||
.filters .filter {
|
||||
min-height: 44px;
|
||||
padding: 0 14px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: var(--text);
|
||||
background: var(--surface-sunken);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.filters .filter[aria-pressed="true"] {
|
||||
color: var(--surface);
|
||||
background: var(--text);
|
||||
border-color: var(--text);
|
||||
}
|
||||
|
||||
.analysis-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.analysis-row {
|
||||
display: grid;
|
||||
grid-template-columns: 2rem 2.5rem minmax(0, 1fr) auto;
|
||||
gap: var(--space-2);
|
||||
align-items: center;
|
||||
min-height: 44px;
|
||||
padding: 0 var(--space-1);
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.analysis-row[aria-current="true"] {
|
||||
background: var(--accent-soft);
|
||||
}
|
||||
|
||||
.row-number,
|
||||
.row-roll {
|
||||
color: var(--muted);
|
||||
font-variant-numeric: tabular-nums lining-nums;
|
||||
}
|
||||
|
||||
.row-move {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.row-word {
|
||||
display: inline-flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.row-word .icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.analysis-empty {
|
||||
padding: var(--space-2) 0;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.analysis-table {
|
||||
grid-template-columns: minmax(0, 1fr) auto auto;
|
||||
}
|
||||
|
||||
/* En paysage : le plateau du visualiseur à gauche, tenu dans la hauteur
|
||||
* de l'écran ; le texte à droite. */
|
||||
html.landscape .viewer-body {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
gap: var(--space-4);
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
html.landscape .analysis-board {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
height: calc(100vh - 120px);
|
||||
height: calc(100dvh - 120px);
|
||||
aspect-ratio: 640 / 520;
|
||||
}
|
||||
|
||||
/* Le mini-plateau du coup à revoir : trop petit pour les numéros des
|
||||
* flèches, qui se chevaucheraient. */
|
||||
.summary-board .point-number {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -101,6 +101,10 @@
|
||||
app/src/ui/new-game-view.ts. -->
|
||||
<section id="new-game" class="new-game page" hidden></section>
|
||||
|
||||
<!-- L'analyse d'une partie (#/parties/<id>/analyse/<coup>), construite par
|
||||
app/src/ui/analysis-view.ts. -->
|
||||
<section id="analysis" class="analysis page" hidden></section>
|
||||
|
||||
<!-- L'aide : un onglet par adresse (#/aide, #/glossaire, #/a-propos). -->
|
||||
<section id="help" class="help page" hidden>
|
||||
<!-- La barre haute de l'aide reste en vue quand la page défile. -->
|
||||
@@ -158,6 +162,10 @@
|
||||
construite par app/src/ui/advice-view.ts. -->
|
||||
<div id="explain-veil" class="veil sheet-veil" hidden></div>
|
||||
|
||||
<!-- Le bilan de fin de partie (#/parties/<id>/bilan) : un panneau centré,
|
||||
construit par app/src/ui/summary-view.ts. -->
|
||||
<div id="summary-veil" class="veil summary-veil" hidden></div>
|
||||
|
||||
<!-- La marche à suivre pour installer (#/installer) : une feuille. -->
|
||||
<div id="install-veil" class="veil sheet-veil" hidden>
|
||||
<div id="install-sheet" class="sheet" role="dialog" aria-modal="true" aria-labelledby="install-title">
|
||||
|
||||
Reference in New Issue
Block a user