Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/app/(home)/cloud/CloudCodeBlock.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,20 @@
}

@media (max-width: 767px) {
/* Opt-in, off by default. A host that sets this renders the panel at its
desktop measure and scales the whole box down: zoom shrinks the layout box
too, so a percentage width resolves in the panel's own scaled space and the
panel keeps the proportions it has on a wide screen instead of clipping
lines at phone width. */
.panel {
zoom: var(--cloud-code-mobile-zoom, 1);
}

.code {
/* Opt-in, off by default: a host that zooms the panel down can also pull the
code's own padding in, which the zoom would otherwise leave looking
generous relative to the shrunken type. */
padding-block: var(--cloud-code-mobile-padding-block, 48px);
scrollbar-width: none;
}

Expand Down
18 changes: 18 additions & 0 deletions docs/app/(home)/cloud/CloudIntegrationSection.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,28 @@
width: calc(100% - 32px);
}

/* A host that sets this to `contents` drops .content as a box, so its two
children join .inner's column and the orders below can put the code between
them. Left as `flex` the orders are inert: .intro and .stepper are ordered
inside .content in the sequence they already appear in, and .codeColumn is
the second of .inner's two items either way. */
.content {
display: var(--cloud-setup-content-display, flex);
gap: 32px;
}

.intro {
order: 1;
}

.codeColumn {
order: 2;
}

.stepper {
order: 3;
}

.stepper[data-interactive="true"][data-step-count="2"] {
height: 248px;
}
Expand Down
99 changes: 36 additions & 63 deletions docs/app/(home)/cloud/observability/CloudCtaSection.module.css
Original file line number Diff line number Diff line change
@@ -1,52 +1,57 @@
/* No surface of its own: the CTA sits straight on the page. The FAQ band below
brings its own top gap, so this only tops that up rather than stating the
full measure again. */
.section {
width: 100%;
padding: var(--observability-section-gap, 160px) var(--home-section-padding-inline) 0;
background: var(--openui-foreground);
padding: var(--observability-section-gap, 160px) var(--home-section-padding-inline)
calc(var(--observability-section-gap, 160px) / 2);
}

/* One centred column, read top to bottom: the ask, the field that answers it,
then the terms. A two-column split put the title and the field on opposite
sides of 1200px, with the eye crossing the page between reading and acting. */
.inner {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
gap: 48px;
gap: 32px;
width: 100%;
max-width: 1200px;
margin-inline: auto;
text-align: center;
}

.copy {
flex: 1 1 auto;
display: flex;
flex-direction: column;
align-items: center;
min-width: 0;
}

.note {
margin: 0.75rem 0 0;
font-size: 1.0625rem;
line-height: 1.5;
color: var(--openui-text-neutral-secondary);
}

.pricingLink {
color: var(--openui-text-neutral-primary);
text-decoration: none;
border-bottom: 1px solid currentColor;
padding-bottom: 1px;
}
/* The offer line above the title. inline-flex rather than a run of text, so the
mark sits on the line's centre instead of its baseline; the gap replaces the
space flex layout drops between the children.

.pricingLink:hover {
opacity: 0.7;
}

.accessNote {
margin: 0;
color: var(--openui-text-neutral-secondary);
Green is the same #049156 the trace diagram's pass marks and the hero's own
offer line use. Centred by the column, so it needs no alignment of its own. */
.offer {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 0 0 12px;
color: #049156;
font-size: 0.875rem;
font-weight: 600;
line-height: 1.5;
}

.accessNote strong {
color: var(--openui-text-neutral-primary);
font-weight: 600;
[data-theme="dark"] .offer {
/* The solid reads as near-black on the dark ground, so the line lifts. */
color: #3ecf8e;
}

.offerIcon {
flex: none;
}

.title {
Expand All @@ -66,45 +71,13 @@
display: flex;
flex: 0 0 auto;
flex-direction: column;
align-items: flex-start;
gap: 12px;
}

.formTitle {
margin: 0;
color: var(--openui-text-neutral-primary);
font-family: var(--home-font-display);
font-size: var(--home-heading-size);
font-weight: var(--home-heading-weight);
line-height: var(--home-heading-leading);
letter-spacing: var(--home-heading-tracking);
}

.separator {
width: 100%;
max-width: 1200px;
height: 1px;
margin: var(--observability-section-gap, 160px) auto 0;
background: var(--home-hairline);
}

@media (max-width: 1023px) {
.inner {
flex-direction: column;
align-items: flex-start;
gap: 32px;
}
align-items: center;
/* The only gap in here, between the field and the link below it. */
gap: 20px;
}

@media (max-width: 767px) {
.inner {
align-items: center;
text-align: center;
}

.actions {
flex-direction: column;
align-items: center;
width: 100%;
max-width: 320px;
}
Expand Down
20 changes: 11 additions & 9 deletions docs/app/(home)/cloud/observability/CloudCtaSection.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/* ssr entry: this section is a server component. */
import { Button } from "@/components/button";
import { Gift } from "@phosphor-icons/react/dist/ssr";
import styles from "./CloudCtaSection.module.css";
import { EarlyAccessForm } from "./EarlyAccessForm";

Expand All @@ -6,25 +9,24 @@ export function CloudCtaSection() {
<section className={styles.section} aria-labelledby="cloud-cta-title">
<div className={styles.inner}>
<div className={styles.copy}>
{/* Above the title rather than under the field: the offer is the
reason to read the line below it, not a footnote to the form. */}
<p className={styles.offer}>
<Gift aria-hidden="true" className={styles.offerIcon} size={15} weight="bold" />
Free during early access.
</p>
<h2 id="cloud-cta-title" className={styles.title}>
See your agent through your users’ eyes
</h2>
<p className={styles.note}>See what works, what’s missing, and what to build next.</p>
</div>
{/* The same capture as the hero, so the page opens and closes on the
one action. */}
<div className={styles.actions}>
<h3 className={styles.formTitle}>Join waitlist</h3>
<EarlyAccessForm />
<p className={styles.accessNote}>
<strong>Free during early access.</strong>{" "}
<a className={styles.pricingLink} href="/pricing">
View pricing
</a>
</p>
{/* The same tertiary button the trust section uses for its own link. */}
<Button href="/pricing" text="View pricing" variant="tertiary" />
</div>
</div>
<div className={styles.separator} aria-hidden="true" />
</section>
);
}
4 changes: 3 additions & 1 deletion docs/app/(home)/cloud/observability/FaqSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ export function FaqSection() {
firstOpen
contact={
<>
Have another question? Join our{" "}
Have another question?
<br />
Join our{" "}
<a
className={styles.noteLink}
href="https://discord.com/invite/Pbv5PsqUSv"
Expand Down
79 changes: 59 additions & 20 deletions docs/app/(home)/cloud/observability/FeaturesSection.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,46 @@
width: 100%;
}

/* Shrinks below the 1200px design width instead of overflowing; the gap above
is the floor, space-between distributes anything left over. */
.featureImage {
/* The stage: shader behind, artwork on top. Shrinks below the 1200px design
width instead of overflowing; the gap above is the floor, space-between
distributes anything left over.

The stroke is the shader's own base colour, so the edge is the same shade as
the fill inside it. Keep in step with TONES in FadedDitherCanvas.tsx. */
.shot {
--shot-stroke: #f8f8f8;

position: relative;
flex: 0 1 720px;
align-self: center;
min-width: 0;
width: auto;
height: auto;
aspect-ratio: 720 / 400;
overflow: hidden;
border: 1px solid var(--shot-stroke);
border-radius: 24px;
}

[data-theme="dark"] .shot {
--shot-stroke: #0e0e0e;
}

.shotShader {
position: absolute;
z-index: 0;
inset: 0;
}

.shotShader > * {
width: 100%;
height: 100%;
}

.featureImage {
position: relative;
z-index: 1;
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}

Expand Down Expand Up @@ -140,10 +166,9 @@
gap: 32px;
}

.featureImage {
.shot {
flex: 0 0 auto;
width: 100%;
height: auto;
aspect-ratio: 720 / 400;
}

Expand All @@ -167,26 +192,40 @@
width: calc(100% - 32px);
}

.featureImage {
order: -1;
aspect-ratio: 4 / 3;
/* One gap governs both sides of the shot, so heading-to-image and
image-to-description stay equal by construction. */
.card {
gap: 20px;
}

/* The artwork's own ratio, the same as desktop. A 4/3 stage cut roughly a
quarter of the width off every 1.8 screenshot, straight through the UI, and
the per-image object-position offsets below it were chasing that crop
rather than removing it. */
.shot {
aspect-ratio: 720 / 400;
border-radius: 12px;
object-fit: cover;
}

.featureImageTriage {
/* The review drawer is the triage story; keep it readable rather than
shrinking the entire 1440px console into a phone-width slot. */
object-position: 72% center;
/* Name the feature, show it, then explain it. display:contents drops .content
as a box so its two halves join the card's column and the shot can be
ordered between them. The orders are absolute rather than relative, so
every card reads the same way whichever side its art takes on desktop. */
.content {
display: contents;
}

.featureImageEvals {
/* Keeps the selected case and its run history in the crop. */
object-position: 58% center;
.headingGroup {
order: 1;
}

.content {
gap: 20px;
.shot,
.shotPlaceholder {
order: 2;
}

.bodyGroup {
order: 3;
}
}

Expand Down
Loading
Loading