diff --git a/docs/app/(home)/cloud/CloudCodeBlock.tsx b/docs/app/(home)/cloud/CloudCodeBlock.tsx
index 41976221f..cbc50518a 100644
--- a/docs/app/(home)/cloud/CloudCodeBlock.tsx
+++ b/docs/app/(home)/cloud/CloudCodeBlock.tsx
@@ -2,16 +2,11 @@
import { useTheme } from "next-themes";
import { Highlight, themes } from "prism-react-renderer";
-import { useEffect, useState } from "react";
import styles from "./CloudCodeBlock.module.css";
export function CloudCodeBlock({ code }: { code: string }) {
const { resolvedTheme } = useTheme();
- const [mounted, setMounted] = useState(false);
-
- useEffect(() => setMounted(true), []);
-
- const isDark = mounted && resolvedTheme === "dark";
+ const isDark = resolvedTheme === "dark";
return (
diff --git a/docs/app/(home)/cloud/CloudHero.tsx b/docs/app/(home)/cloud/CloudHero.tsx
new file mode 100644
index 000000000..0383033c7
--- /dev/null
+++ b/docs/app/(home)/cloud/CloudHero.tsx
@@ -0,0 +1,139 @@
+import { ArrowUpRight } from "lucide-react";
+import { BevelButton } from "../components/Button/BevelButton";
+import heroStyles from "../sections/HeroSection/HeroSection.module.css";
+import cloudStyles from "./page.module.css";
+
+function CloudCtas() {
+ return (
+
+ }
+ />
+ }
+ />
+
+ );
+}
+
+function CloudTitle() {
+ return (
+
+
+ OpenUI Cloud
+
+ API for running OpenUI in Production
+
+ );
+}
+
+function CloudSubtitle() {
+ return (
+
+ One API for models, fallbacks, validation, rendering, and observability.
+
+ );
+}
+
+function CloudPreview({ decorative = false }: { decorative?: boolean }) {
+ return (
+
+
+
+
+ );
+}
+
+export function CloudHero() {
+ return (
+
+ );
+}
diff --git a/docs/app/(home)/cloud/FeaturesSection.module.css b/docs/app/(home)/cloud/FeaturesSection.module.css
index c7c510369..f36b9ed3e 100644
--- a/docs/app/(home)/cloud/FeaturesSection.module.css
+++ b/docs/app/(home)/cloud/FeaturesSection.module.css
@@ -15,30 +15,21 @@
height: 400px;
}
-.featureImage {
+.featureMedia {
flex: 0 0 720px;
width: 720px;
height: 400px;
border-radius: 24px;
+ overflow: hidden;
}
.featureImage {
display: block;
+ width: 100%;
+ height: 100%;
object-fit: cover;
}
-.featureImageDark {
- display: none;
-}
-
-[data-theme="dark"] .featureImageLight {
- display: none;
-}
-
-[data-theme="dark"] .featureImageDark {
- display: block;
-}
-
.content {
display: flex;
flex: 0 0 400px;
@@ -107,7 +98,7 @@
height: auto;
}
- .featureImage {
+ .featureMedia {
flex: 0 0 auto;
width: 100%;
height: auto;
@@ -131,7 +122,7 @@
padding-inline: var(--home-section-padding-inline);
}
- .featureImage {
+ .featureMedia {
order: -1;
border-radius: 12px;
}
diff --git a/docs/app/(home)/cloud/FeaturesSection.tsx b/docs/app/(home)/cloud/FeaturesSection.tsx
index 3be69c4c7..377e41fa9 100644
--- a/docs/app/(home)/cloud/FeaturesSection.tsx
+++ b/docs/app/(home)/cloud/FeaturesSection.tsx
@@ -1,5 +1,4 @@
import { Button } from "@/components/button";
-import Image from "next/image";
import type { ReactNode } from "react";
import {
FeatureGridSection,
@@ -64,21 +63,23 @@ export function FeaturesSection() {
<>
-
-
+
+
+
+
-
-
+
+
+
+
-
-
+
+
+
+
{
+ const root = document.documentElement;
+
+ const syncSources = () => {
+ const dark = root.dataset.theme === "dark";
+ const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
+ const media =
+ dark === prefersDark ? "(prefers-color-scheme: dark)" : dark ? "all" : "not all";
+
+ document
+ .querySelectorAll("source[data-theme-source]")
+ .forEach((source) => {
+ if (source.media !== media) source.media = media;
+ });
+ };
+
+ syncSources();
+
+ const observer = new MutationObserver(syncSources);
+ observer.observe(root, {
+ attributes: true,
+ attributeFilter: ["data-theme"],
+ });
+
+ return () => observer.disconnect();
+ }, []);
+
+ return null;
+}
diff --git a/docs/app/(home)/cloud/page.module.css b/docs/app/(home)/cloud/page.module.css
index 3bdb0fb50..2049e929d 100644
--- a/docs/app/(home)/cloud/page.module.css
+++ b/docs/app/(home)/cloud/page.module.css
@@ -63,18 +63,6 @@
height: auto;
}
-.heroImageDark {
- display: none;
-}
-
-[data-theme="dark"] .heroImageLight {
- display: none;
-}
-
-[data-theme="dark"] .heroImageDark {
- display: block;
-}
-
@media (max-width: 1023px) {
.title {
font-size: inherit;
diff --git a/docs/app/(home)/cloud/page.tsx b/docs/app/(home)/cloud/page.tsx
index 74a0943a3..526888128 100644
--- a/docs/app/(home)/cloud/page.tsx
+++ b/docs/app/(home)/cloud/page.tsx
@@ -1,17 +1,14 @@
-import { ArrowUpRight } from "lucide-react";
import type { Metadata } from "next";
-import Image from "next/image";
-import { BevelButton } from "../components/Button/BevelButton";
import styles from "../page.module.css";
import { Footer } from "../sections/Footer/Footer";
-import { HeroSection } from "../sections/HeroSection/HeroSection";
import { LogoStrip } from "../sections/LogoStrip/LogoStrip";
import { CloudCtaSection } from "./CloudCtaSection";
+import { CloudHero } from "./CloudHero";
import { CloudIntegrationSection } from "./CloudIntegrationSection";
import { ComparisonSection } from "./ComparisonSection";
import { EnterpriseSection } from "./EnterpriseSection";
import { FeaturesSection } from "./FeaturesSection";
-import cloudStyles from "./page.module.css";
+import { ThemeImageController } from "./ThemeImageController";
export const metadata: Metadata = {
title: "OpenUI Cloud - Managed Generative UI Infrastructure",
@@ -44,99 +41,20 @@ export const metadata: Metadata = {
export default function OpenUICloudPage() {
return (
-
-
-
-
- OpenUI Cloud
-
- API for running OpenUI in Production
-
- }
- subtitle={
-
- One API for models, fallbacks, validation, rendering, and observability.
-
- }
- smallSubtitle
- tightDesktopSpacing={false}
- splitLockup
- flushInnerInlinePadding
- commandSlot={
-
- }
- />
- }
- />
-
- }
- showPlaygroundButton={false}
- showGitHubBanner={false}
- showTagline={false}
- desktopPreviewSlot={
- <>
-
-
- >
- }
- mobilePreviewSlot={
- <>
-
-
- >
- }
- />
-
-
-
-
-
-
-
+ <>
+
+
+
+
+
+
+
+
+
+
+
-
+
+ >
);
}
diff --git a/docs/app/(home)/globals.css b/docs/app/(home)/globals.css
index 41e11f1a6..90bb8ea02 100644
--- a/docs/app/(home)/globals.css
+++ b/docs/app/(home)/globals.css
@@ -1,4 +1,9 @@
.homeTheme {
+ /* The component-library secondary/tertiary defaults are intended for disabled
+ UI and fall below WCAG contrast when used as marketing copy. */
+ --openui-text-neutral-secondary: #676767;
+ --openui-text-neutral-tertiary: #676767;
+
--home-color-text-primary: var(--text-neutral-primary);
--home-color-text-inverse: var(--text-accent-primary);
--home-color-text-muted: var(--text-neutral-secondary);
@@ -109,5 +114,7 @@
/* Dark mode: flip the few hardcoded marketing surfaces/hairlines that don't ride
on the --openui-* / --text-* tokens (those adapt automatically). */
[data-theme="dark"] .homeTheme {
+ --openui-text-neutral-secondary: #aaa;
+ --openui-text-neutral-tertiary: #aaa;
--home-hairline: rgba(255, 255, 255, 0.07);
}
diff --git a/docs/app/(home)/sections/LogoStrip/LogoStrip.tsx b/docs/app/(home)/sections/LogoStrip/LogoStrip.tsx
index a3e319c3b..ea84aab62 100644
--- a/docs/app/(home)/sections/LogoStrip/LogoStrip.tsx
+++ b/docs/app/(home)/sections/LogoStrip/LogoStrip.tsx
@@ -22,10 +22,10 @@ const HOME_LOGOS: Logo[] = [
const CLOUD_LOGOS: Logo[] = [
{ src: "/logos/entelligence.svg", alt: "Entelligence" },
- { src: "/logos/pointlabs.svg", alt: "Pointlabs" },
+ { src: "/logos/pointlabs.webp", alt: "Pointlabs" },
{ src: "/logos/wisdom.svg", alt: "Wisdom" },
{ src: "/logos/mili.svg", alt: "Mili" },
- { src: "/logos/ficell-labs.svg", alt: "Ficell Labs" },
+ { src: "/logos/ficell-labs.webp", alt: "Ficell Labs" },
];
/* The track holds SETS copies of the logo list and animates by -50%, so the
diff --git a/docs/public/logos/ficell-labs.webp b/docs/public/logos/ficell-labs.webp
new file mode 100644
index 000000000..687e3ddfe
Binary files /dev/null and b/docs/public/logos/ficell-labs.webp differ
diff --git a/docs/public/logos/pointlabs.webp b/docs/public/logos/pointlabs.webp
new file mode 100644
index 000000000..cc6c85c47
Binary files /dev/null and b/docs/public/logos/pointlabs.webp differ
diff --git a/docs/public/openui-cloud/hero-dark-1280.webp b/docs/public/openui-cloud/hero-dark-1280.webp
new file mode 100644
index 000000000..ba9707902
Binary files /dev/null and b/docs/public/openui-cloud/hero-dark-1280.webp differ
diff --git a/docs/public/openui-cloud/hero-dark-720.webp b/docs/public/openui-cloud/hero-dark-720.webp
new file mode 100644
index 000000000..6ef22d052
Binary files /dev/null and b/docs/public/openui-cloud/hero-dark-720.webp differ
diff --git a/docs/public/openui-cloud/hero-dark.svg b/docs/public/openui-cloud/hero-dark.svg
index 36bd99e10..538e130b2 100644
--- a/docs/public/openui-cloud/hero-dark.svg
+++ b/docs/public/openui-cloud/hero-dark.svg
@@ -1,327 +1 @@
-
+
\ No newline at end of file
diff --git a/docs/public/openui-cloud/hero-light-1280.webp b/docs/public/openui-cloud/hero-light-1280.webp
new file mode 100644
index 000000000..b37cd6d20
Binary files /dev/null and b/docs/public/openui-cloud/hero-light-1280.webp differ
diff --git a/docs/public/openui-cloud/hero-light-720.webp b/docs/public/openui-cloud/hero-light-720.webp
new file mode 100644
index 000000000..d5f459b0b
Binary files /dev/null and b/docs/public/openui-cloud/hero-light-720.webp differ
diff --git a/docs/public/openui-cloud/hero-light.svg b/docs/public/openui-cloud/hero-light.svg
index 2190d7936..706a2bfa3 100644
--- a/docs/public/openui-cloud/hero-light.svg
+++ b/docs/public/openui-cloud/hero-light.svg
@@ -1,340 +1 @@
-
+
\ No newline at end of file
diff --git a/docs/public/openui-cloud/llm-gateway-dark.svg b/docs/public/openui-cloud/llm-gateway-dark.svg
index 278c2348b..5e3e44669 100644
--- a/docs/public/openui-cloud/llm-gateway-dark.svg
+++ b/docs/public/openui-cloud/llm-gateway-dark.svg
@@ -1,88 +1 @@
-
+
\ No newline at end of file
diff --git a/docs/public/openui-cloud/llm-gateway-dark.webp b/docs/public/openui-cloud/llm-gateway-dark.webp
new file mode 100644
index 000000000..6a9394306
Binary files /dev/null and b/docs/public/openui-cloud/llm-gateway-dark.webp differ
diff --git a/docs/public/openui-cloud/llm-gateway.svg b/docs/public/openui-cloud/llm-gateway.svg
index 58fdc14fb..6fb876fb5 100644
--- a/docs/public/openui-cloud/llm-gateway.svg
+++ b/docs/public/openui-cloud/llm-gateway.svg
@@ -1,92 +1 @@
-
+
\ No newline at end of file
diff --git a/docs/public/openui-cloud/llm-gateway.webp b/docs/public/openui-cloud/llm-gateway.webp
new file mode 100644
index 000000000..bb839cca6
Binary files /dev/null and b/docs/public/openui-cloud/llm-gateway.webp differ
diff --git a/docs/public/openui-cloud/reports-dark-1440.webp b/docs/public/openui-cloud/reports-dark-1440.webp
new file mode 100644
index 000000000..e7448b0c0
Binary files /dev/null and b/docs/public/openui-cloud/reports-dark-1440.webp differ
diff --git a/docs/public/openui-cloud/reports-dark-720.webp b/docs/public/openui-cloud/reports-dark-720.webp
new file mode 100644
index 000000000..286a4bde2
Binary files /dev/null and b/docs/public/openui-cloud/reports-dark-720.webp differ
diff --git a/docs/public/openui-cloud/reports-light-1440.webp b/docs/public/openui-cloud/reports-light-1440.webp
new file mode 100644
index 000000000..540b2758f
Binary files /dev/null and b/docs/public/openui-cloud/reports-light-1440.webp differ
diff --git a/docs/public/openui-cloud/reports-light-720.webp b/docs/public/openui-cloud/reports-light-720.webp
new file mode 100644
index 000000000..d612e352e
Binary files /dev/null and b/docs/public/openui-cloud/reports-light-720.webp differ
diff --git a/docs/public/openui-cloud/validation-dark.svg b/docs/public/openui-cloud/validation-dark.svg
index 899fd98c9..e2fd9a804 100644
--- a/docs/public/openui-cloud/validation-dark.svg
+++ b/docs/public/openui-cloud/validation-dark.svg
@@ -1,80 +1 @@
-
+
\ No newline at end of file
diff --git a/docs/public/openui-cloud/validation.svg b/docs/public/openui-cloud/validation.svg
index ee57c1892..ba80fc79b 100644
--- a/docs/public/openui-cloud/validation.svg
+++ b/docs/public/openui-cloud/validation.svg
@@ -1,80 +1 @@
-
+
\ No newline at end of file