fix(web): stack mobile audit tables and restore sidebar hierarchy
Narrow screens were wrapping 已执行 into a glyph column and painting every sidebar row the same gray, so history looked like top-level chrome. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+5
-3
@@ -142,6 +142,7 @@ The base unit is 4px. Tokens are `--space-1: 4px`, `--space-2: 8px`, `--space-3:
|
||||
|
||||
- **Structure:** title, optional metadata, current-state marker.
|
||||
- **States:** default, hover, current, focus, disabled.
|
||||
- **Hierarchy:** section labels stay tertiary; session titles and primary actions use ink so history rows do not collapse into the same gray as “收藏对话 / 历史对话”.
|
||||
- **Request behavior:** existing sessions remain selectable for reading while a request is active; creating or sending another request stays locked until the active request settles.
|
||||
- **Surface:** translucent warm-gray sidebar; current uses a white glass surface and deep-brown marker.
|
||||
|
||||
@@ -153,7 +154,7 @@ The base unit is 4px. Tokens are `--space-1: 4px`, `--space-2: 8px`, `--space-3:
|
||||
- **Tablet:** 64px collapsed by default from 768px through 1023px; 240px when expanded.
|
||||
- **Mobile:** no icon rail; an off-canvas drawer uses `min(86vw, 320px)` and closes through its scrim or Escape.
|
||||
- **Collapsed content:** logo, new-chat action, reports action, one history expansion action, and account avatar. Individual sessions do not become indistinguishable repeated icons.
|
||||
- **Expanded content:** new chat, my reports, chart list, favorites, then history. Empty untitled sessions stay off the history list. Pin is favorite; archive stays in the session menu.
|
||||
- **Expanded content:** new chat, my reports, chart list, favorites, then history. Nested lists indent under their section labels. Actions, section labels, and session rows share 18px icons, caption/body type, and ink/muted tokens. Empty untitled sessions stay off the history list. Pin is favorite; archive stays in the session menu, not as a history-header toggle.
|
||||
- **Scroll ownership:** header and footer remain fixed; `SidebarContent` is the sole sidebar scroll owner.
|
||||
- **Scrollbar:** `SidebarContent`, ordinary session `.conversation`, and the rectification house board use a quiet overlay scrollbar: transparent track, no `scrollbar-gutter`, and a 4px warm thumb mixed from `--color-ink`. The thumb stays transparent until hover or keyboard focus inside the scroller, then uses `color-mix(in srgb, var(--color-ink) 26%, transparent)`; thumb hover uses 40%. Increased contrast keeps the thumb visible; forced colors restore the system scrollbar.
|
||||
- **Motion:** Sidebar state changes are immediate on desktop, tablet, and mobile. The 44px trigger keeps one stable 18px sidebar glyph and never enters an intermediate scale or opacity state.
|
||||
@@ -165,6 +166,7 @@ The base unit is 4px. Tokens are `--space-1: 4px`, `--space-2: 8px`, `--space-3:
|
||||
- **Variants:** assistant editorial text on canvas; user text on warm card surface; streaming; error. Streaming uses a timeline of completed steps plus the current step; the thinking body expands while streaming, collapses when answer text appears, and is stored with the assistant message.
|
||||
- **Identity:** every assistant message carries the 32px Jyotisha logo avatar; user messages stay visually lighter and avatar-free.
|
||||
- **Typography:** assistant body 16px with serif subheadings; user body 14px.
|
||||
- **Tables:** three-column technique audit tables keep 状态 on one line. Below 768px they stack each row as title + status, then the note, instead of squeezing 已执行 into a vertical glyph column.
|
||||
- **Follow-up:** the latest settled consultation answer may offer two or three grounded next questions under that answer. Clicking one sends it in the current session. The composer never hosts suggestion chips. If the answer does not support a grounded continuation, nothing is shown.
|
||||
- **Motion:** new messages enter with a short opacity/translate transition only.
|
||||
|
||||
@@ -177,10 +179,10 @@ The base unit is 4px. Tokens are `--space-1: 4px`, `--space-2: 8px`, `--space-3:
|
||||
|
||||
### Product entrypoint card
|
||||
|
||||
- **Structure:** the homepage daily-reading and birth-time cards are single native-button targets stretched across their article surface. Content remains semantic card copy; a compact action label and arrow sit at the lower right.
|
||||
- **Structure:** the homepage daily-reading and birth-time cards are single native-button targets stretched across their article surface. Content remains semantic card copy. On two-column viewports a compact action label and arrow sit at the trailing edge; on a stacked homepage they sit under the supporting line, leading-aligned, so a short label like “深入看今日” does not float to the opposite corner from “开始新的生时校正”.
|
||||
- **Copy:** chat history titles daily readings as “8月22日 · 今日节奏”, topic cards as “事业 · …”, and rectification as “生时校正 · 8月21日”. Clicking the daily card starts a consultation session immediately; it does not place the question in the composer. Private model instructions are selected by a closed entrypoint identifier and expanded only on the server.
|
||||
- **States:** default, whole-card hover, pressed, focus-visible, and disabled. The card surface—not an inner promotional button—carries the interaction feedback.
|
||||
- **Responsive:** cards stack below 768px without introducing a large nested button; the footer keeps supporting copy flexible and the action label on one line.
|
||||
- **Responsive:** cards stack below 900px without introducing a large nested button. Stacked cards hug their copy instead of stretching to a min-height; the footer stacks supporting copy above a leading-aligned one-line action.
|
||||
- **Accessibility:** each card exposes exactly one native button with a descriptive accessible name, preserves a visible focus ring, and meets the full-card touch target.
|
||||
|
||||
### Start greeting
|
||||
|
||||
+154
-40
@@ -151,8 +151,8 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
.app-loading-orbit::after { position: absolute; top: -3px; left: 50%; width: 6px; height: 6px; margin-left: -3px; border-radius: 50%; background: var(--color-action); box-shadow: 0 0 0 3px var(--color-canvas); content: ""; }
|
||||
.app-loading-actions { display: flex; gap: 10px; margin-top: 12px; }
|
||||
.brand-mark, .welcome-mark, .auth-brand span { width: 28px; height: 28px; display: block; flex: 0 0 auto; background: url("/jyotish-logo.png") center / contain no-repeat; font-size: 0; }
|
||||
.new-chat svg { width: 18px; height: 18px; }
|
||||
.session-nav { min-height: 0; flex: 1; display: flex; flex-direction: column; }
|
||||
.session-nav { min-height: 0; flex: 0 0 auto; }
|
||||
.session-nav:last-of-type { min-height: 0; flex: 1 1 auto; display: flex; flex-direction: column; }
|
||||
.chevron { width: 18px; height: 18px; color: var(--color-ink-tertiary); }
|
||||
.chat-header strong, .chat-header span { display: block; }
|
||||
.credit-button span { display: inline-flex; align-items: center; margin: 0; color: inherit; font-size: inherit; line-height: 1; }
|
||||
@@ -228,7 +228,8 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--color-border) 72%, transparent);
|
||||
vertical-align: top;
|
||||
text-align: start;
|
||||
overflow-wrap: anywhere;
|
||||
overflow-wrap: break-word;
|
||||
word-break: keep-all;
|
||||
}
|
||||
.markdown-table thead th {
|
||||
color: var(--color-ink-secondary);
|
||||
@@ -239,6 +240,11 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
.markdown-table tbody th {
|
||||
font-weight: 550;
|
||||
}
|
||||
.markdown-table table:has(thead th:nth-child(3):last-child) td:nth-child(2) {
|
||||
width: 4.5em;
|
||||
color: var(--color-ink-secondary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.markdown-table tr:last-child th,
|
||||
.markdown-table tr:last-child td { border-bottom: 0; }
|
||||
.agent-activity-status,
|
||||
@@ -446,8 +452,8 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
.group\/sidebar-provider[data-viewport] { height: 100vh; height: 100dvh; min-height: 0; overflow: hidden; }
|
||||
.chat-app { width: 100%; height: 100%; min-height: 0; overflow: hidden; display: grid; background: var(--color-canvas); grid-template-columns: minmax(0, 1fr); }
|
||||
.sidebar { position: relative; width: 100%; height: 100%; min-width: 0; min-height: 0; overflow: hidden; display: flex; flex-direction: column; border-right: 1px solid var(--sidebar-border); color: var(--sidebar-foreground); padding: var(--space-5) var(--space-3) 0; background: var(--sidebar-background); backdrop-filter: saturate(130%) blur(20px); }
|
||||
[data-sidebar="header"] { flex: 0 0 auto; }
|
||||
[data-sidebar="content"] { min-height: 0; flex: 1 1 auto; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; }
|
||||
[data-sidebar="header"] { flex: 0 0 auto; padding-bottom: var(--space-3); }
|
||||
[data-sidebar="content"] { min-height: 0; flex: 1 1 auto; display: flex; flex-direction: column; gap: var(--space-3); overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; }
|
||||
[data-sidebar="content"],
|
||||
.conversation,
|
||||
.rectification-board__body {
|
||||
@@ -496,59 +502,73 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
.brand-row strong { font-weight: 400; }
|
||||
.brand-mark, .auth-brand span { width: 32px; height: 32px; border-radius: 50%; background: var(--color-canvas) url("/jyotish-logo.png") center / contain no-repeat; box-shadow: 0 0 0 1px oklch(0 0 0 / .1); }
|
||||
.auth-story-brand img { width: 32px; height: 32px; border-radius: 50%; object-fit: contain; box-shadow: 0 0 0 1px oklch(0 0 0 / .1); }
|
||||
.new-chat { width: 100%; min-height: 44px; display: flex; align-items: center; justify-content: center; gap: var(--space-2); padding: 0 var(--space-3); border: 0; background: transparent; color: var(--sidebar-foreground); cursor: pointer; font-size: var(--type-body-sm); transition: background-color 120ms ease-out, transform 120ms ease-out; margin: 0; border-radius: var(--radius-md); font-weight: 500; }
|
||||
.report-nav-button { width: 100%; min-height: 44px; display: flex; align-items: center; justify-content: center; gap: var(--space-2); padding: 0 var(--space-3); margin-bottom: var(--space-2); border: 0; border-radius: var(--radius-md); color: var(--sidebar-foreground); }
|
||||
.new-chat { width: 100%; min-height: 44px; display: flex; align-items: center; justify-content: center; gap: var(--space-2); padding: 0 var(--space-3); border: 0; background: transparent; color: var(--sidebar-foreground); cursor: pointer; font-size: var(--type-body-sm); line-height: 1.35; transition: background-color 120ms ease-out, transform 120ms ease-out; margin: 0; border-radius: var(--radius-md); font-weight: 500; }
|
||||
.report-nav-button { width: 100%; min-height: 44px; display: flex; align-items: center; justify-content: center; gap: var(--space-2); padding: 0 var(--space-3); margin: 0; border: 0; border-radius: var(--radius-md); background: transparent; color: var(--sidebar-foreground); cursor: pointer; font-size: var(--type-body-sm); font-weight: 500; line-height: 1.35; transition: background-color 120ms ease-out, transform 120ms ease-out; }
|
||||
.report-nav-button:hover,
|
||||
.new-chat:hover { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); }
|
||||
[data-state="expanded"] .new-chat,
|
||||
[data-state="expanded"] .report-nav-button { justify-content: flex-start; }
|
||||
.session-nav-header { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--space-2); padding: 0 var(--space-3) var(--space-2); }
|
||||
.session-nav-header-inline { padding-top: 0; }
|
||||
.sidebar-section { margin: 0 0 var(--space-3); }
|
||||
.new-chat svg,
|
||||
.report-nav-button svg,
|
||||
.sidebar-label > svg,
|
||||
.sidebar-section-summary > svg,
|
||||
.session-nav-toggle svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
flex: 0 0 auto;
|
||||
stroke-width: 1.75;
|
||||
}
|
||||
.session-nav-header { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--space-2); padding: 0 var(--space-3); }
|
||||
.sidebar-section { margin: 0; }
|
||||
.sidebar-label,
|
||||
.sidebar-section-summary {
|
||||
display: flex;
|
||||
min-height: 44px;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
color: var(--color-ink-tertiary);
|
||||
font-size: var(--type-caption);
|
||||
font-weight: 500;
|
||||
letter-spacing: 0;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.sidebar-section-summary {
|
||||
padding: 0 var(--space-3);
|
||||
list-style: none;
|
||||
color: var(--sidebar-muted-foreground);
|
||||
cursor: pointer;
|
||||
font-size: var(--type-overline);
|
||||
font-weight: 500;
|
||||
letter-spacing: 1.5px;
|
||||
}
|
||||
.sidebar-section-summary::-webkit-details-marker { display: none; }
|
||||
.sidebar-section-summary > svg { width: 16px; height: 16px; flex: 0 0 auto; }
|
||||
.sidebar-section-chevron { margin-left: auto; width: 16px; height: 16px; transition: transform 120ms ease-out; }
|
||||
.sidebar-section-summary > .sidebar-section-chevron { margin-left: auto; width: 16px; height: 16px; flex: 0 0 auto; color: currentColor; opacity: .72; transition: transform 120ms ease-out; }
|
||||
.sidebar-section[open] .sidebar-section-chevron { transform: rotate(180deg); }
|
||||
.sidebar-empty { margin: 0; padding: 0 var(--space-3) var(--space-2); color: var(--color-ink-tertiary); font-size: var(--type-caption); }
|
||||
.chart-nav-list { display: flex; flex-wrap: wrap; gap: var(--space-2); padding: 0 var(--space-3) var(--space-2); }
|
||||
.sidebar-nested { padding: 0 var(--space-3) var(--space-1) calc(var(--space-3) + 18px + var(--space-2)); }
|
||||
.sidebar-empty { margin: 0; padding: 0 0 var(--space-2); color: var(--color-ink-tertiary); font-size: var(--type-caption); line-height: 1.35; }
|
||||
.chart-nav-list { display: flex; flex-wrap: wrap; gap: var(--space-2); padding: 0 0 var(--space-2); }
|
||||
.chart-nav-chip {
|
||||
min-height: 32px;
|
||||
max-width: 100%;
|
||||
padding: 0 12px;
|
||||
padding: 0 var(--space-3);
|
||||
border: 1px solid var(--sidebar-border);
|
||||
border-radius: 999px;
|
||||
background: var(--color-canvas);
|
||||
color: var(--sidebar-foreground);
|
||||
cursor: pointer;
|
||||
font-size: var(--type-caption);
|
||||
font-weight: 400;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.chart-nav-chip:hover { background: var(--sidebar-accent); }
|
||||
.sidebar-label { min-height: 44px; display: flex; align-items: center; gap: var(--space-2); color: var(--sidebar-muted-foreground); font-size: var(--type-overline); font-weight: 500; letter-spacing: 1.5px; }
|
||||
.chart-nav-chip:hover { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); }
|
||||
.sidebar-label:focus-visible { outline: 3px solid color-mix(in srgb, var(--sidebar-ring) 56%, transparent); outline-offset: 2px; border-radius: var(--radius-sm); }
|
||||
.session-nav-toggle { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0 var(--space-2); border: 0; border-radius: var(--radius-md); background: transparent; color: var(--sidebar-muted-foreground); cursor: pointer; font-size: var(--type-overline); transition: background-color 120ms ease-out, color 120ms ease-out; }
|
||||
.session-nav-toggle svg { width: 16px; height: 16px; }
|
||||
.session-nav-toggle { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: var(--radius-md); background: transparent; color: var(--color-ink-tertiary); cursor: pointer; font-size: var(--type-caption); transition: background-color 120ms ease-out, color 120ms ease-out; }
|
||||
.session-nav-toggle:hover { background: var(--sidebar-accent); color: var(--sidebar-foreground); }
|
||||
.session-list { min-height: 0; display: flex; flex-direction: column; gap: var(--space-1); }
|
||||
.session-row { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 44px; align-items: center; border-radius: var(--radius-lg); color: var(--sidebar-muted-foreground); transition: background-color 120ms ease-out, box-shadow 120ms ease-out, color 120ms ease-out; }
|
||||
.session-row { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 44px; align-items: center; border-radius: var(--radius-lg); color: var(--sidebar-foreground); transition: background-color 120ms ease-out, box-shadow 120ms ease-out, color 120ms ease-out; }
|
||||
.session-row:hover, .session-row:focus-within { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); }
|
||||
.session-row:has(.session-main[data-active="true"]) { background: var(--sidebar-accent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sidebar-ring) 22%, transparent); color: var(--sidebar-accent-foreground); }
|
||||
.session-main { position: relative; width: 100%; min-height: 44px; display: grid; gap: 2px; padding: var(--space-2) var(--space-3) var(--space-2) var(--space-4); border: 0; border-radius: var(--radius-md); background: transparent; color: inherit; cursor: pointer; text-align: left; transition: background-color 120ms ease-out, color 120ms ease-out, transform 120ms ease-out; }
|
||||
.session-main { position: relative; width: 100%; min-height: 44px; display: grid; gap: 2px; padding: var(--space-2); border: 0; border-radius: var(--radius-md); background: transparent; color: inherit; cursor: pointer; text-align: left; transition: background-color 120ms ease-out, color 120ms ease-out, transform 120ms ease-out; }
|
||||
.session-main[data-active="true"] { color: var(--sidebar-accent-foreground); background: transparent; }
|
||||
.session-main[data-active="true"]::before { position: absolute; border-radius: 3px; content: ""; top: var(--space-3); bottom: var(--space-3); left: var(--space-1); width: 2px; background: var(--sidebar-ring); }
|
||||
.session-title { min-width: 0; display: flex; align-items: center; gap: var(--space-1); overflow: hidden; line-height: 1.35; font-size: var(--type-body-sm); font-weight: 500; }
|
||||
.session-title > svg { width: var(--space-3); height: var(--space-3); flex: 0 0 auto; color: var(--sidebar-ring); }
|
||||
.session-main[data-active="true"]::before { position: absolute; border-radius: 3px; content: ""; top: var(--space-3); bottom: var(--space-3); left: 0; width: 2px; background: var(--sidebar-ring); }
|
||||
.session-title { min-width: 0; display: flex; align-items: center; gap: var(--space-1); overflow: hidden; line-height: 1.35; font-size: var(--type-caption); font-weight: 500; }
|
||||
.session-title > svg { width: 14px; height: 14px; flex: 0 0 auto; color: currentColor; }
|
||||
.session-main small { color: var(--color-ink-tertiary); line-height: 1.3; font-size: var(--type-overline); }
|
||||
.session-menu-trigger { width: 44px; height: 44px; display: grid; place-items: center; justify-self: center; padding: 0; border: 0; border-radius: 0; background: transparent; color: inherit; cursor: pointer; opacity: .64; transition: background-color 120ms ease-out, color 120ms ease-out, opacity 120ms ease-out, transform 120ms ease-out; }
|
||||
.session-menu-trigger > svg { width: 18px; height: 18px; }
|
||||
@@ -998,7 +1018,8 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--color-border) 64%, transparent);
|
||||
vertical-align: top;
|
||||
text-align: start;
|
||||
overflow-wrap: anywhere;
|
||||
overflow-wrap: break-word;
|
||||
word-break: keep-all;
|
||||
}
|
||||
.technique-audit-panel thead th {
|
||||
color: var(--color-ink-tertiary);
|
||||
@@ -1019,6 +1040,67 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
.technique-audit-panel td:last-child { color: var(--color-ink-secondary); }
|
||||
.technique-audit-panel tr:last-child th,
|
||||
.technique-audit-panel tr:last-child td { border-bottom: 0; }
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.markdown-table table:has(thead th:nth-child(3):last-child) thead,
|
||||
.technique-audit-panel thead {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.markdown-table table:has(thead th:nth-child(3):last-child) tbody tr,
|
||||
.technique-audit-panel tbody tr {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
gap: var(--space-1) var(--space-3);
|
||||
padding: var(--space-3) 0;
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--color-border) 64%, transparent);
|
||||
}
|
||||
|
||||
.markdown-table table:has(thead th:nth-child(3):last-child) tbody th,
|
||||
.markdown-table table:has(thead th:nth-child(3):last-child) tbody td,
|
||||
.technique-audit-panel tbody th,
|
||||
.technique-audit-panel tbody td {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.markdown-table table:has(thead th:nth-child(3):last-child) tbody td:nth-child(1),
|
||||
.technique-audit-panel tbody th {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
color: var(--color-ink);
|
||||
font-weight: 550;
|
||||
}
|
||||
|
||||
.markdown-table table:has(thead th:nth-child(3):last-child) tbody td:nth-child(2),
|
||||
.technique-audit-panel td[data-status] {
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
width: auto;
|
||||
color: var(--color-ink-secondary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.markdown-table table:has(thead th:nth-child(3):last-child) tbody td:nth-child(3),
|
||||
.technique-audit-panel td:last-child {
|
||||
grid-column: 1 / -1;
|
||||
grid-row: 2;
|
||||
color: var(--color-ink-secondary);
|
||||
font-size: var(--type-caption);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.markdown-table table:has(thead th:nth-child(3):last-child) tbody tr:last-child,
|
||||
.technique-audit-panel tbody tr:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
.error-message { margin: 12px 0 0; padding: 12px 14px; border-left: 3px solid var(--color-danger); background: var(--color-danger-muted); color: var(--color-danger); font-size: 13px; line-height: 1.6; border-color: var(--color-danger); border-radius: 0 var(--radius-md) var(--radius-md) 0; }
|
||||
|
||||
.composer-wrap { position: sticky; bottom: 0; z-index: 2; min-width: 0; border-top: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent); padding: var(--space-3) var(--space-6) var(--space-4); background: var(--color-frosted); backdrop-filter: saturate(130%) blur(20px); }
|
||||
@@ -1507,6 +1589,10 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.product-entrypoint-footer small:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.product-entrypoint-action {
|
||||
display: inline-flex;
|
||||
flex: 0 0 auto;
|
||||
@@ -1657,11 +1743,28 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.daily-starlanguage-card,
|
||||
.birth-rectification-card {
|
||||
min-height: 0;
|
||||
grid-template-rows: auto auto;
|
||||
}
|
||||
|
||||
.birth-rectification-card {
|
||||
border-top: 1px solid var(--color-border);
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.product-entrypoint-footer {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.product-entrypoint-action {
|
||||
margin-left: 0;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.starter-theme-accordion {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
@@ -1698,8 +1801,10 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
|
||||
.daily-starlanguage-card,
|
||||
.birth-rectification-card {
|
||||
min-height: 210px;
|
||||
padding: var(--space-6);
|
||||
min-height: 0;
|
||||
grid-template-rows: auto auto;
|
||||
gap: var(--space-4);
|
||||
padding: var(--space-5);
|
||||
}
|
||||
|
||||
.birth-rectification-card {
|
||||
@@ -1707,6 +1812,24 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.product-entrypoint-copy h2 {
|
||||
font-size: var(--type-title-md);
|
||||
}
|
||||
|
||||
.product-entrypoint-footer {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-3);
|
||||
padding-top: var(--space-4);
|
||||
}
|
||||
|
||||
.product-entrypoint-action {
|
||||
margin-left: 0;
|
||||
justify-content: flex-start;
|
||||
font-size: var(--type-body-sm);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.starter-section-heading {
|
||||
display: grid;
|
||||
gap: var(--space-1);
|
||||
@@ -1731,15 +1854,6 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
padding: var(--space-6) var(--space-5);
|
||||
}
|
||||
|
||||
.product-entrypoint-footer {
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
.product-entrypoint-action {
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.starter-content span {
|
||||
font-size: var(--type-title-sm);
|
||||
}
|
||||
|
||||
@@ -3866,7 +3866,9 @@ export default function Home() {
|
||||
>{natalMinuteAvailable ? dailyStarlanguageTrend : "看看今天的整体节奏、适合推进的事和需要留意的地方。"}</p>
|
||||
</div>
|
||||
<div className="product-entrypoint-footer">
|
||||
<small>{natalMinuteAvailable ? dailyStarlanguageAction : "不支持的个人判断会明确说明,不会补造出生时间。"}</small>
|
||||
{natalMinuteAvailable
|
||||
? (dailyStarlanguageAction ? <small>{dailyStarlanguageAction}</small> : null)
|
||||
: <small>不支持的个人判断会明确说明,不会补造出生时间。</small>}
|
||||
<span className="product-entrypoint-action" aria-hidden="true">{natalMinuteAvailable ? dailyStarlanguageQuestion : "查看今日运势"} <ArrowUpRight className="starter-arrow" /></span>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
@@ -168,7 +168,7 @@ export function AppSidebar({
|
||||
disabled={newChatDisabled}
|
||||
onClick={handleNewChat}
|
||||
>
|
||||
<SquarePen aria-hidden="true" />
|
||||
<SquarePen size={18} strokeWidth={1.75} aria-hidden="true" />
|
||||
{showExpandedContent ? <span>{creatingSession ? "正在创建" : "新建对话"}</span> : null}
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
@@ -179,7 +179,7 @@ export function AppSidebar({
|
||||
tooltip="我的报告"
|
||||
onClick={handleOpenReports}
|
||||
>
|
||||
<FileText aria-hidden="true" />
|
||||
<FileText size={18} strokeWidth={1.75} aria-hidden="true" />
|
||||
{showExpandedContent ? <span>我的报告</span> : null}
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
@@ -192,7 +192,7 @@ export function AppSidebar({
|
||||
<SidebarGroup className="chart-nav" aria-label="星盘列表">
|
||||
<div className="session-nav-header">
|
||||
<SidebarGroupLabel className="sidebar-label">
|
||||
<Users aria-hidden="true" />
|
||||
<Users size={18} strokeWidth={1.75} aria-hidden="true" />
|
||||
星盘列表
|
||||
</SidebarGroupLabel>
|
||||
<button
|
||||
@@ -201,10 +201,10 @@ export function AppSidebar({
|
||||
aria-label="添加星盘"
|
||||
onClick={onAddChart}
|
||||
>
|
||||
<UserPlus aria-hidden="true" />
|
||||
<UserPlus size={18} strokeWidth={1.75} aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
<SidebarGroupContent>
|
||||
<SidebarGroupContent className="sidebar-nested">
|
||||
{charts.length === 0 ? <p className="sidebar-empty">还没有星盘</p> : (
|
||||
<div className="chart-nav-list">
|
||||
{charts.map((chart) => (
|
||||
@@ -225,11 +225,11 @@ export function AppSidebar({
|
||||
<SidebarGroup className="session-nav" aria-label="收藏对话">
|
||||
<details className="sidebar-section" open>
|
||||
<summary className="sidebar-section-summary">
|
||||
<Star aria-hidden="true" />
|
||||
<Star size={18} strokeWidth={1.75} aria-hidden="true" />
|
||||
<span>收藏对话</span>
|
||||
<ChevronDown className="sidebar-section-chevron" aria-hidden="true" />
|
||||
<ChevronDown className="sidebar-section-chevron" size={16} strokeWidth={1.75} aria-hidden="true" />
|
||||
</summary>
|
||||
<SidebarGroupContent>
|
||||
<SidebarGroupContent className="sidebar-nested">
|
||||
{favoriteSessions.length === 0 ? <p className="sidebar-empty">还没有收藏</p> : (
|
||||
<SidebarMenu className="session-list">
|
||||
{favoriteSessions.map((session, index) => renderSession(session, index))}
|
||||
@@ -242,16 +242,11 @@ export function AppSidebar({
|
||||
<SidebarGroup className="session-nav" aria-label={sessionControls.showingArchived ? "归档记录" : "历史对话"}>
|
||||
<details className="sidebar-section" open>
|
||||
<summary className="sidebar-section-summary" ref={historyHeadingRef} tabIndex={-1}>
|
||||
<Clock3 aria-hidden="true" />
|
||||
<Clock3 size={18} strokeWidth={1.75} aria-hidden="true" />
|
||||
<span>{sessionControls.showingArchived ? "归档记录" : "历史对话"}</span>
|
||||
<ChevronDown className="sidebar-section-chevron" aria-hidden="true" />
|
||||
<ChevronDown className="sidebar-section-chevron" size={16} strokeWidth={1.75} aria-hidden="true" />
|
||||
</summary>
|
||||
<div className="session-nav-header session-nav-header-inline">
|
||||
<button className="session-nav-toggle" type="button" onClick={sessionControls.onToggleArchivedView}>
|
||||
{sessionControls.showingArchived ? "返回" : `归档 ${sessionControls.archivedCount}`}
|
||||
</button>
|
||||
</div>
|
||||
<SidebarGroupContent>
|
||||
<SidebarGroupContent className="sidebar-nested">
|
||||
{historySessions.length === 0 ? <p className="sidebar-empty">暂无对话</p> : (
|
||||
<SidebarMenu className="session-list">
|
||||
{historySessions.map((session, index) => renderSession(session, favoriteSessions.length + index))}
|
||||
@@ -270,7 +265,7 @@ export function AppSidebar({
|
||||
aria-label="聊天记录"
|
||||
onClick={handleExpandHistory}
|
||||
>
|
||||
<MessageSquareText aria-hidden="true" />
|
||||
<MessageSquareText size={18} strokeWidth={1.75} aria-hidden="true" />
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
|
||||
@@ -352,7 +352,7 @@ test("the starter heading is drawn per visit and the rectification card carries
|
||||
assert.match(source, /useState\(\(\) => Math\.random\(\)\)/);
|
||||
assert.match(source, /starterGreetingUnseen\.current = true;\s*\n\s*setStarterGreetingSelection\(Math\.random\(\)\)/);
|
||||
|
||||
// Then: the rectification card's footer is the action alone, still flush right.
|
||||
// Then: the rectification card's footer is the action alone, still flush right on two-column layouts.
|
||||
const rectificationCard = source.slice(
|
||||
source.indexOf('<article className="birth-rectification-card'),
|
||||
source.indexOf("</article>", source.indexOf('<article className="birth-rectification-card')),
|
||||
@@ -362,6 +362,22 @@ test("the starter heading is drawn per visit and the rectification card carries
|
||||
assert.match(styles, /\.product-entrypoint-action \{[^}]*margin-left: auto;/);
|
||||
});
|
||||
|
||||
test("stacked homepage cards hug copy and lead-align the action", () => {
|
||||
const styles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8");
|
||||
const phoneCards = styles.match(
|
||||
/\.starter-hero h1 \{\s*font-size: clamp\(38px[\s\S]*?\.daily-starlanguage-card,\s*\.birth-rectification-card \{([^}]*)\}[\s\S]*?\.product-entrypoint-footer \{([^}]*)\}[\s\S]*?\.product-entrypoint-action \{([^}]*)\}/,
|
||||
);
|
||||
|
||||
assert.ok(phoneCards);
|
||||
assert.match(phoneCards[1], /min-height:\s*0;/);
|
||||
assert.match(phoneCards[1], /grid-template-rows:\s*auto auto;/);
|
||||
assert.doesNotMatch(phoneCards[1], /min-height:\s*210px/);
|
||||
assert.match(phoneCards[2], /flex-direction:\s*column;/);
|
||||
assert.match(phoneCards[2], /align-items:\s*flex-start;/);
|
||||
assert.match(phoneCards[3], /margin-left:\s*0;/);
|
||||
assert.match(phoneCards[3], /justify-content:\s*flex-start;/);
|
||||
});
|
||||
|
||||
test("starter homepage keeps its editorial display typography", () => {
|
||||
const styles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8");
|
||||
const heroHeading = styles.match(/\.starter-hero h1\s*\{([^}]*)\}/)?.[1] ?? "";
|
||||
|
||||
@@ -110,4 +110,7 @@ test("the folded audit control stays closed and never remounts the internal pane
|
||||
assert.match(globalStyles, /\.markdown-table/);
|
||||
assert.match(globalStyles, /\.technique-audit >/);
|
||||
assert.match(globalStyles, /\.markdown-table th,/);
|
||||
assert.match(globalStyles, /word-break:\s*keep-all/);
|
||||
assert.match(globalStyles, /\.markdown-table table:has\(thead th:nth-child\(3\):last-child\) td:nth-child\(2\)/);
|
||||
assert.match(globalStyles, /@media \(max-width: 767px\) \{[\s\S]*\.markdown-table table:has\(thead th:nth-child\(3\):last-child\) tbody tr/);
|
||||
});
|
||||
|
||||
@@ -305,6 +305,29 @@ test("styles the session history scrollbar as a quiet overlay", () => {
|
||||
assert.match(readProjectFile("DESIGN.md"), /ordinary session/);
|
||||
});
|
||||
|
||||
test("nests sidebar lists under one heading scale without an archive toggle", () => {
|
||||
const appSidebar = readProjectFile("src/components/app-sidebar.tsx");
|
||||
assert.doesNotMatch(appSidebar, /归档 \$\{/);
|
||||
assert.doesNotMatch(appSidebar, /onToggleArchivedView/);
|
||||
assert.match(appSidebar, /className="sidebar-nested"/);
|
||||
assert.match(cssBlock(".sidebar-nested"), /calc\(var\(--space-3\) \+ 18px \+ var\(--space-2\)\)/);
|
||||
assert.match(cssBlock(".session-title"), /font-size:\s*var\(--type-caption\)/);
|
||||
assert.match(cssBlock(".session-title"), /font-weight:\s*500/);
|
||||
assert.match(cssBlock(".session-row"), /color:\s*var\(--sidebar-foreground\)/);
|
||||
assert.match(cssBlock(".sidebar-label"), /color:\s*var\(--color-ink-tertiary\)/);
|
||||
assert.match(cssBlock(".sidebar-section-summary"), /color:\s*var\(--color-ink-tertiary\)/);
|
||||
assert.match(cssBlock(".sidebar-label"), /font-size:\s*var\(--type-caption\)/);
|
||||
assert.match(cssBlock(".sidebar-section-summary"), /font-size:\s*var\(--type-caption\)/);
|
||||
assert.match(cssBlock(".new-chat"), /font-size:\s*var\(--type-body-sm\)/);
|
||||
assert.match(cssBlock(".report-nav-button"), /font-size:\s*var\(--type-body-sm\)/);
|
||||
assert.match(cssBlock(".new-chat svg"), /width:\s*18px/);
|
||||
assert.match(cssBlock(".report-nav-button svg"), /width:\s*18px/);
|
||||
assert.match(cssBlock(".sidebar-label > svg"), /width:\s*18px/);
|
||||
assert.match(cssBlock(".sidebar-section-summary > svg"), /width:\s*18px/);
|
||||
assert.match(cssBlock(".session-title > svg"), /color:\s*currentColor/);
|
||||
assert.doesNotMatch(appSidebar, /session-nav-header-inline/);
|
||||
});
|
||||
|
||||
test("renders each session title and menu as one unified row surface", () => {
|
||||
assert.match(cssBlock(".session-row"), /grid-template-columns:\s*minmax\(0,\s*1fr\)\s+44px/);
|
||||
assert.match(globalStyles, /\.session-row:has\(\.session-main\[data-active="true"\]\)[^{]*\{[^}]*background:\s*var\(--sidebar-accent\)/);
|
||||
|
||||
Reference in New Issue
Block a user