Skip to content

Commit 0dd8f7a

Browse files
committed
fix(tour): cap card max-height + raise placement threshold so step 1 fits its viewport slot
1 parent 2c2c75c commit 0dd8f7a

2 files changed

Lines changed: 23 additions & 3 deletions

File tree

src/cli/dashboard/src/components/tour/GuidedTour.module.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@
3939
left: var(--card-left, auto);
4040
bottom: var(--card-bottom, auto);
4141
right: var(--card-right, auto);
42+
// Cap height + scroll-on-overflow. Without this, long step bodies
43+
// (e.g. step 1's full Quickstart description) plus the 14-step
44+
// counter, action row, and tab badge made the card ~280px tall —
45+
// taller than the 200px "below" threshold the placement code uses,
46+
// so the Skip/Next buttons disappeared off the bottom of the
47+
// viewport. Inner overflow-y: auto keeps every step visible
48+
// regardless of how the placement math lands.
49+
max-height: calc(100dvh - 32px);
50+
overflow-y: auto;
51+
display: flex;
52+
flex-direction: column;
4253
}
4354

4455
.card.mobile {

src/cli/dashboard/src/components/tour/GuidedTour.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,21 +329,30 @@ export function GuidedTour({ activeTab, chatEnabled = true, onTabChange, onClose
329329

330330
// Compute card position via CSS custom properties so the static styles
331331
// live in the SCSS module while runtime values flow through inline.
332+
// Threshold reflects the real card footprint, not just header chrome:
333+
// step 1 ("Quickstart — author from a brief") plus the 14-step
334+
// counter + tab badge + Skip/Next action row lands around 280px on
335+
// desktop, so a 200px "below" check happily placed the card in a
336+
// slot it could never fit. The card itself is also max-heighted +
337+
// overflow-y: auto in the SCSS so even worst-case anchors keep the
338+
// controls reachable, but biasing toward "above" / "right" first
339+
// avoids the awkward inner scroll on the most common targets.
340+
const CARD_MIN_VERTICAL_SLOT = 320;
332341
const cardVars: CSSProperties = {};
333342
if (!isMobile && rect) {
334343
const below = vh - (rect.top + rect.height + 10);
335344
const above = rect.top - 10;
336345
const right = vw - (rect.left + rect.width + 10);
337346

338-
if (below >= 200) {
347+
if (below >= CARD_MIN_VERTICAL_SLOT) {
339348
(cardVars as Record<string, string>)['--card-top'] = `${rect.top + rect.height + 16}px`;
340349
(cardVars as Record<string, string>)['--card-left'] = `${Math.max(16, Math.min(rect.left, vw - CARD_W - 16))}px`;
341-
} else if (above >= 200) {
350+
} else if (above >= CARD_MIN_VERTICAL_SLOT) {
342351
(cardVars as Record<string, string>)['--card-bottom'] = `${vh - rect.top + 16}px`;
343352
(cardVars as Record<string, string>)['--card-left'] = `${Math.max(16, Math.min(rect.left, vw - CARD_W - 16))}px`;
344353
} else if (right >= CARD_W + 24) {
345354
(cardVars as Record<string, string>)['--card-left'] = `${rect.left + rect.width + 16}px`;
346-
(cardVars as Record<string, string>)['--card-top'] = `${Math.max(16, rect.top)}px`;
355+
(cardVars as Record<string, string>)['--card-top'] = `${Math.max(16, Math.min(rect.top, vh - CARD_MIN_VERTICAL_SLOT - 16))}px`;
347356
} else {
348357
(cardVars as Record<string, string>)['--card-bottom'] = '24px';
349358
(cardVars as Record<string, string>)['--card-right'] = '24px';

0 commit comments

Comments
 (0)