fix(ui): keep mobile onboarding and login usable
Hide the dead composer during birth-time intake, replace internal copy with user-facing hints, and keep short-screen login, location search, and session history reachable on phones.
This commit is contained in:
@@ -274,8 +274,9 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
@media (max-width: 767px) {
|
||||
.brand-row { padding: 0 4px; }
|
||||
.brand-mark { width: 26px; height: 26px; }
|
||||
.session-nav { overflow: hidden; }
|
||||
.session-nav { overflow: visible; }
|
||||
.session-list { overflow-x: clip; }
|
||||
[data-sidebar="content"] { -webkit-overflow-scrolling: touch; }
|
||||
.chat-header > div { min-width: 0; flex: 1; }
|
||||
.chat-header strong { max-width: 100%; }
|
||||
.onboarding-card { padding: 16px; }
|
||||
@@ -294,8 +295,7 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
.profile-grid, .location-grid, .code-form { grid-template-columns: 1fr; }
|
||||
.code-form .note-field { grid-column: auto; }
|
||||
.code-form .button-primary { width: 100%; }
|
||||
.auth-page { padding: 16px; }
|
||||
.auth-brand { margin-bottom: 32px; }
|
||||
.auth-brand { margin-bottom: var(--space-6); }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
@@ -825,8 +825,8 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
.synastry-history-item { display: grid; gap: 3px; padding: var(--space-3); border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-canvas); color: var(--color-ink); text-align: left; }
|
||||
.synastry-history-item small { color: var(--color-ink-secondary); font-size: var(--type-caption); }
|
||||
|
||||
input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input), select:not([class^="ant-"]):not([class*=" ant-"]) { width: 100%; min-height: 44px; padding: 0 12px; border: 1px solid var(--color-border-strong); color: var(--color-ink); border-color: var(--color-border-strong); border-radius: var(--radius-md); background: var(--color-canvas); font-size: 14px; }
|
||||
input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled, select:not([class^="ant-"]):not([class*=" ant-"]):disabled { color: var(--color-ink-tertiary); background: var(--color-canvas-muted); }
|
||||
input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input), select:not([class^="ant-"]):not([class*=" ant-"]) { width: 100%; min-height: 44px; padding: 0 12px; border: 1px solid var(--color-border-strong); color: var(--color-ink); border-color: var(--color-border-strong); border-radius: var(--radius-md); background: var(--color-canvas); font-size: 14px; }
|
||||
input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled, select:not([class^="ant-"]):not([class*=" ant-"]):disabled { color: var(--color-ink-tertiary); background: var(--color-canvas-muted); }
|
||||
.button-primary, .button-secondary { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0 15px; border: 1px solid var(--color-action); cursor: pointer; text-decoration: none; transition: background-color 120ms ease-out, color 120ms ease-out, transform 120ms ease-out; border-radius: var(--radius-md); font-size: 14px; font-weight: 500; }
|
||||
.button-primary { border-color: var(--color-action); background: var(--color-action); color: var(--color-on-dark); }
|
||||
.button-secondary { border-color: var(--color-border-strong); background: var(--color-canvas); color: var(--color-ink); }
|
||||
@@ -925,17 +925,19 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled
|
||||
.message-list { width: 100%; padding: var(--space-5) var(--space-4) var(--space-12); }
|
||||
.message-content { max-width: 88%; }
|
||||
.composer-wrap { padding: var(--space-2) var(--space-3) max(var(--space-3), env(safe-area-inset-bottom)); }
|
||||
:root { --composer-reserve: 116px; }
|
||||
.location-combobox-results { position: static; top: auto; max-height: min(240px, 42dvh); margin-top: var(--space-2); box-shadow: none; }
|
||||
.account-modal { max-height: calc(100dvh - var(--space-8)); padding: var(--space-6); }
|
||||
.profile-modal .account-modal-header { margin: calc(var(--space-6) * -1) calc(var(--space-6) * -1) var(--space-4); padding: var(--space-6) var(--space-6) var(--space-4); }
|
||||
.avatar-editor { grid-template-columns: 72px minmax(0, 1fr); gap: var(--space-4); }
|
||||
.avatar-editor > .user-avatar { width: 72px !important; height: 72px !important; }
|
||||
.avatar-palette-list { grid-template-columns: repeat(2, minmax(64px, 1fr)); }
|
||||
.auth-page { padding: 0; }
|
||||
.auth-shell { min-height: 100dvh; grid-template-columns: 1fr; grid-template-rows: auto 1fr; border-radius: 0; box-shadow: none; }
|
||||
.auth-story { min-height: 248px; padding: var(--space-8) var(--space-6); }
|
||||
.auth-page { height: 100dvh; overflow-x: hidden; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 0; }
|
||||
.auth-shell { min-height: 100%; overflow: visible; align-content: start; grid-template-columns: 1fr; grid-template-rows: auto auto; border-radius: 0; box-shadow: none; }
|
||||
.auth-story { min-height: 0; justify-content: flex-start; gap: var(--space-3); padding: var(--space-6) var(--space-6) var(--space-5); }
|
||||
.auth-story h2 { max-width: 560px; margin: var(--space-3) 0 0; font-size: var(--type-display-sm); }
|
||||
.auth-story > div > p, .auth-footnote { display: none; }
|
||||
.auth-panel { padding: var(--space-8) var(--space-6); }
|
||||
.auth-panel { justify-content: flex-start; padding: var(--space-8) var(--space-6) max(var(--space-8), env(safe-area-inset-bottom)); }
|
||||
.auth-panel h1 { font-size: var(--type-display-md); }
|
||||
.admin-header { padding: 0 var(--space-4); }
|
||||
.admin-scroll { padding: var(--space-6) var(--space-4) var(--space-12); }
|
||||
@@ -959,15 +961,20 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled
|
||||
.paywall-footer > a, .paywall-footer > button { width: 100%; }
|
||||
.dialog-actions { flex-direction: column-reverse; }
|
||||
.dialog-actions > button { width: 100%; }
|
||||
.auth-story { min-height: 220px; padding: var(--space-6) var(--space-5); }
|
||||
.auth-story h2 { font-size: var(--type-display-sm); }
|
||||
.auth-panel { padding: var(--space-8) var(--space-5); }
|
||||
.auth-story { min-height: 0; padding: var(--space-5); }
|
||||
.auth-story h2 { font-size: var(--type-title-lg); }
|
||||
.auth-panel { padding: var(--space-6) var(--space-5) max(var(--space-6), env(safe-area-inset-bottom)); }
|
||||
.auth-panel h1 { font-size: var(--type-display-sm); }
|
||||
.admin-section { padding: var(--space-5); }
|
||||
}
|
||||
.session-delete-overlay { z-index: 100; }
|
||||
.session-delete-confirmation p { margin: 0; color: var(--color-ink-secondary); }
|
||||
|
||||
@media (max-width: 767px) and (max-height: 640px) {
|
||||
.auth-story { display: none; }
|
||||
.auth-brand { display: flex; margin-bottom: var(--space-6); }
|
||||
}
|
||||
|
||||
@media (max-width: 430px) {
|
||||
[data-sonner-toaster] { right: var(--space-4) !important; left: var(--space-4) !important; width: auto !important; }
|
||||
.conversational-rectification { width: 100%; max-width: 100%; gap: var(--space-4); overflow-x: clip; }
|
||||
@@ -1571,18 +1578,36 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled
|
||||
.onboarding-card-heading b { font-size: clamp(22px, 2.6vw, 30px); letter-spacing: -.03em; }
|
||||
.onboarding-card-heading small { max-width: 260px; color: var(--color-ink-secondary); line-height: 1.55; font-size: var(--type-caption); text-wrap: pretty; }
|
||||
.birth-time-intake { gap: var(--space-6); }
|
||||
.conversation.is-onboarding-form { align-content: start; padding-bottom: var(--space-8); }
|
||||
.conversation.is-onboarding-form .welcome { padding-top: var(--space-6); padding-bottom: var(--space-8); }
|
||||
.conversation.is-onboarding-form .welcome > .onboarding-message:first-child { padding-bottom: var(--space-3); }
|
||||
.conversation.is-onboarding-form .welcome > .onboarding-message:first-child .message-bubble p {
|
||||
max-width: 680px;
|
||||
font-size: var(--type-title-md);
|
||||
letter-spacing: -.2px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.birth-time-source-fieldset { padding-top: var(--space-5); border-top: 1px solid var(--color-border); }
|
||||
.birth-time-source-fieldset legend { margin-bottom: 5px; color: var(--color-ink); font-size: var(--type-title-sm); font-weight: 700; }
|
||||
.birth-time-source-fieldset legend {
|
||||
display: block;
|
||||
float: none;
|
||||
width: 100%;
|
||||
margin: 0 0 5px;
|
||||
padding: 0;
|
||||
color: var(--color-ink);
|
||||
font-size: var(--type-title-sm);
|
||||
font-weight: 700;
|
||||
}
|
||||
.birth-time-source-intro { margin: 0 0 var(--space-3); color: var(--color-ink-secondary); font-size: var(--type-caption); line-height: 1.55; }
|
||||
.birth-time-source-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
|
||||
.birth-time-source-option { min-height: 118px; grid-template-columns: 20px minmax(0, 1fr); align-items: start; gap: var(--space-3); padding: 18px; border-color: var(--color-border); border-radius: var(--radius-md); background: var(--color-canvas-soft); transition: border-color 160ms ease-out, background-color 160ms ease-out; }
|
||||
.birth-time-source-list { grid-template-columns: 1fr; gap: var(--space-2); }
|
||||
.birth-time-source-option { min-height: 64px; grid-template-columns: 18px minmax(0, 1fr); align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-color: var(--color-border); border-radius: var(--radius-md); background: var(--color-canvas); transition: border-color 160ms ease-out, background-color 160ms ease-out; }
|
||||
.birth-time-source-option:hover { border-color: color-mix(in srgb, var(--color-action) 44%, var(--color-border)); }
|
||||
.birth-time-source-option.is-selected { border-color: var(--color-action); background: var(--color-action-soft); box-shadow: inset 0 0 0 1px var(--color-action); }
|
||||
.birth-time-source-option input { appearance: none; position: relative; width: 16px; min-width: 16px; height: 16px; min-height: 16px; margin: 3px 0 0; border: 1.5px solid var(--color-border-strong); border-radius: 50%; background: var(--color-canvas); }
|
||||
.birth-time-source-option input { appearance: none; align-self: center; justify-self: center; position: static; box-sizing: border-box; width: 16px; min-width: 16px; max-width: 16px; height: 16px; min-height: 16px; max-height: 16px; margin: 0; overflow: visible; clip: auto; clip-path: none; border: 1.5px solid var(--color-border-strong); border-radius: 50%; background: var(--color-canvas); }
|
||||
.birth-time-source-option input:checked { border-color: var(--color-action); background: var(--color-action); box-shadow: inset 0 0 0 4px var(--color-action-soft); }
|
||||
.birth-time-source-option > span { gap: 7px; }
|
||||
.birth-time-source-option b { font-size: var(--type-title-sm); line-height: 1.3; }
|
||||
.birth-time-source-option small { font-size: var(--type-body-sm); line-height: 1.55; }
|
||||
.birth-time-source-option > span { gap: 4px; }
|
||||
.birth-time-source-option b { font-size: var(--type-body-sm); line-height: 1.35; }
|
||||
.birth-time-source-option small { font-size: var(--type-caption); line-height: 1.5; }
|
||||
.birth-time-detail-grid { grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: var(--space-3); padding: var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-canvas-soft); }
|
||||
.birth-time-period-details { align-items: start; }
|
||||
.birth-time-period-details > label { align-self: start; }
|
||||
@@ -1650,8 +1675,7 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled
|
||||
.select-item-indicator { display: inline-flex; flex: 0 0 auto; color: var(--color-action); }
|
||||
@keyframes select-content-in { from { opacity: 0; transform: translateY(-3px) scale(.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
|
||||
|
||||
.birth-time-source-option { grid-template-columns: minmax(0, 1fr); }
|
||||
.birth-time-source-option input { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
|
||||
.birth-time-source-option { grid-template-columns: 18px minmax(0, 1fr); }
|
||||
.birth-time-source-option:focus-within { border-color: var(--color-action); outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-action) 16%, transparent); }
|
||||
.birth-time-source-option.is-selected:focus-within { box-shadow: inset 0 0 0 1px var(--color-action), 0 0 0 3px color-mix(in srgb, var(--color-action) 16%, transparent); }
|
||||
.birth-time-source-option > span { min-width: 0; }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Metadata } from "next";
|
||||
import type { Metadata, Viewport } from "next";
|
||||
import Script from "next/script";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import "./globals.css";
|
||||
@@ -9,6 +9,13 @@ export const metadata: Metadata = {
|
||||
description: "与 Mastra Agent 对话,基于星盘证据讨论事业、关系与时间窗口。",
|
||||
};
|
||||
|
||||
export const viewport: Viewport = {
|
||||
width: "device-width",
|
||||
initialScale: 1,
|
||||
viewportFit: "cover",
|
||||
interactiveWidget: "resizes-content",
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
|
||||
const enableReactDevTools = process.env.NODE_ENV === "development"
|
||||
&& process.env.NEXT_PUBLIC_ENABLE_REACT_DEVTOOLS === "1";
|
||||
|
||||
@@ -52,6 +52,7 @@ import {
|
||||
describeBirthTimeDraft,
|
||||
isDeclaredBirthProfileComplete,
|
||||
isBirthTimeDraftReady,
|
||||
birthTimeDraftReadyHint,
|
||||
normalizePersistedBirthDate,
|
||||
type BirthTimeDraft,
|
||||
type BirthTimeSource,
|
||||
@@ -1255,6 +1256,8 @@ export default function Home() {
|
||||
&& !onboardingPending
|
||||
&& !rectificationSurfaceOpen
|
||||
&& !activeSession?.messages.length;
|
||||
const onboardingFormActive = !profileComplete && onboardingStep !== "name";
|
||||
const birthTimeContinueHint = onboardingStep === "birth" ? birthTimeDraftReadyHint(profileDraft) : "";
|
||||
const daypartGreeting = greetingForHour(new Date().getHours());
|
||||
|
||||
function restoreConsultationRecovery(session: ChatSession, requestId: string) {
|
||||
@@ -3257,7 +3260,7 @@ export default function Home() {
|
||||
</header>
|
||||
|
||||
{!rectificationSurfaceOpen && (
|
||||
<div ref={conversation} className={`conversation ${activeSession?.messages.length ? "" : "is-empty"}`}>
|
||||
<div ref={conversation} className={`conversation ${!activeSession?.messages.length && !onboardingFormActive ? "is-empty" : ""} ${onboardingFormActive ? "is-onboarding-form" : ""}`}>
|
||||
{!activeSession?.messages.length ? (
|
||||
<div className="welcome">
|
||||
{!profileComplete ? (
|
||||
@@ -3287,6 +3290,7 @@ export default function Home() {
|
||||
<BirthTimeIntakeFields value={profileDraft} onPatch={(patch) => setProfileDraft((current) => applyBirthTimeDraftPatch(current, patch))} />
|
||||
{accountError && <p className="form-error" role="alert">{accountError}</p>}
|
||||
<div className="onboarding-card-actions">
|
||||
{birthTimeContinueHint ? <p className="onboarding-card-action-hint">{birthTimeContinueHint}</p> : <span />}
|
||||
<button className="button-primary" type="submit" disabled={profileSaving || !isBirthTimeDraftReady(profileDraft)}>{profileSaving ? "保存中" : "继续"}</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -3460,7 +3464,7 @@ export default function Home() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{!rectificationSurfaceOpen && <div className={`composer-wrap ${starterHomeVisible ? "composer-wrap-starter" : ""}`}>
|
||||
{!rectificationSurfaceOpen && !onboardingFormActive && <div className={`composer-wrap ${starterHomeVisible ? "composer-wrap-starter" : ""}`}>
|
||||
{activeSuggestions.length > 0 && (
|
||||
<div className="composer-suggestions" aria-label="推荐继续提问">
|
||||
{activeSuggestions.map((question) => (
|
||||
|
||||
Reference in New Issue
Block a user