/* V2 landing — token-aligned, single accent, borders not shadows. A marketing * surface: the one allowed soft shadow (on floating screenshot cards) is the * only departure from in-app chrome rules — rows D and E took the navy out of * the proof and the close, so both are panels and type on the page's own * white. * Sentence case, no emoji in chrome, calm motion. Full-bleed bands; content * centered at 1312px via a max() padding trick (row A, TASK-192: the product * frame and the demo inside it are the same 1312 wide, so the page and the * product share one measure). */ /* The landing is its own scroll container. .v2-root (the app shell) is height:100vh / display:flex / overflow:hidden — override here with a .v2-root.v2-landing selector (beats .v2-root) so the long page scrolls. */ .v2-root.v2-landing { display: block; height: 100vh; overflow-y: auto; overflow-x: hidden; /* The scroller is the containing block for the absolutely-positioned `.v2-demo__sr` inside the hero demo (TASK-167 row A, ux-lead's #2018 finding 9: without it that node resolves against the document and extends it — a wheel-overscroll at the footer scrolled the WINDOW 401px on live, pushing the bar off and showing blank grey). Nothing moves: measured at 1440 and 390. */ position: relative; background: var(--v2-bg, #ffffff); color: var(--v2-text-primary); font-family: var(--v2-font); -webkit-font-smoothing: antialiased; /* TASK-205: a first-click anchor landed the section short and then under the bar. Two causes, one rule each. scroll-padding-top here, on the SCROLLER rather than as scroll-margin on each section, so hash navigation, scrollIntoView and keyboard focus all inherit it — focus was landing under the bar too. 72 is the frosted bar plus 40 of air; the phone block below drops it to 88 (64 + 24). `scroll-behavior: smooth` used to sit here unconditionally, which beat the no-preference block at the foot of this file (0,2,0 against 0,1,0) and so animated the jump for visitors who had asked for reduced motion. Deleted rather than overridden: smooth scrolling now has exactly one source, and a reduced-motion visitor gets an instant jump. */ scroll-padding-top: 112px; } .v2-landing__bar, .v2-landing__hero, /* The product frame is OUTSIDE the band (row A, ux-lead's #2018 finding 1), and it carries the page measure like every band does, so the demo does not drift to the viewport edge once it stops being a child of the hero. */ .v2-landing__hero-art, .v2-landing__trusted, .v2-landing__section, .v2-landing__wedge, .v2-landing__proof, .v2-landing__cta, .v2-landing__footer { padding-left: max(24px, calc((100% - 1312px) / 2)); padding-right: max(24px, calc((100% - 1312px) / 2)); } /* Suffix after the rotating term (zh: 「与你的___对话」). Same visual weight as the title; the space is handled by the margin, not the string. */ .v2-landing__title-suffix { margin-left: 0.18em; /* TASK-211: the zh hero is 「与你的___对话」, so this suffix is a word the reader has to see whole. At 390 with the "Claude Code" term the two characters straddled the wrap: the h1's content box ran 24 → 366, so 对 fitted (348.5, i.e. 17.5px inside the right edge) and it was 话 — 44.3px wide, which would have ended at 392.8, 26.8px past it — that sat alone on line 3. nowrap makes the suffix one unbreakable unit: it moves to the next line as a pair instead of splitting. Measured live at 390 (44px/46px) and again at 320, where the 整个团队 term split it the same way. en ships an empty suffix and renders no span, so this is zh-only and cannot move the English hero. */ white-space: nowrap; } /* ---------- Top bar (sticky) ---------- */ .v2-landing__bar { position: sticky; top: 0; z-index: 20; display: flex; align-items: center; justify-content: space-between; height: 72px; background: rgba(255, 255, 255, 0.86); backdrop-filter: saturate(180%) blur(12px); border-bottom: 1px solid var(--v2-border-soft); } /* One element, two states. While the cobalt band is under the bar the bar is cobalt too — #1d3fd1, a white hairline, no blur — so the band reads as one block from the top of the page; past the band's bottom edge it is the white bar above. The class is set once by an IntersectionObserver on the band (see V2LandingPage), and the class starts ON so first paint is the band state and there is no white flash before the observer runs. */ .v2-landing__bar--band { background: #1d3fd1; backdrop-filter: none; border-bottom-color: rgba(255, 255, 255, 0.22); } .v2-landing__brand { display: flex; align-items: center; gap: 8px; } /* Wordmark only — the band carries no glyph mark, and the board sets the name in the display face at 24. */ .v2-landing__brand-name { font-family: var(--v2-font-display, var(--v2-font)); font-size: 24px; font-weight: 800; letter-spacing: -0.03em; color: var(--v2-text-primary); } .v2-landing__nav { display: flex; align-items: center; gap: 28px; } .v2-landing__navlink { font-size: 15px; font-weight: 500; color: var(--v2-text-secondary); text-decoration: none; transition: color 80ms ease; } .v2-landing__navlink:hover { color: var(--v2-text-primary); } .v2-landing__bar--band .v2-landing__brand-name { color: #ffffff; } .v2-landing__bar--band .v2-landing__navlink { color: rgba(255, 255, 255, 0.86); } .v2-landing__bar--band .v2-landing__navlink:hover { color: #ffffff; } /* The language trigger is a