fix: improve Android tablet keyboard-safe layout
Use dynamic viewport sizing and keyboard-aware spacing to keep new-game inputs and navigation reachable in PWA landscape mode on Android tablets. Refs #30. Made-with: Cursor
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
min-height: var(--app-height);
|
||||
display: none;
|
||||
opacity: 0;
|
||||
transform: translateX(100%);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
.screen-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
min-height: var(--app-height);
|
||||
padding: var(--space-lg);
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
min-height: var(--app-height);
|
||||
display: none;
|
||||
opacity: 0;
|
||||
transform: translateX(100%);
|
||||
@@ -145,8 +145,10 @@
|
||||
|
||||
.form-content {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
padding: 0 var(--space-lg);
|
||||
padding-bottom: var(--space-md);
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -154,7 +156,12 @@
|
||||
|
||||
.form-footer {
|
||||
flex-shrink: 0;
|
||||
padding: var(--space-lg);
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
background: var(--color-surface);
|
||||
padding: var(--space-md) var(--space-lg) calc(var(--space-lg) + var(--keyboard-offset)) var(--space-lg);
|
||||
border-top: 1px solid var(--color-border);
|
||||
}
|
||||
.progress-indicator {
|
||||
display: flex;
|
||||
@@ -210,7 +217,7 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: var(--space-xxl);
|
||||
margin-top: var(--space-lg);
|
||||
width: 100%;
|
||||
gap: var(--space-lg);
|
||||
}
|
||||
|
||||
@@ -111,8 +111,15 @@ export const Player1Step = ({ playerNameHistory, onNext, onCancel, initialValue
|
||||
}
|
||||
}}
|
||||
autoComplete="off"
|
||||
autoCapitalize="words"
|
||||
spellCheck={false}
|
||||
enterKeyHint="next"
|
||||
aria-label="Name Spieler 1"
|
||||
aria-describedby="player1-help"
|
||||
onFocus={(e) => {
|
||||
const target = e.currentTarget as HTMLInputElement;
|
||||
target.scrollIntoView({ block: 'center', behavior: 'smooth' });
|
||||
}}
|
||||
style={{
|
||||
fontSize: UI_CONSTANTS.INPUT_FONT_SIZE,
|
||||
minHeight: UI_CONSTANTS.INPUT_MIN_HEIGHT,
|
||||
|
||||
@@ -70,7 +70,14 @@ export const Player2Step = ({ playerNameHistory, onNext, onCancel, initialValue
|
||||
setPlayer2(target.value);
|
||||
}}
|
||||
autoComplete="off"
|
||||
autoCapitalize="words"
|
||||
spellCheck={false}
|
||||
enterKeyHint="next"
|
||||
aria-label="Name Spieler 2"
|
||||
onFocus={(e) => {
|
||||
const target = e.currentTarget as HTMLInputElement;
|
||||
target.scrollIntoView({ block: 'center', behavior: 'smooth' });
|
||||
}}
|
||||
style={{ fontSize: '1.2rem', minHeight: 48, marginTop: 12, marginBottom: 12, width: '100%', paddingRight: 44 }}
|
||||
ref={inputRef}
|
||||
/>
|
||||
|
||||
@@ -67,7 +67,14 @@ export const Player3Step = ({ playerNameHistory, onNext, onCancel, initialValue
|
||||
setPlayer3(target.value);
|
||||
}}
|
||||
autoComplete="off"
|
||||
autoCapitalize="words"
|
||||
spellCheck={false}
|
||||
enterKeyHint="done"
|
||||
aria-label="Name Spieler 3"
|
||||
onFocus={(e) => {
|
||||
const target = e.currentTarget as HTMLInputElement;
|
||||
target.scrollIntoView({ block: 'center', behavior: 'smooth' });
|
||||
}}
|
||||
style={{ fontSize: '1.2rem', minHeight: 48, marginTop: 12, marginBottom: 12, width: '100%', paddingRight: 44 }}
|
||||
ref={inputRef}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user