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
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
.feature-bento-card {
position: relative;
display: flex;
flex-direction: column;
padding: 10px;
border-radius: var(--radius-4);
border: 1px solid var(--gray-a4);
background: var(--color-panel-solid);
transition:
border-color 0.25s ease,
transform 0.25s ease,
box-shadow 0.25s ease;
overflow: hidden;
cursor: default;
user-select: none;
}

.feature-bento-card:hover,
.feature-bento-card--active {
border-color: var(--accent-a7);
transform: translateY(-2px);
box-shadow:
0 1px 0 0 var(--gray-a3) inset,
0 8px 24px -12px var(--accent-a4);
}

.feature-bento-card__placeholder {
position: relative;
flex: 1 1 0;
min-height: 0;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-3);
border: 1px dashed var(--gray-a5);
background:
radial-gradient(120% 80% at 50% 0%, var(--accent-a2) 0%, transparent 60%),
linear-gradient(180deg, var(--gray-2) 0%, var(--gray-3) 100%);
overflow: hidden;
}

.feature-bento-card__placeholder-grid {
position: absolute;
inset: 0;
background-image:
linear-gradient(to right, var(--gray-a3) 1px, transparent 1px),
linear-gradient(to bottom, var(--gray-a3) 1px, transparent 1px);
background-size: 16px 16px;
background-position: -1px -1px;
mask-image: radial-gradient(120% 80% at 50% 50%, black 30%, transparent 80%);
opacity: 0.5;
transition: opacity 0.1s ease;
}

.feature-bento-card__placeholder-glow {
position: absolute;
inset: -20%;
background: radial-gradient(closest-side, var(--accent-a3), transparent 70%);
opacity: 0;
transition: opacity 0.1s ease;
pointer-events: none;
}

.feature-bento-card:hover .feature-bento-card__placeholder-glow,
.feature-bento-card--active .feature-bento-card__placeholder-glow {
opacity: 1;
}

.feature-bento-card:hover .feature-bento-card__placeholder-grid,
.feature-bento-card--active .feature-bento-card__placeholder-grid {
opacity: 0.8;
}

.feature-bento-card__icon {
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
border-radius: var(--radius-3);
background: var(--color-panel-solid);
border: 1px solid var(--gray-a5);
color: var(--gray-12);
box-shadow: 0 1px 0 0 var(--gray-a3) inset;
transition:
transform 0.1s ease,
border-color 0.1s ease,
color 0.1s ease;
}

.feature-bento-card:hover .feature-bento-card__icon,
.feature-bento-card--active .feature-bento-card__icon {
transform: scale(1.05);
border-color: var(--accent-a7);
color: var(--accent-11);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Flex, Text } from "@radix-ui/themes";
import { motion } from "framer-motion";
import type { ReactNode } from "react";
import "./FeatureBentoCard.css";

interface FeatureBentoCardProps {
icon: ReactNode;
title: string;
description: string;
active?: boolean;
index?: number;
/** Tailwind classes controlling the cell's grid placement (e.g. "col-span-4 row-span-2"). */
className?: string;
onMouseEnter?: () => void;
onMouseLeave?: () => void;
}

export function FeatureBentoCard({
icon,
title,
description,
active = false,
index = 0,
className = "",
onMouseEnter,
onMouseLeave,
}: FeatureBentoCardProps) {
return (
<motion.div
initial={{ opacity: 0, y: 12 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3, delay: index * 0.08 }}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
className={`feature-bento-card ${active ? "feature-bento-card--active" : ""} ${className}`}
>
<div className="feature-bento-card__placeholder">
<div
className="feature-bento-card__placeholder-grid"
aria-hidden="true"
/>
<div
className="feature-bento-card__placeholder-glow"
aria-hidden="true"
/>
<Flex
align="center"
justify="center"
className="relative z-10 text-(--gray-9)"
>
<div className="feature-bento-card__icon">{icon}</div>
</Flex>
Comment thread
Twixes marked this conversation as resolved.
</div>
<Flex
direction="column"
gap="1"
className="feature-bento-card__content shrink-0 px-1 pt-3 pb-1"
>
<Text className="font-medium text-(--gray-12) text-sm leading-snug">
{title}
</Text>
<Text className="text-(--gray-11) text-[12px] leading-snug">
{description}
</Text>
</Flex>
</motion.div>
);
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,45 @@ import { Button, Flex, Text } from "@radix-ui/themes";
import explorerHog from "@renderer/assets/images/hedgehogs/explorer-hog.png";
import Logo from "@renderer/assets/logo";
import { useCallback, useEffect, useRef, useState } from "react";
import { FeatureListItem } from "./FeatureListItem";
import { FeatureBentoCard } from "./FeatureBentoCard";
import { OnboardingHogTip } from "./OnboardingHogTip";
import { StepActions } from "./StepActions";

const FEATURES = [
{
icon: <Tray size={24} />,
title: "Your signals inbox",
icon: <ChartLine size={28} />,
title: "Product data as context",
description:
"Automatically surfaces the highest-impact work from your product data so you always know what to do next.",
"Built-in context on analytics, session replays, experiments, feature flags, and more.",
className: "col-span-4",
},
{
icon: <ChartLine size={24} />,
title: "Product data as context",
icon: <Tray size={26} />,
title: "Your signals inbox",
description:
"Your agents have context from your analytics, session replays and feature flags built in.",
"Automatically surfaces the highest-impact work from your product data so you always know what to do next.",
className: "col-span-2",
},
{
icon: <Robot size={24} />,
title: "Any model, any harness",
icon: <Robot size={22} />,
title: "Your pick of Claude Code or Codex",
description:
"Bring your own agent framework or use our built-in harnesses. Swap models without changing your workflow.",
"PostHog is harness-agnostic – both Anthropic and OpenAI supported.",
className: "col-span-2",
},
{
icon: <Cloud size={24} />,
title: "Ship work, not messages",
icon: <Cloud size={22} />,
title: "Build non-stop",
description:
"Run tasks in parallel across local and cloud environments. Work gets done whether you're watching or not.",
"Run tasks in parallel across local and cloud environments - even while you're away.",
className: "col-span-2",
},
{
icon: <GitPullRequest size={24} />,
icon: <GitPullRequest size={22} />,
title: "Review and ship with confidence",
description:
"Inline diffs, AI-assisted code review and automated pull request creation in one flow.",
"Inline diffs, AI-assisted code review and PR creation in a single flow.",
className: "col-span-2",
},
];

Expand Down Expand Up @@ -96,57 +101,53 @@ export function WelcomeScreen({ onNext }: WelcomeScreenProps) {
<Flex
direction="column"
align="center"
className="min-h-0 w-full flex-1 overflow-y-auto"
className="min-h-0 w-full flex-1"
>
<Flex
direction="column"
align="start"
style={{
margin: "auto 0",
}}
className="w-full max-w-[560px] gap-[20px]"
className="mx-0 my-auto w-full max-w-[760px] gap-6 overflow-hidden"
>
<Flex direction="column" gap="1">
<Flex direction="row" align="center" gap="2">
<Text className="font-bold text-(--gray-12) text-2xl">
Welcome to
</Text>
<Logo />
</Flex>

<Text className="hidden text-(--gray-11) text-sm">
Your product workbench.
<Flex direction="row" align="center" gap="3">
<Text
/** Very specifically 25px text to be the same size as the Logo's font size */
className="font-bold text-(--gray-12) text-[25px] tracking-[-0.05em]"
>
Welcome to
</Text>
<Logo />
</Flex>

<Flex direction="column" className="w-full gap-[8px]">
<div className="grid w-full grid-cols-6 grid-rows-[18rem_14rem] gap-3 overflow-hidden rounded-lg">
{FEATURES.map((feature, index) => (
<FeatureListItem
<FeatureBentoCard
key={feature.title}
icon={feature.icon}
title={feature.title}
description={feature.description}
active={activeIndex === index}
index={index}
className={feature.className}
onMouseEnter={() => handleMouseEnter(index)}
onMouseLeave={handleMouseLeave}
/>
))}
</Flex>

<OnboardingHogTip
hogSrc={explorerHog}
message="Let's get you set up! It only takes a minute."
/>
</div>
</Flex>
</Flex>

<StepActions>
<Button size="3" onClick={onNext}>
Start shipping
<ArrowRight size={16} weight="bold" />
</Button>
</StepActions>
<Flex direction="column" align="center" className="shrink-0 pt-[16px]">
<OnboardingHogTip
hogSrc={explorerHog}
message="Let's get you set up! It only takes a minute."
/>
<StepActions delay={0.25}>
<Button size="3" onClick={onNext}>
Start shipping
<ArrowRight size={16} weight="bold" />
</Button>
</StepActions>
</Flex>
</Flex>
</Flex>
);
Expand Down
Loading