+
- {/* Title */}
-
- {pageTitle}
-
+
+ {/* Title */}
+
+ {pageTitle}
+
- {/* Server info row with separator */}
-
-
{t('Auth.homeserver')}
-
{server}
- {clientConfig.allowCustomHomeservers && (
-
+ {/* Server info row with separator */}
+
+ {t('Auth.homeserver')}
+ {server}
+ {clientConfig.allowCustomHomeservers && (
+
+ )}
+
+
+ {/* Loading / error / form */}
+ {discoveryState.status === AsyncStatus.Loading && (
+
+ )}
+ {discoveryState.status === AsyncStatus.Error && (
+
+ )}
+ {autoDiscoveryError?.action === AutoDiscoveryAction.FAIL_PROMPT && (
+
+ )}
+ {autoDiscoveryError?.action === AutoDiscoveryAction.FAIL_ERROR && (
+
+ )}
+ {discoveryState.status === AsyncStatus.Success && autoDiscoveryInfo && (
+
+
+ (
+
+ )}
+ error={() => (
+
+ )}
+ >
+ {(specVersions) => (
+
+ (
+
+ )}
+ error={() => }
+ >
+ {(authFlows) => (
+
+
+
+ )}
+
+
+ )}
+
+
+
)}
-
- {/* Loading / error / form */}
- {discoveryState.status === AsyncStatus.Loading && (
-
- )}
- {discoveryState.status === AsyncStatus.Error && (
-
- )}
- {autoDiscoveryError?.action === AutoDiscoveryAction.FAIL_PROMPT && (
-
- )}
- {autoDiscoveryError?.action === AutoDiscoveryAction.FAIL_ERROR && (
-
- )}
- {discoveryState.status === AsyncStatus.Success && autoDiscoveryInfo && (
-
-
- (
-
- )}
- error={() => (
-
- )}
- >
- {(specVersions) => (
-
- (
-
- )}
- error={() => (
-
- )}
- >
- {(authFlows) => (
-
-
-
- )}
-
-
- )}
-
-
-
- )}
diff --git a/src/app/pages/auth/styles.css.ts b/src/app/pages/auth/styles.css.ts
index 01039433..3b16ed95 100644
--- a/src/app/pages/auth/styles.css.ts
+++ b/src/app/pages/auth/styles.css.ts
@@ -108,14 +108,25 @@ export const AuthCard = style({
});
export const AuthCardContent = style({
- display: 'flex',
- flexDirection: 'column',
borderRadius: 'inherit',
backgroundColor: 'rgba(18, 19, 22, 0.55)',
backdropFilter: 'blur(22px) saturate(150%)',
WebkitBackdropFilter: 'blur(22px) saturate(150%)',
border: '1px solid rgba(255, 255, 255, 0.08)',
width: `min(${toRem(492)}, calc(100vw - 2rem))`,
+ boxSizing: 'border-box',
+ maxHeight: 'var(--vojo-modal-max-h)',
+ overflowY: 'hidden',
+});
+
+export const AuthCardContentScrollable = style({
+ overflowY: 'auto',
+ overscrollBehavior: 'contain',
+});
+
+export const AuthCardBody = style({
+ display: 'flex',
+ flexDirection: 'column',
padding: `${toRem(32)} ${toRem(40)}`,
boxSizing: 'border-box',
gap: toRem(20),
@@ -128,12 +139,6 @@ export const AuthCardContent = style({
},
});
-export const AuthCardContentConstrained = style({
- maxHeight: 'var(--vojo-modal-max-h)',
- overflowY: 'auto',
- overscrollBehavior: 'contain',
-});
-
/* ── Server info row ── */
export const ServerRow = style({
display: 'grid',
@@ -285,20 +290,6 @@ globalStyle(`${AuthCardContent} input::placeholder`, {
color: 'rgba(232, 228, 223, 0.35)',
});
-/*
- * Floor for input boxes when the modal is height-constrained (small screen
- * or on-screen keyboard). Natural input height is 3rem; floor at 2rem so
- * the keyboard can still squeeze the form to ~66% before hitting the stop.
- * Past the floor, flex can't compress further — the form overflows the
- * AuthLayout (overflow: hidden) and the bottom is covered by the keyboard.
- *
- * `:has(> input)` targets the folds Input's outer wrapper (the box that
- * flex-shrinks) rather than the native
. Excludes checkboxes.
- */
-globalStyle(`${AuthCardContent} div:has(> input:not([type="checkbox"]))`, {
- minHeight: toRem(48),
-});
-
/*
* Chromium's UA stylesheet paints a saved-credentials overlay on
* :-webkit-autofill inputs, forcing a light background and dark text. Without