mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
121 lines
4.5 KiB
TypeScript
121 lines
4.5 KiB
TypeScript
'use client'
|
|
|
|
/**
|
|
* How it works, as eight cards.
|
|
*
|
|
* NO TAILWIND. The section frame and its centred head are
|
|
* `components/marketing/band`'s `Band` and `Head`; the card and its disc are
|
|
* gui props over @hanzo/design's tokens.
|
|
*
|
|
* The deck is `Grid`'s `{ min, max }` — the same four-up value
|
|
* `components/realtime/Features` uses — so it wraps by width rather than at
|
|
* named breakpoints.
|
|
*/
|
|
|
|
import { motion } from "@/components/motion";
|
|
import { Sparkles, Zap, Lock, Globe, Lightbulb, Share2, FileText, Command } from "lucide-react";
|
|
import { View, XStack } from '@hanzo/ui'
|
|
import { Grid } from '@hanzo/ui/grid'
|
|
import { Band, Head, Words } from '@/components/marketing/band'
|
|
|
|
/** How narrow a column may get before the grid drops one. */
|
|
const DECK = { min: 260, max: 4 } as const
|
|
|
|
|
|
const FeatureCard = ({ icon: Icon, title, description }) => {
|
|
return (
|
|
<View
|
|
render={<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} />}
|
|
display="block"
|
|
height="100%"
|
|
p={24}
|
|
rounded="var(--radius-xl)"
|
|
borderWidth={1}
|
|
borderColor="var(--neutral-800)"
|
|
background="color-mix(in oklab, var(--neutral-900) 30%, transparent)"
|
|
>
|
|
<XStack
|
|
width={48}
|
|
height={48}
|
|
items="center"
|
|
justify="center"
|
|
mb={16}
|
|
rounded="var(--radius-lg)"
|
|
bg="$raised"
|
|
>
|
|
<Icon width={24} height={24} color="var(--foreground)" />
|
|
</XStack>
|
|
<Words render="h3" mb={8} fontSize="$6" lineHeight="1.4" weight="700" color="var(--foreground)">{title}</Words>
|
|
<Words render="p" color="color-mix(in oklab, var(--foreground) 80%, transparent)">{description}</Words>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const HanzoExtensionFeatures = () => {
|
|
const features = [
|
|
{
|
|
icon: Sparkles,
|
|
title: "It uses your session",
|
|
description: "The agent drives the browser you are already signed into, so a page behind a login is a page it can read. Nothing has to be scraped from the outside."
|
|
},
|
|
{
|
|
icon: Zap,
|
|
title: "No port to open",
|
|
description: "The extension talks to the local Hanzo daemon through a native messaging host over a Unix socket. There is no WebSocket, no localhost port, and nothing else on the machine can dial in."
|
|
},
|
|
{
|
|
icon: Lock,
|
|
title: "Connected means registered",
|
|
description: "It only reports itself connected once the daemon lists it as a provider. An open pipe to a wedged process is the failure this replaced, and it is checked on every tick."
|
|
},
|
|
{
|
|
icon: Globe,
|
|
title: "Three browsers, one behaviour",
|
|
description: "Chrome, Firefox and Safari builds come out of the same source. The evaluate rule is shared, so the same snippet from a caller behaves identically in all three."
|
|
},
|
|
{
|
|
icon: Lightbulb,
|
|
title: "Tabs are addressable",
|
|
description: "Each browser registers separately, so listing tabs asks the browser that is active — and naming a tab id from another browser's list is how you reach the other one."
|
|
},
|
|
{
|
|
icon: Share2,
|
|
title: "The rest of your tools, too",
|
|
description: "The same repo carries connectors for the software your work already lives in — documents, tickets, design files, mail, calendars — so an agent reaches them the same way it reaches a tab."
|
|
},
|
|
{
|
|
icon: FileText,
|
|
title: "Read a page as text",
|
|
description: "It hands back page content, console messages and network requests, which is what makes it useful for checking your own site rather than just browsing someone else's."
|
|
},
|
|
{
|
|
icon: Command,
|
|
title: "Installs from a file",
|
|
description: "Load it unpacked in Chrome or as a temporary add-on in Firefox while you are working on it. The build produces all three targets in one command."
|
|
}
|
|
];
|
|
|
|
return (
|
|
<Band rule={false} pad="$11" ground="color-mix(in oklab, var(--black) 50%, transparent)">
|
|
<Head
|
|
title="How it works"
|
|
lede="The extension registers as a provider on the local fabric. Whatever can reach the fabric can then reach a tab."
|
|
measure={768}
|
|
/>
|
|
|
|
<Grid columns={DECK} gap={24}>
|
|
{features.map((feature, index) => (
|
|
<FeatureCard
|
|
key={index}
|
|
icon={feature.icon}
|
|
title={feature.title}
|
|
description={feature.description}
|
|
/>
|
|
))}
|
|
</Grid>
|
|
</Band>
|
|
);
|
|
};
|
|
|
|
export default HanzoExtensionFeatures;
|