diff --git a/public/images/integrations/claude-managed-agents-dark.webp b/public/images/integrations/claude-managed-agents-dark.webp new file mode 100644 index 0000000..c8e2d6d Binary files /dev/null and b/public/images/integrations/claude-managed-agents-dark.webp differ diff --git a/public/images/integrations/claude-managed-agents-light.webp b/public/images/integrations/claude-managed-agents-light.webp new file mode 100644 index 0000000..176ff87 Binary files /dev/null and b/public/images/integrations/claude-managed-agents-light.webp differ diff --git a/src/components/react/ThemeImage.tsx b/src/components/react/ThemeImage.tsx new file mode 100644 index 0000000..e23e096 --- /dev/null +++ b/src/components/react/ThemeImage.tsx @@ -0,0 +1,58 @@ +import type { CSSProperties } from 'react'; + +interface ThemeImageProps { + /** Image shown in light mode. */ + light: string; + /** Image shown in dark mode. */ + dark: string; + alt: string; + width?: number | string; + height?: number | string; + className?: string; + style?: CSSProperties; +} + +/** + * Renders a light and dark version of an image and swaps between them based on + * the active `data-theme`. The swap is pure CSS (see custom.css), so there's no + * hydration flash — both ``s are in the DOM and only one is displayed. + * + * The images carry their own alpha channel (the flat canvas is keyed out to + * transparency), so the artwork floats on any surface — page body, nav, a + * callout, the dark-mode ambient texture. That's why this uses transparency + * rather than `mix-blend-mode`: a blend only melts into a flat backdrop in the + * same stacking context and leaves a seam anywhere the surface isn't that exact + * color. + */ +export function ThemeImage({ + light, + dark, + alt, + width, + height, + className, + style, +}: ThemeImageProps) { + return ( + + {alt} + + + ); +} diff --git a/src/components/react/index.ts b/src/components/react/index.ts index 0632b77..5309a73 100644 --- a/src/components/react/index.ts +++ b/src/components/react/index.ts @@ -36,4 +36,5 @@ export { SearchDialog } from './SearchDialog'; export { SearchDialogWrapper } from './SearchDialogWrapper'; export { StatusBadge, StatusCodes } from './StatusCodes'; export { StatusIcon } from './StatusIcon'; +export { ThemeImage } from './ThemeImage'; export { ThemeSwitcher } from './ThemeSwitcher'; diff --git a/src/content/docs/integrations/claude-managed-agents.mdx b/src/content/docs/integrations/claude-managed-agents.mdx index 639b95e..a2e61d6 100644 --- a/src/content/docs/integrations/claude-managed-agents.mdx +++ b/src/content/docs/integrations/claude-managed-agents.mdx @@ -3,8 +3,7 @@ title: Claude Managed Agents description: Run Anthropic Claude Managed Agents with tool execution inside your own Sprites --- -import { Callout } from '@/components/react'; -import SelfHostedDiagram from '@/components/SelfHostedDiagram.astro'; +import { Callout, ThemeImage } from '@/components/react'; import { Tabs, TabItem } from '@astrojs/starlight/components'; + The runner authenticates with an **environment key**, the only credential it needs for both the control plane and the per-session calls. Your organization API key never reaches the Sprite. diff --git a/src/styles/custom.css b/src/styles/custom.css index 5b6287d..7a204a1 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -2135,3 +2135,26 @@ h2.method-title { --co-decoration-hover: #1e3a8a99; --co-link-hover: #172554; } + +/* Theme-aware image swap (ThemeImage component) + Both variants render into the DOM; CSS shows the one matching the active + theme. The images have transparent (keyed) backgrounds, so the artwork floats + on any surface with no blend mode or matching backdrop needed. */ +.theme-image-frame { + display: block; + line-height: 0; +} +.theme-image { + display: block; + width: 100%; + height: auto; +} +.theme-image--dark { + display: none; +} +[data-theme='dark'] .theme-image--light { + display: none; +} +[data-theme='dark'] .theme-image--dark { + display: block; +}