Battle result dialog, speed toggle, and topbar refactor for mobile.
- End-of-battle result is now a centered dialog (Victory/Defeat/Draw) with 'Next round' and 'Not yet'; 'Not yet' dismisses it to rewatch the battle, and a toolbar button remains to advance. A modal is always fully on screen, fixing the next-round button being unreachable below the arena on phones. - Also make the play area genuinely scrollable on phones (stretch the body so table-main's overflow can engage) as a safety net. - Collapse the 5-button playback speed picker into one button that cycles through the options, keeping the battle controls on a single row. - Topbar: show the round as a die face (1-6 pips) on all screens, move the room code and Leave into a '...' dropdown menu, and drop the wordmark on phones so the rail stays one row (die + players + menu). - On phones, strip battle cards to art + power/damage + name (no suit, tier, or ability text); the magnified view still shows the full card.
This commit is contained in:
@@ -289,7 +289,11 @@ function unitPop(ev: BattleEvent | null, seat: number, events: BattleEvent[], st
|
|||||||
export function BattlePhase({ view, send, step, setStep }: Props) {
|
export function BattlePhase({ view, send, step, setStep }: Props) {
|
||||||
const battle = view.battle!
|
const battle = view.battle!
|
||||||
const events = battle.events ?? []
|
const events = battle.events ?? []
|
||||||
|
// acked = the player committed to the next round (waiting on the opponent).
|
||||||
const [acked, setAcked] = useState(false)
|
const [acked, setAcked] = useState(false)
|
||||||
|
// The result dialog pops when the replay ends. "Not yet" dismisses it so the
|
||||||
|
// battle can be rewatched; a toolbar button then remains to advance the round.
|
||||||
|
const [resultDismissed, setResultDismissed] = useState(false)
|
||||||
// The deck-peek popover lives inside .battlefield, which sets overflow-x
|
// The deck-peek popover lives inside .battlefield, which sets overflow-x
|
||||||
// (and thus overflow-y) to auto — so an absolutely-positioned popover gets
|
// (and thus overflow-y) to auto — so an absolutely-positioned popover gets
|
||||||
// clipped to the battlefield. We anchor it to the hovered stack's viewport
|
// clipped to the battlefield. We anchor it to the hovered stack's viewport
|
||||||
@@ -358,6 +362,17 @@ export function BattlePhase({ view, send, step, setStep }: Props) {
|
|||||||
const won = battle.winnerSeat === youSeat
|
const won = battle.winnerSeat === youSeat
|
||||||
const draw = battle.winnerSeat < 0
|
const draw = battle.winnerSeat < 0
|
||||||
|
|
||||||
|
// Commit to the next round: ack and hand off to the server.
|
||||||
|
const proceed = () => {
|
||||||
|
setAcked(true)
|
||||||
|
send({ type: 'ready' })
|
||||||
|
}
|
||||||
|
const nextLabel = battle.round >= view.maxRounds ? 'See final results' : 'Next round →'
|
||||||
|
// Show the result dialog when the replay finishes — unless the player chose
|
||||||
|
// "Not yet" to rewatch (then only the toolbar button remains). Once they've
|
||||||
|
// committed, the dialog reappears to show the "waiting" state.
|
||||||
|
const showResult = done && (acked || !resultDismissed)
|
||||||
|
|
||||||
// Dice for the rock event currently on screen. renderSide draws them under
|
// Dice for the rock event currently on screen. renderSide draws them under
|
||||||
// the throwing side's deck; `step` keys the tray so the scramble replays for
|
// the throwing side's deck; `step` keys the tray so the scramble replays for
|
||||||
// every rock event.
|
// every rock event.
|
||||||
@@ -603,6 +618,17 @@ export function BattlePhase({ view, send, step, setStep }: Props) {
|
|||||||
>
|
>
|
||||||
⏱ {speed}×
|
⏱ {speed}×
|
||||||
</button>
|
</button>
|
||||||
|
{/* Once the replay ends, a persistent way to advance the round — the
|
||||||
|
path forward after the result dialog is dismissed to rewatch. */}
|
||||||
|
{done && !acked && (
|
||||||
|
<button
|
||||||
|
className="btn btn-primary btn-sm battle-next"
|
||||||
|
onClick={proceed}
|
||||||
|
title={nextLabel}
|
||||||
|
>
|
||||||
|
{battle.round >= view.maxRounds ? 'Results →' : 'Next round →'}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -658,32 +684,38 @@ export function BattlePhase({ view, send, step, setStep }: Props) {
|
|||||||
)
|
)
|
||||||
})()}
|
})()}
|
||||||
|
|
||||||
{done && (
|
{/* The result lands as a centered dialog — always fully on screen, even on
|
||||||
<div className={`battle-result ${draw ? 'is-draw' : won ? 'is-win' : 'is-loss'}`}>
|
a phone where the arena fills the viewport. "Not yet" dismisses it so
|
||||||
|
the battle can be rewatched; the toolbar keeps a way to advance. */}
|
||||||
|
{showResult &&
|
||||||
|
createPortal(
|
||||||
|
<div className="modal-backdrop">
|
||||||
|
<div className={`modal battle-result-modal ${draw ? 'is-draw' : won ? 'is-win' : 'is-loss'}`}>
|
||||||
<div className="battle-result-title">
|
<div className="battle-result-title">
|
||||||
{draw ? 'Draw!' : won ? 'Victory!' : 'Defeat…'}
|
{draw ? 'Draw!' : won ? 'Victory!' : 'Defeat…'}
|
||||||
</div>
|
</div>
|
||||||
{!draw && (
|
{!draw ? (
|
||||||
<div className="battle-result-sub">
|
<div className="battle-result-sub">
|
||||||
{view.players[battle.winnerSeat]?.name} wins{' '}
|
{view.players[battle.winnerSeat]?.name} wins {'🏆'.repeat(battle.trophies)}
|
||||||
{'🏆'.repeat(battle.trophies)}
|
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="battle-result-sub">No trophies awarded</div>
|
||||||
)}
|
)}
|
||||||
{draw && <div className="battle-result-sub">No trophies awarded</div>}
|
|
||||||
{acked ? (
|
{acked ? (
|
||||||
<p className="muted">Waiting for opponent…</p>
|
<p className="muted">Waiting for opponent…</p>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<div className="actions">
|
||||||
className="btn btn-primary btn-big"
|
<button className="btn btn-ghost" onClick={() => setResultDismissed(true)}>
|
||||||
onClick={() => {
|
Not yet
|
||||||
setAcked(true)
|
|
||||||
send({ type: 'ready' })
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{battle.round >= view.maxRounds ? 'See final results' : 'Next round →'}
|
|
||||||
</button>
|
</button>
|
||||||
|
<button className="btn btn-primary btn-big" onClick={proceed}>
|
||||||
|
{nextLabel}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</div>,
|
||||||
|
document.body,
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ const DIE_PIPS: Record<number, [number, number][]> = {
|
|||||||
6: [[9, 9], [21, 9], [9, 15], [21, 15], [9, 21], [21, 21]],
|
6: [[9, 9], [21, 9], [9, 15], [21, 15], [9, 21], [21, 21]],
|
||||||
}
|
}
|
||||||
|
|
||||||
function TierDie({ tier }: { tier: number }) {
|
// DieFace renders a value 1–6 as a pipped die, like the real game's markers.
|
||||||
const pips = DIE_PIPS[tier] ?? DIE_PIPS[1]
|
// Shared by the card's tier corner and the topbar's round indicator.
|
||||||
|
export function DieFace({ value, className }: { value: number; className?: string }) {
|
||||||
|
const pips = DIE_PIPS[value] ?? DIE_PIPS[1]
|
||||||
return (
|
return (
|
||||||
<svg className="card-die" viewBox="0 0 30 30" aria-hidden>
|
<svg className={className} viewBox="0 0 30 30" aria-hidden>
|
||||||
<rect x="1.5" y="1.5" width="27" height="27" rx="6.5" fill="#fff" stroke="#2c1c0e" strokeWidth="2" />
|
<rect x="1.5" y="1.5" width="27" height="27" rx="6.5" fill="#fff" stroke="#2c1c0e" strokeWidth="2" />
|
||||||
{pips.map(([cx, cy], i) => (
|
{pips.map(([cx, cy], i) => (
|
||||||
<circle key={i} cx={cx} cy={cy} r="2.9" fill="#2c1c0e" />
|
<circle key={i} cx={cx} cy={cy} r="2.9" fill="#2c1c0e" />
|
||||||
@@ -25,6 +27,10 @@ function TierDie({ tier }: { tier: number }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function TierDie({ tier }: { tier: number }) {
|
||||||
|
return <DieFace value={tier} className="card-die" />
|
||||||
|
}
|
||||||
|
|
||||||
// useFitText shrinks text until it fits its box, so long abilities (and the
|
// useFitText shrinks text until it fits its box, so long abilities (and the
|
||||||
// smaller battle cards) render in full instead of being clipped by the fixed
|
// smaller battle cards) render in full instead of being clipped by the fixed
|
||||||
// card height, and long single-line names shrink instead of wrapping. It
|
// card height, and long single-line names shrink instead of wrapping. It
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { Dispatch, SetStateAction } from 'react'
|
|||||||
import { createPortal } from 'react-dom'
|
import { createPortal } from 'react-dom'
|
||||||
import { useGame } from '../useGame'
|
import { useGame } from '../useGame'
|
||||||
import { useCatalog } from '../useCatalog'
|
import { useCatalog } from '../useCatalog'
|
||||||
import { CardView } from './CardView'
|
import { CardView, DieFace } from './CardView'
|
||||||
import type { Card, Session } from '../types'
|
import type { Card, Session } from '../types'
|
||||||
import { Lobby } from './Lobby'
|
import { Lobby } from './Lobby'
|
||||||
import { ShopPhase } from './ShopPhase'
|
import { ShopPhase } from './ShopPhase'
|
||||||
@@ -44,6 +44,10 @@ export function Table({ session, onLeave }: { session: Session; onLeave: () => v
|
|||||||
// this open flag is simply ignored.
|
// this open flag is simply ignored.
|
||||||
const [logOpen, setLogOpen] = useState(false)
|
const [logOpen, setLogOpen] = useState(false)
|
||||||
|
|
||||||
|
// The room code and Leave button live behind a "⋯" menu in the topbar rail,
|
||||||
|
// keeping the rail short enough for one row on a phone.
|
||||||
|
const [menuOpen, setMenuOpen] = useState(false)
|
||||||
|
|
||||||
// The battle outcome is known before the replay plays out, so we hold its
|
// The battle outcome is known before the replay plays out, so we hold its
|
||||||
// "result" log entry back: it's dropped from the persistent list during the
|
// "result" log entry back: it's dropped from the persistent list during the
|
||||||
// battle and appended as the final battle line only once the replay reaches
|
// battle and appended as the final battle line only once the replay reaches
|
||||||
@@ -132,8 +136,12 @@ export function Table({ session, onLeave }: { session: Session; onLeave: () => v
|
|||||||
🐾 <span>SAP</span>
|
🐾 <span>SAP</span>
|
||||||
</div>
|
</div>
|
||||||
{view.phase !== 'gameover' && view.phase !== 'lobby' && (
|
{view.phase !== 'gameover' && view.phase !== 'lobby' && (
|
||||||
<div className="topbar-round">
|
<div
|
||||||
Round <strong>{view.round}</strong> / {view.maxRounds}
|
className="topbar-round"
|
||||||
|
title={`Round ${view.round} of ${view.maxRounds}`}
|
||||||
|
aria-label={`Round ${view.round} of ${view.maxRounds}`}
|
||||||
|
>
|
||||||
|
<DieFace value={view.round} className="topbar-die" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="topbar-players">
|
<div className="topbar-players">
|
||||||
@@ -179,12 +187,41 @@ export function Table({ session, onLeave }: { session: Session; onLeave: () => v
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="topbar-code" title="Share this code with your opponent">
|
<div className="topbar-menu">
|
||||||
{view.code}
|
<button
|
||||||
</div>
|
className="btn btn-ghost btn-sm topbar-menu-btn"
|
||||||
<button className="btn btn-ghost btn-sm" onClick={onLeave}>
|
onClick={() => setMenuOpen((o) => !o)}
|
||||||
Leave
|
aria-haspopup="menu"
|
||||||
|
aria-expanded={menuOpen}
|
||||||
|
aria-label="Game menu"
|
||||||
|
title="Room code & leave"
|
||||||
|
>
|
||||||
|
⋯
|
||||||
</button>
|
</button>
|
||||||
|
{menuOpen && (
|
||||||
|
<>
|
||||||
|
<div className="topbar-menu-backdrop" onClick={() => setMenuOpen(false)} />
|
||||||
|
<div className="topbar-menu-pop" role="menu">
|
||||||
|
<div className="topbar-menu-code">
|
||||||
|
<span className="muted">Room code</span>
|
||||||
|
<span className="topbar-code" title="Share this code with your opponent">
|
||||||
|
{view.code}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="btn btn-ghost btn-sm"
|
||||||
|
role="menuitem"
|
||||||
|
onClick={() => {
|
||||||
|
setMenuOpen(false)
|
||||||
|
onLeave()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Leave game
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div className="table-body">
|
<div className="table-body">
|
||||||
|
|||||||
+105
-27
@@ -422,14 +422,17 @@ h3 {
|
|||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The round shows as a die face — 1–6 pips, like the real game's round marker. */
|
||||||
.topbar-round {
|
.topbar-round {
|
||||||
font-size: 0.95rem;
|
display: flex;
|
||||||
font-weight: 700;
|
align-items: center;
|
||||||
color: rgba(255, 245, 225, 0.9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.topbar-round strong {
|
.topbar-die {
|
||||||
color: var(--gold);
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
display: block;
|
||||||
|
filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.4));
|
||||||
}
|
}
|
||||||
|
|
||||||
.topbar-players {
|
.topbar-players {
|
||||||
@@ -514,7 +517,7 @@ h3 {
|
|||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The room code, stamped like a label on a card tray. */
|
/* The room code, stamped like a label on a card tray. Lives inside the ⋯ menu. */
|
||||||
.topbar-code {
|
.topbar-code {
|
||||||
font-family: var(--font-display);
|
font-family: var(--font-display);
|
||||||
letter-spacing: 0.28em;
|
letter-spacing: 0.28em;
|
||||||
@@ -525,6 +528,54 @@ h3 {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The ⋯ menu holds the room code and Leave, pushed to the right of the rail so
|
||||||
|
the middle is just the players and their stats. */
|
||||||
|
.topbar-menu {
|
||||||
|
position: relative;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-menu-btn {
|
||||||
|
font-size: 1.15rem;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 5px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A full-viewport catcher so a click anywhere off the menu closes it. */
|
||||||
|
.topbar-menu-backdrop {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-menu-pop {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: calc(100% + 8px);
|
||||||
|
z-index: 21;
|
||||||
|
min-width: 190px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 14px;
|
||||||
|
background:
|
||||||
|
repeating-linear-gradient(92deg, rgba(0, 0, 0, 0.05) 0 3px, transparent 3px 7px),
|
||||||
|
linear-gradient(180deg, var(--wood-light), var(--wood) 70%, var(--wood-dark));
|
||||||
|
border: 2px solid var(--wood-dark);
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow:
|
||||||
|
inset 0 1px 0 rgba(255, 220, 170, 0.25),
|
||||||
|
0 14px 30px rgba(0, 0, 0, 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-menu-code {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
align-items: flex-start;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
}
|
||||||
|
|
||||||
.table-body {
|
.table-body {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -2666,14 +2717,11 @@ h3 {
|
|||||||
z-index: 5;
|
z-index: 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.battle-result {
|
/* The end-of-battle result dialog: a centered modal so it's always fully on
|
||||||
text-align: center;
|
screen (even on a phone where the arena fills the viewport). */
|
||||||
display: flex;
|
.battle-result-modal {
|
||||||
flex-direction: column;
|
gap: 14px;
|
||||||
gap: 12px;
|
min-width: min(320px, 86vw);
|
||||||
align-items: center;
|
|
||||||
padding: 8px 0;
|
|
||||||
animation: result-in 400ms ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes result-in {
|
@keyframes result-in {
|
||||||
@@ -2693,15 +2741,15 @@ h3 {
|
|||||||
text-shadow: 0 3px 0 rgba(0, 0, 0, 0.3), 0 6px 14px rgba(0, 0, 0, 0.4);
|
text-shadow: 0 3px 0 rgba(0, 0, 0, 0.3), 0 6px 14px rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.battle-result.is-win .battle-result-title {
|
.battle-result-modal.is-win .battle-result-title {
|
||||||
color: var(--gold);
|
color: var(--gold);
|
||||||
}
|
}
|
||||||
|
|
||||||
.battle-result.is-loss .battle-result-title {
|
.battle-result-modal.is-loss .battle-result-title {
|
||||||
color: #ff8f7a;
|
color: #ff8f7a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.battle-result.is-draw .battle-result-title {
|
.battle-result-modal.is-draw .battle-result-title {
|
||||||
color: #6fd6c2;
|
color: #6fd6c2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2710,6 +2758,11 @@ h3 {
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The toolbar's "advance the round" button stands out from the ghost controls. */
|
||||||
|
.battle-next {
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- game over ---------- */
|
/* ---------- game over ---------- */
|
||||||
|
|
||||||
.gameover {
|
.gameover {
|
||||||
@@ -2856,19 +2909,23 @@ h3 {
|
|||||||
gap: 5px 8px;
|
gap: 5px 8px;
|
||||||
padding: 5px 9px;
|
padding: 5px 9px;
|
||||||
}
|
}
|
||||||
|
/* Drop the wordmark entirely on a phone — the die, the player tags, and the
|
||||||
|
⋯ menu are all that's needed, and losing it helps the rail stay one row. */
|
||||||
.topbar-brand {
|
.topbar-brand {
|
||||||
font-size: 1.05rem;
|
|
||||||
}
|
|
||||||
/* The wordmark is redundant next to the paw on a phone — drop it to buy width
|
|
||||||
so the rail packs onto fewer rows. */
|
|
||||||
.topbar-brand span {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
/* Let the tags pack tight instead of stretching across a whole row. */
|
.topbar-die {
|
||||||
|
width: 23px;
|
||||||
|
height: 23px;
|
||||||
|
}
|
||||||
|
/* Let the tags pack tight; the ⋯ menu is pushed to the right by margin-auto. */
|
||||||
.topbar-players {
|
.topbar-players {
|
||||||
flex: 0 1 auto;
|
flex: 0 1 auto;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
.topbar-menu-btn {
|
||||||
|
padding: 4px 10px;
|
||||||
|
}
|
||||||
.topbar-round {
|
.topbar-round {
|
||||||
font-size: 0.82rem;
|
font-size: 0.82rem;
|
||||||
}
|
}
|
||||||
@@ -3065,6 +3122,30 @@ h3 {
|
|||||||
min-width: 72px;
|
min-width: 72px;
|
||||||
min-height: 112px;
|
min-height: 112px;
|
||||||
}
|
}
|
||||||
|
/* A battle card is small and glanced at, not read — so on a phone strip it to
|
||||||
|
the essentials: big art, the power badge and any damage marker, and the
|
||||||
|
name. No suit dot, tier die, or ability text (the magnified view still shows
|
||||||
|
the full card). The scene grows to fill the space the panel gives up. */
|
||||||
|
.battle-unit .card-scene {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
.battle-unit .card-panel {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
.battle-unit .card-effect,
|
||||||
|
.battle-unit .card-suit,
|
||||||
|
.battle-unit .card-die,
|
||||||
|
.battle-unit .card-panel-slot {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.battle-unit .card-panel-head {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
border-bottom: none;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
.battle-unit .card-art {
|
||||||
|
font-size: 2.1rem;
|
||||||
|
}
|
||||||
.card-back {
|
.card-back {
|
||||||
width: 56px;
|
width: 56px;
|
||||||
height: 78px;
|
height: 78px;
|
||||||
@@ -3078,13 +3159,10 @@ h3 {
|
|||||||
.food-fan-card:not(:first-child) {
|
.food-fan-card:not(:first-child) {
|
||||||
margin-left: -50px;
|
margin-left: -50px;
|
||||||
}
|
}
|
||||||
.battle-result {
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
.battle-result-title {
|
.battle-result-title {
|
||||||
font-size: 1.7rem;
|
font-size: 1.7rem;
|
||||||
}
|
}
|
||||||
.battle-result .btn-big {
|
.battle-result-modal .btn-big {
|
||||||
font-size: 1.05rem;
|
font-size: 1.05rem;
|
||||||
padding: 11px 22px;
|
padding: 11px 22px;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user