fix(dashboard): mobile polish — single-row api key input, NewAgentDialog safe-area + scroll
ModelOnboardingModal: - API-key row was forced to flex-direction: column on mobile, stacking the input above the Save button and doubling the vertical space inside the already-cramped provider card. Switch to flex-direction: row with the input growing (flex: 1, left-aligned) and Save shrunk to its label (right-aligned). Tighten input/button min-height to 32px and shrink the button's inline padding. - Tighten surrounding form: gap → --space-xs, label font-size → 11px with no margin-bottom, helper paragraphs → 11px / line-height 1.35. NewAgentDialog: - Top of the dialog was cut off under the iOS notch / status bar. Added env(safe-area-inset-top) to the mobile header padding-top, and env(safe-area-inset-bottom) to the footer padding-bottom so the home indicator doesn't cover the action buttons. - Body wasn't scrolling because the flex child kept its default min-height: auto, making the dialog grow past the viewport and never trigger overflow-y: auto. Added min-height: 0 + flex: 1 1 auto on the body, and flex-shrink: 0 on the header/footer/steps so only the body gives up height. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1359,18 +1359,47 @@
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.onboarding-apikey-input {
|
/* Keep the API-key input and the Save button on a single row on mobile.
|
||||||
width: 100%;
|
Earlier rule stacked them (input above, button below), which doubled
|
||||||
min-height: 36px;
|
the vertical space inside an already-cramped provider card. The input
|
||||||
|
stays left-aligned and grows to fill the row, the Save button shrinks
|
||||||
|
to its label and pins to the right. */
|
||||||
|
.onboarding-apikey-input-row {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
.onboarding-apikey-input-row {
|
.onboarding-apikey-input {
|
||||||
flex-direction: column;
|
flex: 1 1 auto;
|
||||||
align-items: stretch;
|
width: auto;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.onboarding-apikey-input-row .btn {
|
.onboarding-apikey-input-row .btn {
|
||||||
min-height: 36px;
|
flex: 0 0 auto;
|
||||||
|
min-height: 32px;
|
||||||
|
/* Compact label so "Save" doesn't bloat the row. */
|
||||||
|
padding-inline: var(--space-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tighten the surrounding form so the row doesn't sit inside a tall
|
||||||
|
wrapper of label + input + footnote. */
|
||||||
|
.onboarding-apikey-form {
|
||||||
|
gap: var(--space-xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
.onboarding-apikey-field-label {
|
||||||
|
font-size: 11px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.onboarding-apikey-instructions,
|
||||||
|
.onboarding-apikey-usage {
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.35;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.onboarding-apikey-dashboard-link {
|
.onboarding-apikey-dashboard-link {
|
||||||
|
|||||||
@@ -561,10 +561,19 @@
|
|||||||
border-right: 0;
|
border-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tighter chrome leaves more room for the scrollable body. */
|
/* Tighter chrome leaves more room for the scrollable body. The header
|
||||||
.agent-dialog-header,
|
adds env(safe-area-inset-top) so the iOS notch / status bar doesn't
|
||||||
|
hide the title and close button. The footer mirrors that with
|
||||||
|
safe-area-inset-bottom so the home indicator doesn't sit on top of
|
||||||
|
the action buttons. */
|
||||||
|
.agent-dialog-header {
|
||||||
|
padding: calc(var(--space-md) + env(safe-area-inset-top)) var(--space-md)
|
||||||
|
var(--space-md);
|
||||||
|
}
|
||||||
|
|
||||||
.agent-dialog-footer {
|
.agent-dialog-footer {
|
||||||
padding: var(--space-md) var(--space-md);
|
padding: var(--space-md) var(--space-md)
|
||||||
|
calc(var(--space-md) + env(safe-area-inset-bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
.agent-dialog-steps {
|
.agent-dialog-steps {
|
||||||
@@ -573,12 +582,26 @@
|
|||||||
instead of overflowing the dialog. */
|
instead of overflowing the dialog. */
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header/footer must not shrink — only the body should give up height
|
||||||
|
to keep the chrome fixed and the body scrollable. */
|
||||||
|
.agent-dialog-header,
|
||||||
|
.agent-dialog-footer {
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.agent-dialog-body {
|
.agent-dialog-body {
|
||||||
padding: var(--space-md);
|
padding: var(--space-md);
|
||||||
/* Already overflow-y: auto, but lock the scroll inside the body so iOS
|
/* `min-height: 0` is required for `overflow-y: auto` to take effect
|
||||||
doesn't bubble it up to the page and trap the user above the footer. */
|
on a flex child — without it the body's intrinsic height grows to
|
||||||
|
its content, the dialog bleeds past the viewport, and scroll never
|
||||||
|
activates. This is the classic flex `min-height: auto` gotcha. */
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
/* Lock the scroll inside the body so iOS doesn't bubble it up to the
|
||||||
|
page and trap the user above the footer. */
|
||||||
overscroll-behavior: contain;
|
overscroll-behavior: contain;
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user