diff --git a/app/src/football/CommentaryDanmaku.jsx b/app/src/football/CommentaryDanmaku.jsx index e5eea8a..1478dc1 100644 --- a/app/src/football/CommentaryDanmaku.jsx +++ b/app/src/football/CommentaryDanmaku.jsx @@ -165,10 +165,10 @@ export default function CommentaryDanmaku() { aria-hidden sx={{ position: "fixed", - top: { xs: "5.5rem", md: "6.25rem" }, + top: { xs: "32%", md: "6.25rem" }, left: 0, right: 0, - height: { xs: "38%", md: "42%" }, + height: { xs: "28%", md: "42%" }, zIndex: 11, pointerEvents: "none", overflow: "hidden", @@ -183,7 +183,7 @@ export default function CommentaryDanmaku() { left: "100%", whiteSpace: "nowrap", fontFamily: ANTON, - fontSize: { xs: "0.95rem", md: "1.15rem" }, + fontSize: { xs: "0.82rem", md: "1.15rem" }, letterSpacing: "0.04em", color: it.team === "red" ? RED_ACCENT : it.team === "blue" ? BLUE_ACCENT : CREAM, textShadow: `0 1px 0 ${COMIC_INK}, 0 0 10px rgba(0,0,0,0.65)`, diff --git a/app/src/football/FootballHud.jsx b/app/src/football/FootballHud.jsx index f491dc7..cf3db22 100644 --- a/app/src/football/FootballHud.jsx +++ b/app/src/football/FootballHud.jsx @@ -103,12 +103,14 @@ function BackButton() { { uiClick(); useGame.setState({ menuOpen: true }); }} sx={{ appearance: "none", @@ -134,7 +137,7 @@ function BackButton() { color: CREAM, cursor: "pointer", fontFamily: ANTON, - fontSize: "0.82rem", + fontSize: { xs: "0.72rem", sm: "0.82rem" }, letterSpacing: "0.08em", textTransform: "uppercase", lineHeight: 1, @@ -150,7 +153,10 @@ function BackButton() { }, }} > - {t(locale, "back")} + + + {t(locale, "back")} + @@ -168,7 +174,7 @@ function DanmakuToggleButton() { ...scorePlateSx, flexDirection: "row", minWidth: "unset", - padding: "6px 12px", + padding: { xs: "5px 8px", sm: "6px 12px" }, }} > 1 ? ORANGE : CREAM, cursor: "pointer", fontFamily: MONO, - fontSize: "0.65rem", + fontSize: { xs: "0.55rem", sm: "0.65rem" }, letterSpacing: "0.08em", textTransform: "uppercase", lineHeight: 1, @@ -267,48 +273,61 @@ function Scoreboard() { - + {/* Score line */} - RED + RED + R {red} {blue} - BLUE + BLUE + B {/* Timer */} {time} @@ -318,13 +337,14 @@ function Scoreboard() { {label} @@ -383,16 +403,18 @@ export function MatchResultBanner() { aria-live="polite" sx={{ position: "fixed", - top: "8.75rem", + top: { xs: "5.5rem", sm: "8.75rem" }, left: "50%", translate: "-50% 0", - zIndex: 11, + zIndex: 13, pointerEvents: "none", display: "flex", flexDirection: "column", alignItems: "center", - gap: "0.65rem", - rotate: "-1.5deg", + gap: { xs: "0.45rem", sm: "0.65rem" }, + width: { xs: "calc(100vw - 1.25rem)", sm: "auto" }, + maxWidth: "28rem", + rotate: { xs: "-0.6deg", sm: "-1.5deg" }, animation: `${slamIn} 0.45s cubic-bezier(0.2, 1.4, 0.4, 1) both`, "@media (prefers-reduced-motion: reduce)": { animation: "none" }, }} @@ -407,7 +429,9 @@ export function MatchResultBanner() { outlineOffset: 0, borderRadius: 0, background: GLASS, - padding: "10px 34px 12px", + padding: { xs: "8px 16px 10px", sm: "10px 34px 12px" }, + width: { xs: "100%", sm: "auto" }, + boxSizing: "border-box", boxShadow: `7px 7px 0 ${COMIC_INK}, 7px 7px 0 2px ${accent}55`, "&::after": { content: '""', @@ -421,7 +445,7 @@ export function MatchResultBanner() { {headline} @@ -567,7 +592,11 @@ function EventTicker() { {events.map((ev, i) => ( @@ -583,15 +613,18 @@ function EventTicker() { key={`${ev.type}-${ev.time}-${i}`} sx={{ fontFamily: MONO, - fontSize: "0.7rem", + fontSize: { xs: "0.58rem", sm: "0.7rem" }, letterSpacing: "0.1em", textTransform: "uppercase", color: CREAM, background: "rgba(16, 16, 24, 0.75)", border: `1px solid rgba(255, 122, 47, 0.35)`, borderRadius: 0, - padding: "4px 12px", + padding: { xs: "3px 8px", sm: "4px 12px" }, whiteSpace: "nowrap", + maxWidth: "100%", + overflow: "hidden", + textOverflow: "ellipsis", opacity: 1 - i * 0.25, animation: `${fadeSlideUp} 0.3s ease both`, animationDelay: `${i * 0.08}s`, @@ -619,8 +652,9 @@ function PenaltyIndicator() { s.entered); + const menuOpen = useGame((s) => s.menuOpen); + // Title / pause overlay is opaque — keep match chrome out of the way so + // it cannot peek through or steal layout on phones. + if (!entered || menuOpen) return null; + return ( diff --git a/app/src/football/FootballTitle.jsx b/app/src/football/FootballTitle.jsx index be84119..f37e8b0 100644 --- a/app/src/football/FootballTitle.jsx +++ b/app/src/football/FootballTitle.jsx @@ -257,7 +257,7 @@ export default function FootballTitle({ onKickOff }) { flexDirection: "column", alignItems: "center", justifyContent: "center", - p: "2.4rem 1.4rem 1.8rem", + p: { xs: "1.1rem 0.85rem 1.1rem", sm: "2.4rem 1.4rem 1.8rem" }, background: INK, opacity: menuOpen ? 1 : 0, pointerEvents: menuOpen ? "auto" : "none", @@ -282,8 +282,8 @@ export default function FootballTitle({ onKickOff }) { aria-hidden sx={{ position: "absolute", - top: "1.25rem", - left: "1.5rem", + top: { xs: "0.75rem", sm: "1.25rem" }, + left: { xs: "0.75rem", sm: "1.5rem" }, zIndex: 1, display: "flex", alignItems: "center", @@ -299,7 +299,7 @@ export default function FootballTitle({ onKickOff }) { sx={{ position: "relative", display: "block", - height: "2.1rem", + height: { xs: "1.7rem", sm: "2.1rem" }, filter: "drop-shadow(2px 2px 0 rgba(0, 0, 0, 0.5))", }} > @@ -341,9 +341,38 @@ export default function FootballTitle({ onKickOff }) { )} - {ready && } - {ready && } - {ready && } + {ready && ( + + )} + {ready && ( + + )} + {ready && ( + + )} {/* Boot gate: one centered spinner on bare ink with the match's step line until fonts, brand art and the game core are in. A @@ -400,7 +429,7 @@ export default function FootballTitle({ onKickOff }) { maxWidth: "min(48rem, 94vw)", flex: "1 1 auto", minHeight: 0, - pt: { xs: "2.6rem", md: "1rem" }, + pt: { xs: "3.4rem", sm: "2.6rem", md: "1rem" }, }} > {bootFailed ? ( @@ -428,7 +457,7 @@ export default function FootballTitle({ onKickOff }) { component="h1" tone="dark" accent={ORANGE} - fontSize="clamp(3.2rem, 8.5vw, 5.8rem)" + fontSize="clamp(2.35rem, 11vw, 5.8rem)" lines={[ { text: "Microduck" }, { text: "Football 3v3", variant: "outline", scale: 0.62 }, @@ -439,14 +468,15 @@ export default function FootballTitle({ onKickOff }) { @@ -463,8 +493,8 @@ export default function FootballTitle({ onKickOff }) { display: "inline-flex", flexDirection: "column", alignItems: "center", - mt: "1.4rem", - "@media (max-height: 700px)": { mt: "1rem" }, + mt: { xs: "0.9rem", sm: "1.4rem" }, + "@media (max-height: 700px)": { mt: "0.75rem" }, ...row(0.32), }} > @@ -544,9 +574,10 @@ export default function FootballTitle({ onKickOff }) { position: "relative", width: "100%", textAlign: "center", - mt: "1.2rem", - pt: "1.15rem", + mt: { xs: "0.85rem", sm: "1.2rem" }, + pt: { xs: "0.85rem", sm: "1.15rem" }, borderTop: "1px solid rgba(255, 255, 255, 0.08)", + display: { xs: "none", sm: "block" }, ...row(0.5), }} > diff --git a/app/src/football/StrategyBoard.jsx b/app/src/football/StrategyBoard.jsx index 67c1a9a..7a3b0dc 100644 --- a/app/src/football/StrategyBoard.jsx +++ b/app/src/football/StrategyBoard.jsx @@ -86,7 +86,7 @@ function TeamTags({ team, strategy, locale, isUser, onOpenCoach }) { border: `2px solid ${accent}`, boxShadow: `inset 0 0 0 1px ${COMIC_INK}`, background: GLASS, - p: "0.45rem 0.55rem", + p: { xs: "0.35rem 0.4rem", sm: "0.45rem 0.55rem" }, pointerEvents: isUser ? "auto" : "none", cursor: isUser ? "pointer" : "default", }} @@ -104,7 +104,7 @@ function TeamTags({ team, strategy, locale, isUser, onOpenCoach }) { *": { pointerEvents: "auto" }, }} @@ -177,24 +177,28 @@ export default function StrategyBoard() { border: `2px solid ${COMIC_INK}`, background: GLASS, boxShadow: `inset 0 0 0 1px rgba(255,255,255,0.08)`, - p: "0.5rem 0.7rem 0.55rem", + p: { xs: "0.3rem 0.45rem 0.35rem", sm: "0.5rem 0.7rem 0.55rem" }, display: "flex", - flexDirection: "column", - gap: "0.4rem", + flexDirection: { xs: "row", sm: "column" }, + alignItems: { xs: "center", sm: "stretch" }, + gap: { xs: "0.55rem", sm: "0.4rem" }, }} > - + + + {shotsR} @@ -202,7 +206,7 @@ export default function StrategyBoard() { component="span" sx={{ fontFamily: MONO, - fontSize: "0.5rem", + fontSize: { xs: "0.42rem", sm: "0.5rem" }, letterSpacing: "0.14em", textTransform: "uppercase", color: "rgba(255,255,255,0.45)", @@ -214,7 +218,7 @@ export default function StrategyBoard() { - + {t(locale, "fpvLabel")} @@ -120,21 +121,21 @@ export default function TeamFpv() { - + );