From a3a7634f831a9f2cde76c19f34b3a9cbefad4e04 Mon Sep 17 00:00:00 2001 From: rahul Date: Wed, 16 Sep 2026 17:43:24 +0530 Subject: [PATCH] feat(docs): add Autofix marketing banner --- docs/app/(home)/cloud/gateway/page.tsx | 2 + .../(home)/cloud/gateway/sections.module.css | 8 +- docs/app/(home)/globals.css | 1 + docs/app/(home)/page.module.css | 6 +- .../AutofixSection/AutofixSection.module.css | 229 ++++++++++++++++++ .../AutofixSection/AutofixSection.tsx | 45 ++++ .../CloudSection/CloudSection.module.css | 6 +- .../sections/CloudSection/CloudSection.tsx | 3 + .../sections/FaqSection/FaqSection.module.css | 2 + .../ProductSection/ProductSection.module.css | 8 +- .../sections/ProductSection/products.ts | 4 +- .../TweetWallSection.module.css | 6 +- 12 files changed, 299 insertions(+), 21 deletions(-) create mode 100644 docs/app/(home)/sections/AutofixSection/AutofixSection.module.css create mode 100644 docs/app/(home)/sections/AutofixSection/AutofixSection.tsx diff --git a/docs/app/(home)/cloud/gateway/page.tsx b/docs/app/(home)/cloud/gateway/page.tsx index bbe68e287..5f45cb3cf 100644 --- a/docs/app/(home)/cloud/gateway/page.tsx +++ b/docs/app/(home)/cloud/gateway/page.tsx @@ -2,6 +2,7 @@ import { ArrowUpRight } from "lucide-react"; import type { Metadata } from "next"; import { BevelButton } from "../../components/Button/BevelButton"; import styles from "../../page.module.css"; +import { AutofixSection } from "../../sections/AutofixSection/AutofixSection"; import { Footer } from "../../sections/Footer/Footer"; import { HeroSection } from "../../sections/HeroSection/HeroSection"; import { GatewayReliabilityIllustration } from "../../sections/ProductIllustrations/ProductIllustrations"; @@ -96,6 +97,7 @@ export default function GatewayPage() {
+
diff --git a/docs/app/(home)/cloud/gateway/sections.module.css b/docs/app/(home)/cloud/gateway/sections.module.css index 43741e34d..eba56a334 100644 --- a/docs/app/(home)/cloud/gateway/sections.module.css +++ b/docs/app/(home)/cloud/gateway/sections.module.css @@ -3,7 +3,7 @@ width: 100%; max-width: var(--home-container-max); margin-inline: auto; - padding-inline: var(--home-section-padding-inline); + padding-inline: var(--home-container-gutter); } .problemSection { @@ -11,7 +11,7 @@ } .repairSection { - padding-bottom: 160px; + padding-bottom: 64px; } .sectionLockup { @@ -397,7 +397,7 @@ section.usageSection { } .repairSection { - padding-bottom: 112px; + padding-bottom: 48px; } .pricingBand { @@ -457,7 +457,7 @@ section.usageSection { } .repairSection { - padding-bottom: 96px; + padding-bottom: 48px; } .pricingBand { diff --git a/docs/app/(home)/globals.css b/docs/app/(home)/globals.css index 41e11f1a6..5e017629b 100644 --- a/docs/app/(home)/globals.css +++ b/docs/app/(home)/globals.css @@ -21,6 +21,7 @@ /* Layout container */ --home-container-max: 75rem; --home-container-wide: 90rem; + --home-container-gutter: clamp(1.25rem, 4vw, 2.5rem); --home-section-padding-inline: 1.25rem; /* Marketing surfaces / borders / shadows */ diff --git a/docs/app/(home)/page.module.css b/docs/app/(home)/page.module.css index 754acae83..17478f110 100644 --- a/docs/app/(home)/page.module.css +++ b/docs/app/(home)/page.module.css @@ -28,7 +28,7 @@ and Observability bands below it rather than sitting 40px wider. */ max-width: var(--home-container-max); margin-inline: auto; - padding-inline: clamp(1.25rem, 4vw, 2.5rem); + padding-inline: var(--home-container-gutter); } /* NB: both breakpoints below override this gap, so editing it here has no @@ -84,10 +84,6 @@ gap: 7rem; padding-block: 4rem; } - - .faqBand { - padding-inline: 1.25rem; - } } /* Keep the main page field solid in both themes. */ diff --git a/docs/app/(home)/sections/AutofixSection/AutofixSection.module.css b/docs/app/(home)/sections/AutofixSection/AutofixSection.module.css new file mode 100644 index 000000000..ca34489bc --- /dev/null +++ b/docs/app/(home)/sections/AutofixSection/AutofixSection.module.css @@ -0,0 +1,229 @@ +.section { + --autofix-text: var(--openui-text-neutral-primary); + --autofix-muted: var(--openui-text-neutral-secondary); + --autofix-surface: #fff; + --autofix-border: var(--home-hairline); + + box-sizing: border-box; + width: 100%; + max-width: var(--home-container-max); + margin: clamp(4.5rem, 8vw, 6.5rem) auto; + color: var(--autofix-text); +} + +.section:not(.cloud) { + margin-top: clamp(1.25rem, 2vw, 2rem); + margin-bottom: clamp(7.5rem, 10vw, 9rem); + padding-inline: var(--home-container-gutter); +} + +.cloud { + --autofix-text: #fff; + --autofix-muted: rgba(255, 255, 255, 0.58); + --autofix-surface: rgba(255, 255, 255, 0.042); + --autofix-border: rgba(255, 255, 255, 0.075); +} + +.banner { + position: relative; + display: grid; + grid-template-columns: minmax(22rem, 0.9fr) minmax(0, 1.1fr); + align-items: stretch; + overflow: hidden; + min-height: 13.5rem; + border: 1px solid var(--autofix-border); + border-radius: 20px; + background: var(--autofix-surface); +} + +.copy { + position: relative; + z-index: 1; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + min-width: 0; + padding: clamp(1.375rem, 2.4vw, 2rem); +} + +.title { + max-width: 18ch; + margin: 0; + font-family: var(--home-font-display); + font-size: clamp(1rem, 1.5vw, 1.375rem); + font-weight: var(--home-title-weight); + line-height: 1.08; + letter-spacing: -0.02em; + text-wrap: balance; +} + +.titleLine { + display: block; + white-space: nowrap; +} + +.description { + max-width: 31rem; + margin: 0.75rem 0 0; + font-family: var(--home-font-text); + font-size: 0.9375rem; + line-height: 1.5; + color: var(--autofix-muted); + text-wrap: pretty; +} + +.descriptionLine { + display: block; +} + +.cta { + width: fit-content; + max-width: none; + margin-top: 1rem; +} + +.cloud .cta { + background: #0a0a0a; + border-color: rgba(255, 255, 255, 0.12); + box-shadow: var(--home-bevel-on-dark); + color: #fff; + --bevel-badge-bg: #fff; + --bevel-badge-fg: #0a0a0a; +} + +.visual { + position: relative; + display: flex; + align-items: center; + justify-content: flex-end; + align-self: stretch; + overflow: hidden; + min-width: 0; +} + +.illustration { + position: absolute; + top: 50%; + right: 0; + display: block; + width: calc(100% - 12px); + aspect-ratio: 3 / 1; + transform: translateY(-50%); + background-image: + url("https://www.thesys.dev/homepage-may26/openui-api/error-correction.svg?v=20260524-2"), + url("https://www.thesys.dev/homepage-may26/openui-api/error-correction.svg?v=20260524-2"); + background-position: + left center, + left center; + background-repeat: no-repeat; + background-size: contain, contain; +} + +.section:not(.cloud) .illustration { + background-image: + url("https://www.thesys.dev/homepage-may26/openui-api/error-correction.svg?v=20260524-2"), + url("https://www.thesys.dev/homepage-may26/openui-api/error-correction.svg?v=20260524-2"); + background-position: + left center, + left center; + background-size: contain, contain; + filter: invert(1) hue-rotate(180deg) saturate(1.55) contrast(0.92) brightness(1.14); +} + +[data-theme="dark"] .section:not(.cloud) { + --autofix-surface: rgba(255, 255, 255, 0.042); + --autofix-border: rgba(255, 255, 255, 0.075); +} + +[data-theme="dark"] .section:not(.cloud) .illustration { + background-image: + url("https://www.thesys.dev/homepage-may26/openui-api/error-correction.svg?v=20260524-2"), + url("https://www.thesys.dev/homepage-may26/openui-api/error-correction.svg?v=20260524-2"); + background-position: + left center, + left center; + background-size: contain, contain; + filter: none; +} + +[data-theme="dark"] .cloud { + --autofix-text: #0a0a0a; + --autofix-muted: rgba(10, 10, 10, 0.58); + --autofix-surface: #fff; + --autofix-border: rgba(10, 10, 10, 0.075); +} + +[data-theme="dark"] .cloud .illustration { + background-image: + url("https://www.thesys.dev/homepage-may26/openui-api/error-correction.svg?v=20260524-2"), + url("https://www.thesys.dev/homepage-may26/openui-api/error-correction.svg?v=20260524-2"); + background-position: + left center, + left center; + background-size: contain, contain; + filter: invert(1) hue-rotate(180deg) saturate(1.55) contrast(0.92) brightness(1.14); +} + +[data-theme="dark"] .cloud .cta { + background: var(--home-surface-raised); + border-color: rgba(0, 0, 0, 0.08); + box-shadow: var(--home-bevel); + color: #0a0a0a; + --bevel-badge-bg: #0a0a0a; + --bevel-badge-fg: #fff; +} + +@media (max-width: 900px) { + .banner { + grid-template-columns: minmax(20rem, 0.95fr) minmax(0, 1.05fr); + } +} + +@media (max-width: 767px) { + .section { + margin-block: 4rem; + } + + .section:not(.cloud) { + margin-top: 1.5rem; + margin-bottom: 6rem; + } + + .banner { + grid-template-columns: minmax(0, 1fr); + min-height: 0; + border-radius: 18px; + } + + .copy { + padding: 1.375rem; + } + + .title { + max-width: 20ch; + font-size: 18px; + font-weight: 500; + line-height: 1.25; + letter-spacing: -0.01em; + } + + .description { + margin-top: 8px; + font-size: 14px; + line-height: 21px; + } + + .descriptionLine { + display: inline; + white-space: nowrap; + } + + .visual { + min-height: 8rem; + } + + .illustration { + width: calc(100% - 12px); + } +} diff --git a/docs/app/(home)/sections/AutofixSection/AutofixSection.tsx b/docs/app/(home)/sections/AutofixSection/AutofixSection.tsx new file mode 100644 index 000000000..d9bc41f51 --- /dev/null +++ b/docs/app/(home)/sections/AutofixSection/AutofixSection.tsx @@ -0,0 +1,45 @@ +import { ArrowRight } from "@phosphor-icons/react/dist/ssr"; +import { BevelButton } from "../../components/Button/BevelButton"; +import styles from "./AutofixSection.module.css"; + +export function AutofixSection({ + tone = "page", + headingLevel = "h2", +}: { + tone?: "page" | "cloud"; + headingLevel?: "h2" | "h3"; +}) { + const Heading = headingLevel; + + return ( +
+
+
+ + Already have a model stack? + Add the repair layer. + +

+ Autofix fixes invalid generations before users see them, + with one API call. +

+ } + /> +
+ +
+
+
+
+ ); +} diff --git a/docs/app/(home)/sections/CloudSection/CloudSection.module.css b/docs/app/(home)/sections/CloudSection/CloudSection.module.css index 2b3d2394c..4b607245a 100644 --- a/docs/app/(home)/sections/CloudSection/CloudSection.module.css +++ b/docs/app/(home)/sections/CloudSection/CloudSection.module.css @@ -12,7 +12,7 @@ box-sizing: border-box; max-width: var(--home-container-max); margin-inline: auto; - padding-inline: clamp(1.25rem, 4vw, 2.5rem); + padding-inline: var(--home-container-gutter); } @keyframes cloudMarquee { @@ -25,8 +25,8 @@ } /* Closing contact CTA below the ticker. */ -/* The two product bands. Only the space between them lives here; .header's - bottom margin and .contact's top margin bound the group. */ +/* The Gateway product band. AutoFix and Observability carry their own spacing + because they use different compositions below it. */ .products { display: flex; flex-direction: column; diff --git a/docs/app/(home)/sections/CloudSection/CloudSection.tsx b/docs/app/(home)/sections/CloudSection/CloudSection.tsx index 0f3502fa4..fca54e5af 100644 --- a/docs/app/(home)/sections/CloudSection/CloudSection.tsx +++ b/docs/app/(home)/sections/CloudSection/CloudSection.tsx @@ -3,6 +3,7 @@ import { ArrowRight } from "@phosphor-icons/react/dist/ssr"; import Image from "next/image"; import { BevelButton } from "../../components/Button/BevelButton"; import { SectionHeader } from "../../components/SectionHeader/SectionHeader"; +import { AutofixSection } from "../AutofixSection/AutofixSection"; import { ProductLabel, ProductSection } from "../ProductSection/ProductSection"; import { GATEWAY_PRODUCT } from "../ProductSection/products"; import styles from "./CloudSection.module.css"; @@ -33,6 +34,8 @@ export function CloudSection() {
+ +
diff --git a/docs/app/(home)/sections/FaqSection/FaqSection.module.css b/docs/app/(home)/sections/FaqSection/FaqSection.module.css index 36e13644e..bd2f48a55 100644 --- a/docs/app/(home)/sections/FaqSection/FaqSection.module.css +++ b/docs/app/(home)/sections/FaqSection/FaqSection.module.css @@ -12,9 +12,11 @@ /* On top of the content shell's own gap: the FAQ closes the page and wants more separation from the wall of tweets above it. */ margin-top: clamp(3rem, 6vw, 5.5rem); + box-sizing: border-box; width: 100%; max-width: var(--home-container-max); margin-inline: auto; + padding-inline: var(--home-container-gutter); color: var(--faq-text); } diff --git a/docs/app/(home)/sections/ProductSection/ProductSection.module.css b/docs/app/(home)/sections/ProductSection/ProductSection.module.css index 27c16834d..b857fc82c 100644 --- a/docs/app/(home)/sections/ProductSection/ProductSection.module.css +++ b/docs/app/(home)/sections/ProductSection/ProductSection.module.css @@ -219,7 +219,8 @@ font-size: 18px; font-weight: 500; letter-spacing: -0.2px; - line-height: normal; + line-height: 1.25; + text-wrap: balance; } .cardDescription { @@ -259,9 +260,7 @@ } .cards { - grid-template-columns: none; - grid-auto-columns: clamp(15.5rem, 76vw, 18rem); - grid-auto-flow: column; + display: flex; justify-content: start; overflow-x: auto; overscroll-behavior-inline: contain; @@ -277,6 +276,7 @@ } .card { + flex: 0 0 clamp(15.5rem, 76vw, 18rem); scroll-snap-align: start; scroll-snap-stop: always; } diff --git a/docs/app/(home)/sections/ProductSection/products.ts b/docs/app/(home)/sections/ProductSection/products.ts index 61e7d94b4..3813f45c5 100644 --- a/docs/app/(home)/sections/ProductSection/products.ts +++ b/docs/app/(home)/sections/ProductSection/products.ts @@ -87,8 +87,8 @@ export const GATEWAY_PRODUCT: ProductSectionProps = { }, { Icon: ArrowsClockwise, - title: "Stay online through outages", - description: "Gateway switches providers if one fails, keeping the same model.", + title: "Switch providers on failure", + description: "Gateway retries the same model with another provider.", }, { Icon: Key, diff --git a/docs/app/(home)/sections/TweetWallSection/TweetWallSection.module.css b/docs/app/(home)/sections/TweetWallSection/TweetWallSection.module.css index 555e539d9..d5daf81d7 100644 --- a/docs/app/(home)/sections/TweetWallSection/TweetWallSection.module.css +++ b/docs/app/(home)/sections/TweetWallSection/TweetWallSection.module.css @@ -1,10 +1,10 @@ .section { - width: min(100%, var(--home-container-wide)); + width: min(100%, var(--home-container-max)); /* On top of the content shell's own gap: this follows the black Cloud band and needs more room than a gap between two light sections. */ margin-top: clamp(3rem, 6vw, 5.5rem); margin-inline: auto; - padding-inline: 1.25rem; + padding-inline: var(--home-container-gutter); box-sizing: border-box; } @@ -72,6 +72,6 @@ @media (min-width: 1024px) { .section { - padding-inline: 2rem; + padding-inline: var(--home-container-gutter); } }