diff options
| author | srdusr <trevorgray@srdusr.com> | 2025-09-30 13:15:59 +0200 |
|---|---|---|
| committer | srdusr <trevorgray@srdusr.com> | 2025-09-30 13:15:59 +0200 |
| commit | 18a1b361a9d6567b87c49e8bbbf0bba9ba51687f (patch) | |
| tree | 4892a7d495e44b31bb51a1e24748dcdbe57629da /web/src | |
| parent | 8d60c7f93407988ee0232ea90980028f299cb0f3 (diff) | |
| download | typerpunk-18a1b361a9d6567b87c49e8bbbf0bba9ba51687f.tar.gz typerpunk-18a1b361a9d6567b87c49e8bbbf0bba9ba51687f.zip | |
TUI: fixed wpm history/made UI more identical to web/ctrl-backspace behaviour/improved accuracy
Web: improved category selection/fixed endscreen responsiveness inconsistency/mistake tracking/clean game memory after use/improve general UI
Diffstat (limited to 'web/src')
| -rw-r--r-- | web/src/App.tsx | 17 | ||||
| -rw-r--r-- | web/src/components/EndScreen.tsx | 43 | ||||
| -rw-r--r-- | web/src/components/MainMenu.tsx | 39 | ||||
| -rw-r--r-- | web/src/components/TypingGame.tsx | 29 | ||||
| -rw-r--r-- | web/src/hooks/useCoreGame.ts | 17 | ||||
| -rw-r--r-- | web/src/styles.css | 65 |
6 files changed, 121 insertions, 89 deletions
diff --git a/web/src/App.tsx b/web/src/App.tsx index b34c4b4..9b266d9 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -108,7 +108,10 @@ function App() { const { game, resetGame, cleanupGame } = useCoreGame(); const [allTexts, setAllTexts] = useState<TextItem[]>(LOCAL_TEXTS); const [categories, setCategories] = useState<string[]>(uniqueCategories(LOCAL_TEXTS)); - const [selectedCategory, setSelectedCategory] = useState<string>('random'); + const [selectedCategory, setSelectedCategory] = useState<string>(() => { + const saved = localStorage.getItem('typerpunk:last_mode'); + return saved || 'random'; + }); const [gameState, setGameState] = useState<GameState>({ screen: 'main-menu', currentText: '', @@ -140,12 +143,7 @@ function App() { })); const testText = "This is a test sentence for the end screen. It has some text to display and check for errors."; const testUserInput = "This is a test sentance for the end screen. It has sone text to display and check for erors."; - const _testCharTimings = testText.split('').map((char, i) => ({ - time: (i / testText.length) * 60, - isCorrect: char === (testUserInput[i] || ''), - char: char, - index: i - })); + // removed unused _testCharTimings const [lastTest, setLastTest] = useState<{ stats: Stats; wpmHistory: Array<{ time: number; wpm: number; raw: number; isError: boolean }>; text: string; userInput: string; charTimings?: Array<{ time: number; isCorrect: boolean; char: string; index: number }>; keypressHistory?: Array<{ time: number; index: number; isCorrect: boolean }> } | null>(null); // Removed unused Enter key end-screen toggle handler @@ -167,6 +165,10 @@ function App() { })(); }, []); + useEffect(() => { + try { localStorage.setItem('typerpunk:last_mode', selectedCategory); } catch {} + }, [selectedCategory]); + const handleStartGame = async () => { try { // Reset game state first @@ -402,6 +404,7 @@ function App() { categories={categories} selectedCategory={selectedCategory} onSelectCategory={setSelectedCategory} + startLabel={`Start: ${selectedCategory === 'random' ? 'Random' : selectedCategory.charAt(0).toUpperCase() + selectedCategory.slice(1)}`} /> ) : gameState.screen === 'end-screen' ? ( <EndScreen diff --git a/web/src/components/EndScreen.tsx b/web/src/components/EndScreen.tsx index 3c70e95..9b1d7ab 100644 --- a/web/src/components/EndScreen.tsx +++ b/web/src/components/EndScreen.tsx @@ -492,7 +492,7 @@ export const EndScreen: FC<Props> = ({ stats, wpmHistory, onPlayAgain, onMainMen }; // --- Layout --- return ( - <div className="end-screen" style={{ maxWidth: 900, margin: '0 auto', padding: '2rem 1rem', minHeight: '100vh', position: 'relative', display: 'flex', flexDirection: 'column', alignItems: 'center', height: '100vh', boxSizing: 'border-box', overflow: 'hidden' }}> + <div className="end-screen" style={{ maxWidth: 900, margin: '0 auto', minHeight: '100vh', position: 'relative', display: 'flex', flexDirection: 'column', alignItems: 'center', height: '100vh', boxSizing: 'border-box', overflow: 'hidden' }}> {/* Logo at top, same as TypingGame */} <div className="logo" onClick={onMainMenu}>TyperPunk</div> {/* Main content area, all in one flex column, no fixed elements */} @@ -507,7 +507,7 @@ export const EndScreen: FC<Props> = ({ stats, wpmHistory, onPlayAgain, onMainMen boxSizing: 'border-box', }}> {/* Text */} - <div className="end-screen-text" style={{ margin: '0 auto 1.5rem auto', fontSize: '1.25rem', lineHeight: 1.7, maxWidth: 700, width: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative', background: 'rgba(0,0,0,0.04)', borderRadius: 6, padding: '1rem 1.5rem', textAlign: 'left', wordBreak: 'break-word', height: 'auto' }}> + <div className="end-screen-text" style={{ fontSize: '1.25rem', lineHeight: 1.7, maxWidth: 700, width: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative', background: 'rgba(0,0,0,0.04)', borderRadius: 6, padding: '1rem 1.5rem', textAlign: 'left', wordBreak: 'break-word', height: 'auto' }}> <div className="text-display" style={{ whiteSpace: 'pre-wrap', textAlign: 'left', width: '100%' }}>{renderText()}</div> </div> {/* Desktop: WPM | Graph | ACC */} @@ -540,6 +540,45 @@ export const EndScreen: FC<Props> = ({ stats, wpmHistory, onPlayAgain, onMainMen </div> </div> )} + {/* Transparent theme toggle (no class to avoid inherited styles) */} + <button + onClick={toggleTheme} + style={{ + position: 'fixed', + top: '1rem', + right: '1rem', + background: 'transparent', + border: 'none', + boxShadow: 'none', + outline: 'none', + backdropFilter: 'none', + WebkitBackdropFilter: 'none', + appearance: 'none', + WebkitAppearance: 'none', + MozAppearance: 'none', + padding: 0, + margin: 0, + borderRadius: 0, + }} + > + {theme === Theme.Dark ? ( + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"> + <circle cx="12" cy="12" r="5"/> + <line x1="12" y1="1" x2="12" y2="3"/> + <line x1="12" y1="21" x2="12" y2="23"/> + <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/> + <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/> + <line x1="1" y1="12" x2="3" y2="12"/> + <line x1="21" y1="12" x2="23" y2="12"/> + <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/> + <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/> + </svg> + ) : ( + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"> + <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/> + </svg> + )} + </button> {/* TIME stat below graph */} <div className="stat-label" style={{ fontSize: '0.8rem', color: 'var(--neutral-color)', textAlign: 'center', width: '100%', marginTop: 12 }}>TIME</div> <div className="stat-value" style={{ color: '#00ff9d', fontSize: '2.5rem', fontWeight: 700, letterSpacing: '0.05em', lineHeight: 1.1, textAlign: 'center', width: '100%' }}>{stats.time.toFixed(1)}</div> diff --git a/web/src/components/MainMenu.tsx b/web/src/components/MainMenu.tsx index b8daea0..fc80039 100644 --- a/web/src/components/MainMenu.tsx +++ b/web/src/components/MainMenu.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { useTheme } from '../contexts/ThemeContext'; import { Theme } from '../types'; @@ -11,33 +11,28 @@ interface Props { const MainMenu: React.FC<Props> = ({ onStartGame, categories = [], selectedCategory = 'random', onSelectCategory }) => { const { theme, toggleTheme } = useTheme(); + const modes = useMemo(() => ['random', ...categories], [categories]); + const currentIndex = Math.max(0, modes.findIndex(m => (selectedCategory || 'random') === m)); + const currentMode = modes[currentIndex] || 'random'; + const nextMode = modes[(currentIndex + 1) % modes.length] || 'random'; return ( <div className="main-menu"> - <h1>TyperPunk</h1> - <div className="menu-options"> - <div style={{ marginBottom: '0.75rem' }}> - <label htmlFor="category" style={{ marginRight: 8 }}>Category:</label> - <select - id="category" - value={selectedCategory} - onChange={(e) => onSelectCategory && onSelectCategory(e.target.value)} - style={{ padding: '0.4rem 0.6rem' }} - > - <option value="random">Random</option> - {categories.map((c) => ( - <option key={c} value={c}>{c}</option> - ))} - </select> - </div> - <button className="menu-button" onClick={onStartGame}> - Start Typing Test + <h1 style={{ marginTop: '-0.25rem', marginBottom: '0.8rem' }}>TyperPunk</h1> + <div className="menu-options" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '0.6rem' }}> + <button className="menu-button" onClick={onStartGame} style={{ width: 220, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>Start</button> + <button + className="menu-button" + onClick={() => onSelectCategory && onSelectCategory(nextMode)} + style={{ width: 220, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }} + > + {`Mode: ${currentMode === 'random' ? 'Random' : currentMode.charAt(0).toUpperCase() + currentMode.slice(1)}`} </button> - <button className="menu-button" onClick={toggleTheme}> - Toggle {theme === Theme.Dark ? 'Light' : 'Dark'} Mode + <button className="menu-button" onClick={toggleTheme} style={{ width: 220, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}> + Toggle Theme </button> </div> - <button onClick={toggleTheme} className="theme-toggle"> + <button onClick={toggleTheme} className="theme-toggle" style={{ background: 'transparent', border: 'none', boxShadow: 'none', backdropFilter: 'none' }}> {theme === Theme.Dark ? ( <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"> <circle cx="12" cy="12" r="5"/> diff --git a/web/src/components/TypingGame.tsx b/web/src/components/TypingGame.tsx index d815420..7d79c24 100644 --- a/web/src/components/TypingGame.tsx +++ b/web/src/components/TypingGame.tsx @@ -52,7 +52,7 @@ export const TypingGame: React.FC<Props> = React.memo((props: Props): JSX.Elemen const [localInput, setLocalInput] = useState<string>(''); const inputRef = useRef<HTMLInputElement>(null); const [wasmAccuracy, setWasmAccuracy] = useState<number>(100); - const [wasmMistakes, setWasmMistakes] = useState<number>(0); + const [_wasmMistakes, setWasmMistakes] = useState<number>(0); const gameRef = useRef(game); const isInitialized = useRef(false); const lastInputRef = useRef(''); @@ -63,7 +63,7 @@ export const TypingGame: React.FC<Props> = React.memo((props: Props): JSX.Elemen const [finalCharTimings, setFinalCharTimings] = useState<Array<{ time: number; isCorrect: boolean; char: string; index: number }>>([]); // Persistent mistake tracking const [allMistakes, setAllMistakes] = useState<Array<{ time: number; index: number }>>([]); - const [finalAllMistakes, setFinalAllMistakes] = useState<Array<{ time: number; index: number }>>([]); + const [_finalAllMistakes, setFinalAllMistakes] = useState<Array<{ time: number; index: number }>>([]); // Persistent keypress history tracking const [keypressHistory, setKeypressHistory] = useState<Array<{ time: number, index: number, isCorrect: boolean }>>([]); const [finalKeypressHistory, setFinalKeypressHistory] = useState<Array<{ time: number, index: number, isCorrect: boolean }>>([]); @@ -164,7 +164,7 @@ export const TypingGame: React.FC<Props> = React.memo((props: Props): JSX.Elemen // Track error positions for this input let isError = false; if (typeof game.get_stats_and_input === 'function') { - const [wasmInput, accuracy, mistakes] = game.get_stats_and_input(); + const [, , mistakes] = game.get_stats_and_input(); // If mistakes increased, mark as error if (mistakes > 0) isError = true; } @@ -504,7 +504,7 @@ export const TypingGame: React.FC<Props> = React.memo((props: Props): JSX.Elemen /> </div> {attribution && ( - <div style={{ maxWidth: 700, width: '100%', margin: '0 auto 1.5rem auto', textAlign: 'right', color: 'var(--neutral-color)', fontSize: '0.9rem' }}> + <div style={{ maxWidth: 700, width: '100%', margin: '0.5rem auto 1.75rem auto', textAlign: 'center', color: 'var(--neutral-color)', fontSize: '0.95rem' }}> — {attribution} </div> )} @@ -527,7 +527,7 @@ export const TypingGame: React.FC<Props> = React.memo((props: Props): JSX.Elemen </div> {/* Graph center, take all available space with margin for stats */} <div style={{ margin: '0 auto 1.5rem auto', width: '100%', maxWidth: 900, display: 'flex', flexDirection: 'column', alignItems: 'center', minWidth: 0 }}> - <div className="graph-container" style={{ flex: '1 1 0', minWidth: 0, width: '100%', maxWidth: '100%', maxHeight: 220, minHeight: 220, height: 220, margin: '0 auto', position: 'relative', background: 'rgba(0,0,0,0.02)', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden' }} /> + <div className="graph-container" style={{ flex: '1 1 0', minWidth: 0, width: '100%', maxWidth: '100%', maxHeight: 160, minHeight: 160, height: 160, margin: '0 auto', position: 'relative', background: 'rgba(0,0,0,0.02)', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden' }} /> {/* TIME stat below graph */} <div className="stat-label" style={{ fontSize: '0.8rem', color: 'var(--neutral-color)', textAlign: 'center', width: '100%', marginTop: 12 }}>TIME</div> <div className="stat-value" style={{ color: '#00ff9d', fontSize: '2.5rem', fontWeight: 700, letterSpacing: '0.05em', lineHeight: 1.1, textAlign: 'center', width: '100%' }}>{stats.time.toFixed(1)}</div> @@ -537,36 +537,37 @@ export const TypingGame: React.FC<Props> = React.memo((props: Props): JSX.Elemen {/* Mobile: Graph at top, then WPM & ACC in a row, then TIME below */} {isMobileScreen && ( <> - <div className="graph-container" style={{ flex: 'none', minWidth: 0, width: '100%', maxWidth: '100%', maxHeight: 220, minHeight: 220, height: 220, margin: '0 auto 0.5rem auto', position: 'relative', background: 'rgba(0,0,0,0.02)', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden' }} /> + <div className="graph-container" style={{ flex: 'none', minWidth: 0, width: '100%', maxWidth: '100%', maxHeight: 220, minHeight: 220, height: 220, margin: '0 auto 0.35rem auto', position: 'relative', background: 'rgba(0,0,0,0.02)', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden' }} /> <div className="end-screen-stats" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', alignItems: 'center', width: '100%', maxWidth: 700, - margin: '0.5rem auto 0.2rem auto', - gap: '0.3rem', + margin: '0.35rem auto 0.15rem auto', + padding: '0 0.6rem', + gap: '0.2rem', }}> - {/* WPM (left) */} - <div className="end-screen-stat wpm" style={{ textAlign: 'left', alignItems: 'flex-start', justifyContent: 'center' }}> + {/* WPM (left, close to edge) */} + <div className="end-screen-stat wpm" style={{ textAlign: 'left', alignItems: 'flex-start', justifyContent: 'center', paddingLeft: '0.2rem' }}> <div className="stat-label" style={{ textAlign: 'left', width: '100%' }}>WPM</div> <div className="stat-value" style={{ color: '#00ff9d', fontSize: '1.5rem', fontWeight: 700, letterSpacing: '0.05em', lineHeight: 1.1, textAlign: 'left', width: '100%' }}>{Math.round(stats.wpm)}</div> </div> - {/* ACC (right) */} - <div className="end-screen-stat acc" style={{ textAlign: 'right', alignItems: 'flex-end', justifyContent: 'center' }}> + {/* ACC (right, close to edge) */} + <div className="end-screen-stat acc" style={{ textAlign: 'right', alignItems: 'flex-end', justifyContent: 'center', paddingRight: '0.2rem' }}> <div className="stat-label" style={{ textAlign: 'right', width: '100%' }}>ACC</div> <div className="stat-value" style={{ color: '#00ff9d', fontSize: '1.5rem', fontWeight: 700, letterSpacing: '0.05em', lineHeight: 1.1, textAlign: 'right', width: '100%' }}>{Math.round(wasmAccuracy)}%</div> </div> </div> {/* TIME stat below WPM/ACC */} - <div className="stat-label" style={{ fontSize: '0.8rem', color: 'var(--neutral-color)', textAlign: 'center', width: '100%', marginTop: 8 }}>TIME</div> + <div className="stat-label" style={{ fontSize: '0.8rem', color: 'var(--neutral-color)', textAlign: 'center', width: '100%', marginTop: 12 }}>TIME</div> <div className="stat-value" style={{ color: '#00ff9d', fontSize: '1.5rem', fontWeight: 700, letterSpacing: '0.05em', lineHeight: 1.1, textAlign: 'center', width: '100%' }}>{stats.time.toFixed(1)}</div> </> )} </div> {/* Empty space for future game modes, matches EndScreen */} <div className="future-modes-placeholder" /> - <button onClick={toggleTheme} className="theme-toggle"> + <button onClick={toggleTheme} className="theme-toggle" style={{ background: 'transparent', border: 'none', boxShadow: 'none', backdropFilter: 'none' }}> {theme === Theme.Dark ? ( <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"> <circle cx="12" cy="12" r="5"/> diff --git a/web/src/hooks/useCoreGame.ts b/web/src/hooks/useCoreGame.ts index 3aa69ec..7e0b287 100644 --- a/web/src/hooks/useCoreGame.ts +++ b/web/src/hooks/useCoreGame.ts @@ -42,14 +42,8 @@ export function useCoreGame() { }, []); const resetGame = async () => { - if (gameRef.current) { - try { - gameRef.current.free(); - } catch (err) { - console.error('Error freeing old game:', err); - } - } - + // Do NOT free() here to avoid freeing while React components may still reference it. + // Create a fresh instance and replace the ref. try { const game = new Game(); gameRef.current = game; @@ -60,14 +54,15 @@ export function useCoreGame() { }; const cleanupGame = () => { - if (gameRef.current) { + const inst = gameRef.current; + if (inst) { try { - gameRef.current.free(); + inst.free(); } catch (err) { console.error('Error cleaning up game:', err); } - gameRef.current = null; } + gameRef.current = null; }; return { diff --git a/web/src/styles.css b/web/src/styles.css index d9130b4..5eb97eb 100644 --- a/web/src/styles.css +++ b/web/src/styles.css @@ -12,6 +12,8 @@ --neutral-color: #646669; --caret-color: #00ff9d; --sub-color: #646669; + --header-offset: 3.5rem; + --app-padding: 1rem; } [data-theme="light"] { @@ -58,9 +60,9 @@ body { display: flex; flex-direction: column; align-items: center; - justify-content: center; + justify-content: flex-start; /* avoid vertical centering that pushes content down */ height: 100vh; - padding: 1rem; + padding: var(--app-padding); overflow: hidden; } @@ -145,7 +147,7 @@ body { max-width: 800px; margin: 0 auto; padding: 1rem 2rem 0 2rem; - margin-top: 2.5rem; + margin-top: var(--header-offset); /* unified: just below header/toggle */ display: flex; justify-content: center; align-items: flex-start; @@ -227,37 +229,40 @@ body { position: fixed; top: 1rem; right: 1rem; - background: rgba(255,255,255,0.08); + background: transparent !important; border: none !important; outline: none !important; - box-shadow: 0 2px 12px 0 rgba(0,0,0,0.12), 0 1.5px 4px 0 rgba(0,0,0,0.10); + box-shadow: none !important; color: var(--primary-color); - padding: 0.7rem 1rem; + padding: 0; font-size: 1.2rem; cursor: pointer; - transition: all 0.2s cubic-bezier(.4,0,.2,1); + transition: color 0.2s ease; display: flex; align-items: center; gap: 0.5rem; z-index: 100; - border-radius: 1.5rem; - backdrop-filter: blur(8px); - -webkit-backdrop-filter: blur(8px); + border-radius: 0; + backdrop-filter: none !important; + -webkit-backdrop-filter: none !important; + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; } .theme-toggle:focus, .theme-toggle:active { border: none !important; outline: none !important; - box-shadow: 0 4px 16px 0 rgba(0,0,0,0.18); - background: rgba(255,255,255,0.16); + box-shadow: none !important; + background: transparent !important; } .theme-toggle:hover { color: var(--secondary-color); - background: rgba(255,255,255,0.18); - box-shadow: 0 6px 24px 0 rgba(0,0,0,0.18); - transform: scale(1.06); + background: transparent !important; + box-shadow: none !important; + transform: none; } .theme-toggle svg { @@ -291,7 +296,7 @@ body { .text-container { padding: 1rem; - margin-top: 5rem; + margin-top: var(--header-offset); } .stats-container { @@ -403,7 +408,7 @@ body { } .text-container { padding: 0.5rem 0.5rem 0 0.5rem; - margin-top: 1.5rem; + margin-top: var(--header-offset); min-width: 0; } .text-display { @@ -446,8 +451,8 @@ body { width: 100%; max-width: 800px; margin: 0 auto; - padding: 2rem; - padding-top: 6rem; + padding: 0.25rem; + margin-top: calc(var(--header-offset) - var(--app-padding)); /* match .text-container exactly */ min-height: 100vh; position: relative; } @@ -683,7 +688,7 @@ body::-webkit-scrollbar, .app::-webkit-scrollbar, #root::-webkit-scrollbar { .end-screen-text { width: 100%; max-width: 800px; - margin: 0 auto 2rem auto; + margin: 0 auto 0.5rem auto; font-family: 'JetBrains Mono', monospace; font-size: 1.2rem; color: var(--text-color); @@ -728,7 +733,7 @@ body::-webkit-scrollbar, .app::-webkit-scrollbar, #root::-webkit-scrollbar { flex: 1 1 0; min-width: 0; margin: 0; - padding: 2rem 0; + padding: 1rem 0; height: 300px; position: relative; background: rgba(0,0,0,0.02); @@ -880,6 +885,9 @@ body::-webkit-scrollbar, .app::-webkit-scrollbar, #root::-webkit-scrollbar { } @media (max-width: 700px) { + :root { + --header-offset: 2.5rem; + } body, #root, .app, .end-screen { overflow-y: auto !important; overflow-x: hidden !important; @@ -887,7 +895,8 @@ body::-webkit-scrollbar, .app::-webkit-scrollbar, #root::-webkit-scrollbar { .end-screen { min-height: 0 !important; height: auto !important; - padding-top: 1.5rem !important; + padding: 0.5rem 0.75rem !important; + padding-top: var(--header-offset) !important; /* align with game text */ padding-bottom: 0.5rem !important; display: flex !important; flex-direction: column !important; @@ -895,16 +904,6 @@ body::-webkit-scrollbar, .app::-webkit-scrollbar, #root::-webkit-scrollbar { .end-screen-buttons { margin-top: auto !important; margin-bottom: 0 !important; - } - .end-screen-main-content { - flex: 1 0 auto !important; width: 100% !important; - display: flex !important; - flex-direction: column !important; } - .end-screen-buttons { - margin-top: auto !important; - margin-bottom: 0 !important; - width: 100% !important; - } -}
\ No newline at end of file +} |
