diff --git a/packages/devtools/src/inspect/ReactLangStreamEventRow.tsx b/packages/devtools/src/inspect/ReactLangStreamEventRow.tsx
index 34294f176..fa0ad9aef 100644
--- a/packages/devtools/src/inspect/ReactLangStreamEventRow.tsx
+++ b/packages/devtools/src/inspect/ReactLangStreamEventRow.tsx
@@ -104,6 +104,8 @@ export function ReactLangStreamEventRow({
};
const openInDebugDisabled = isStreaming || !stream.response || !canOpenInDebug;
+ const hasOverview =
+ visibleErrors.length > 0 || statementCount !== undefined || orphaned.length > 0;
return (
-
- {visibleErrors.length > 0 ? (
-
- error{visibleErrors.length === 1 ? "" : "s"}
-
- ) : null}
- {statementCount !== undefined ? (
- statement{statementCount === 1 ? "" : "s"}
- ) : null}
- {orphaned.length > 0 ? (
-
- orphaned statement{orphaned.length === 1 ? "" : "s"}
-
- ) : null}
-
+ {hasOverview ? (
+
+ {visibleErrors.length > 0 ? (
+
+ error{visibleErrors.length === 1 ? "" : "s"}
+
+ ) : null}
+ {statementCount !== undefined ? (
+ statement{statementCount === 1 ? "" : "s"}
+ ) : null}
+ {orphaned.length > 0 ? (
+
+ orphaned statement{orphaned.length === 1 ? "" : "s"}
+
+ ) : null}
+
+ ) : null}
{expanded ? (
diff --git a/packages/devtools/src/ui/ReliabilityBanner.tsx b/packages/devtools/src/ui/ReliabilityBanner.tsx
index 4663b7efc..25f198f3c 100644
--- a/packages/devtools/src/ui/ReliabilityBanner.tsx
+++ b/packages/devtools/src/ui/ReliabilityBanner.tsx
@@ -1,38 +1,60 @@
+import { Check, CircleAlert } from "lucide-react";
import { CSSProperties, useState } from "react";
import { withDevtoolsAttribution } from "../lib/links";
import { ColorMode, FONT, theme, ThemeTokens } from "../theme";
+const FEATURES = [
+ "Automatically fix 88% of the errors",
+ "Track requests & generations for free",
+] as const;
+
export default function ReliabilityBanner({ themeMode }: { themeMode: ColorMode }) {
const [bannerHovered, setBannerHovered] = useState(false);
- const styles = bannerStyles(theme(themeMode));
+ const tokens = theme(themeMode);
+ const styles = bannerStyles(tokens);
return (
);
}
@@ -47,7 +69,7 @@ const bannerStyles = (t: ThemeTokens) =>
gap: 8,
flexShrink: 0,
background: t.bg,
- padding: "12px 12px 18px",
+ padding: "6px",
},
fade: {
position: "absolute",
@@ -60,39 +82,102 @@ const bannerStyles = (t: ThemeTokens) =>
},
banner: {
display: "flex",
- alignItems: "center",
- justifyContent: "space-between",
- gap: 12,
+ flexDirection: "column",
+ alignItems: "stretch",
flexShrink: 0,
- textDecoration: "none",
+ overflow: "hidden",
+ border: `1px solid ${t.border}`,
borderRadius: 12,
- background: t.promoBg,
+ background: t.card,
+ boxShadow: t.shadowSubtle,
color: t.fg,
- cursor: "pointer",
fontFamily: FONT,
textAlign: "left",
- padding: "12px 14px",
+ padding: "6px",
+ },
+ title: {
+ display: "flex",
+ alignItems: "flex-start",
+ gap: 8,
+ background: t.dangerBg,
+ color: t.danger,
+ fontSize: 13,
+ fontWeight: 600,
+ lineHeight: 1.3,
+ padding: "8px 16px 8px 8px",
+ borderRadius: 8,
},
- text: {
+ body: {
display: "flex",
flexDirection: "column",
+ gap: 12,
+ padding: "18px 12px 12px 12px",
},
- title: {
+ featuresWrapper: {
+ display: "flex",
+ flexDirection: "column",
+ gap: 6,
+ },
+ alertTile: {
+ display: "inline-flex",
+ alignItems: "center",
+ justifyContent: "center",
+ flexShrink: 0,
+ width: 18,
+ height: 18,
+ marginTop: 1,
+ borderRadius: 5,
+ background: t.danger,
+ color: t.dangerBg,
+ },
+ statement: {
fontSize: 12,
- fontWeight: 500,
+ fontWeight: 600,
+ lineHeight: 1.35,
},
- bannerAction: {
+ features: {
+ display: "flex",
+ flexDirection: "column",
+ gap: 6,
+ margin: 0,
+ padding: 0,
+ listStyle: "none",
+ },
+ feature: {
+ display: "flex",
+ alignItems: "center",
+ gap: 8,
+ color: t.fg,
+ fontSize: 12,
+ lineHeight: 1.35,
+ },
+ checkTile: {
display: "inline-flex",
alignItems: "center",
justifyContent: "center",
flexShrink: 0,
- border: `1px solid ${t.controlBorder}`,
+ width: 18,
+ height: 18,
+ borderRadius: 5,
+ background: t.successBg,
+ },
+ check: {
+ color: t.success,
+ },
+ bannerAction: {
+ display: "inline-flex",
+ alignItems: "center",
+ justifyContent: "center",
+ alignSelf: "flex-start",
+ marginTop: 8,
+ textDecoration: "none",
+ border: `1px solid ${t.inverted}`,
borderRadius: 8,
- background: t.controlBg,
- color: t.fg,
- boxShadow: t.shadowSubtle,
+ background: t.inverted,
+ color: t.invertedFg,
fontSize: 11,
- padding: "5px 12px",
+ fontWeight: 500,
+ padding: "7px 12px",
transition: "transform 150ms ease",
},
bannerActionHover: {