This commit is contained in:
Henri Bourcereau 2026-06-20 15:42:28 +02:00
parent 33d2163bab
commit cf289fa779
9 changed files with 2577 additions and 171 deletions

View file

@ -784,6 +784,7 @@ a:hover { text-decoration: underline; }
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
min-width: 4em; min-width: 4em;
text-align: left;
} }
.score-bars { display: flex; flex-direction: row; gap: 1.5rem; flex: 1; align-items: center; } .score-bars { display: flex; flex-direction: row; gap: 1.5rem; flex: 1; align-items: center; }
@ -864,6 +865,7 @@ a:hover { text-decoration: underline; }
letter-spacing: 0.06em; letter-spacing: 0.06em;
cursor: default; cursor: default;
box-shadow: 0 1px 3px rgba(0,0,0,0.25); box-shadow: 0 1px 3px rgba(0,0,0,0.25);
margin: 0.4em;
} }
/* ── Merged scoreboard (both players, above board) ──────────────────── */ /* ── Merged scoreboard (both players, above board) ──────────────────── */
@ -940,6 +942,7 @@ a:hover { text-decoration: underline; }
display: flex; display: flex;
align-items: baseline; align-items: baseline;
gap: 0.1rem; gap: 0.1rem;
direction: ltr;
} }
.pts-counter { .pts-counter {
@ -2322,9 +2325,8 @@ a:hover { text-decoration: underline; }
gap: 0.5rem; gap: 0.5rem;
} }
.strip-player { display: flex; align-items: center; flex: 1; min-width: 0; } .strip-player { display: flex; justify-content: flex-end; align-items: center; flex: 1; min-width: 0; }
.strip-player-left { justify-content: flex-end; } .strip-player-left { }
.strip-player-right { justify-content: flex-start; }
.strip-active-zone { .strip-active-zone {
display: flex; display: flex;
@ -2362,7 +2364,7 @@ a:hover { text-decoration: underline; }
} }
/* Strip peg overrides */ /* Strip peg overrides */
.players-strip .peg-track { gap: 3px; } .players-strip .peg-track { gap: 3px; direction: ltr; }
.players-strip .peg-hole { width: 12px; height: 12px; } .players-strip .peg-hole { width: 12px; height: 12px; }
.players-strip .peg-hole.filled { .players-strip .peg-hole.filled {
background: #5aab38; border-color: #3a7828; background: #5aab38; border-color: #3a7828;
@ -2404,16 +2406,23 @@ a:hover { text-decoration: underline; }
} }
/* ── Controls column (sidebar on wide, row on narrow) ────────────────── */ /* ── Controls column (sidebar on wide, row on narrow) ────────────────── */
.controls { /* left-control displayed only on wide screen to center board */
.controls, .left-controls {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 0.5rem; gap: 0.5rem;
align-self: stretch; align-self: stretch;
} }
@media (min-width: 1120px) {
.left-controls {
width: 200px;
}
}
@media (min-width: 920px) { @media (min-width: 920px) {
.controls { .controls {
width: 200px; width: 200px;
} }
.strip-player-right { direction: rtl; }
} }
.ctrl-dice { .ctrl-dice {
@ -2502,6 +2511,11 @@ a:hover { text-decoration: underline; }
margin: 0; margin: 0;
} }
@media (max-width: 1119px) {
.left-controls {
width: 0;
}
}
/* ── Responsive: ≤919px → controls becomes a bottom bar ─────────────── */ /* ── Responsive: ≤919px → controls becomes a bottom bar ─────────────── */
@media (max-width: 919px) { @media (max-width: 919px) {
.main-body { .main-body {
@ -2513,6 +2527,7 @@ a:hover { text-decoration: underline; }
width: 100%; width: 100%;
} }
.ctrl-status { flex: 1; } .ctrl-status { flex: 1; }
/* Hide pegs on small screens to save space in the strip */ .strip-center { display: none; }
.players-strip .peg-track { display: none; } /* move second player below first player */
.players-strip { flex-flow: column; }
} }

View file

@ -150,7 +150,7 @@
"account_deleted": "Your account has been permanently deleted.", "account_deleted": "Your account has been permanently deleted.",
"about": "About", "about": "About",
"legal": "Legal notices", "legal": "Legal notices",
"free_mode_label": "Free play mode", "free_mode_label": "Free move mode",
"free_mode_tooltip": "Select any checker and try to find a valid move yourself. If your move breaks a rule, you'll see an explanation.", "free_mode_tooltip": "Select any checker and try to find a valid move yourself. If your move breaks a rule, you'll see an explanation.",
"reset_move": "Try again", "reset_move": "Try again",
"err_invalid_move": "This move is not valid with the current dice", "err_invalid_move": "This move is not valid with the current dice",

View file

@ -148,7 +148,7 @@
"account_deleted": "Votre compte a été définitivement supprimé.", "account_deleted": "Votre compte a été définitivement supprimé.",
"about": "À propos", "about": "À propos",
"legal": "Mentions légales", "legal": "Mentions légales",
"free_mode_label": "Mode jeu libre", "free_mode_label": "Déplacement libre",
"free_mode_tooltip": "Sélectionnez n'importe quelle dame et tentez de trouver un coup valide vous-même. Si votre coup enfreint une règle, une explication s'affichera.", "free_mode_tooltip": "Sélectionnez n'importe quelle dame et tentez de trouver un coup valide vous-même. Si votre coup enfreint une règle, une explication s'affichera.",
"reset_move": "Réessayer", "reset_move": "Réessayer",
"err_invalid_move": "Ce coup n'est pas valide avec les dés actuels", "err_invalid_move": "Ce coup n'est pas valide avec les dés actuels",

View file

@ -696,9 +696,9 @@ fn SiteHamburger() -> impl IntoView {
</div> </div>
<div> <div>
<div class="site-nav-infolinks"> <div class="site-nav-infolinks">
<a href="/page/about">{t!(i18n, about)}</a> <a href="/page/about" on:click=move |_| { sidebar_open.set(false); } >{t!(i18n, about)}</a>
<span> - </span> <span> - </span>
<a href="/page/legal">{t!(i18n, legal)}</a> <a href="/page/legal" on:click=move |_| { sidebar_open.set(false); } >{t!(i18n, legal)}</a>
</div> </div>
</div> </div>
<div> <div>

View file

@ -345,6 +345,7 @@ pub fn GameScreen(state: GameUiState) -> impl IntoView {
// ── Board + controls (sidebar on wide, footer on narrow) ───────── // ── Board + controls (sidebar on wide, footer on narrow) ─────────
<div class="main-body"> <div class="main-body">
<div class="left-controls"></div>
<Board <Board
view_state=vs view_state=vs
player_id=player_id player_id=player_id

View file

@ -170,17 +170,17 @@ pub fn MergedScorePanel(
<div class="score-row-name"> <div class="score-row-name">
<span class="player-name">{my_name}</span> <span class="player-name">{my_name}</span>
</div> </div>
{my_can_bredouille.then(|| view! {
<span class="bredouille-badge"
title=move || t_string!(i18n, bredouille_title).to_owned()>
"B"
</span>
})}
<div class="peg-track">{my_pegs}</div> <div class="peg-track">{my_pegs}</div>
<div class="pts-counter-wrap"> <div class="pts-counter-wrap">
<div class="pts-counter-row"> <div class="pts-counter-row">
<span class="pts-counter">{move || my_displayed_pts.get()}</span> <span class="pts-counter">{move || my_displayed_pts.get()}</span>
<span class="pts-max">"/12"</span> <span class="pts-max">"/12"</span>
{my_can_bredouille.then(|| view! {
<span class="bredouille-badge"
title=move || t_string!(i18n, bredouille_title).to_owned()>
"B"
</span>
})}
</div> </div>
</div> </div>
{(my_holes_gained > 0).then(|| { {(my_holes_gained > 0).then(|| {
@ -207,23 +207,23 @@ pub fn MergedScorePanel(
// ── Opponent: right side, left-aligned from center ────────────── // ── Opponent: right side, left-aligned from center ──────────────
<div class="strip-player strip-player-right"> <div class="strip-player strip-player-right">
<div class="strip-active-zone" class:active=opp_active> <div class="strip-active-zone" class:active=opp_active>
<div class="strip-avatar strip-avatar-opp"></div>
<div class="score-row-name">
<span class="player-name">{opp_name}</span>
</div>
<div class="peg-track">{opp_pegs}</div>
<div class="pts-counter-wrap"> <div class="pts-counter-wrap">
<div class="pts-counter-row"> <div class="pts-counter-row">
<span class="pts-counter">{move || opp_displayed_pts.get()}</span> <span class="pts-counter">{move || opp_displayed_pts.get()}</span>
<span class="pts-max">"/12"</span> <span class="pts-max">"/12"</span>
{opp_can_bredouille.then(|| view! {
<span class="bredouille-badge"
title=move || t_string!(i18n, bredouille_title).to_owned()>
"B"
</span>
})}
</div> </div>
</div> </div>
<div class="peg-track">{opp_pegs}</div>
{opp_can_bredouille.then(|| view! {
<span class="bredouille-badge"
title=move || t_string!(i18n, bredouille_title).to_owned()>
"B"
</span>
})}
<div class="score-row-name">
<span class="player-name">{opp_name}</span>
</div>
<div class="strip-avatar strip-avatar-opp"></div>
</div> </div>
</div> </div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff