@hanzo/gui went to ^8.1.0 while its siblings stayed pinned at 8.0.x. They are one release train published in lockstep, and @hanzogui/web holds the config and theme singletons createGui writes at import — so the split put two of those in the tree and broke it twice. At type level it wore four masks. defaultConfig's AnimationDriver came from the old copy, a different declaration than the new createGui expects, so createGui<Conf extends CreateGuiProps> fell back to its constraint and the degradation surfaced as an apparent library rewrite: AnimationsConfigObject demanding a `default` key, GuiConfig circularly referencing itself, Accordion "no longer accepting" width or children. None of it was real — gui's own apps/demos/src/AccordionDemo.tsx composes Accordion with exactly these props. faq.tsx and gui.config.ts are therefore unchanged; adapting them would have encoded a dependency defect as four permanent workarounds. At runtime the type gate could not see it at all: @hanzo/ui pulls its own @hanzogui/toast + telemetry island, whose exact pins held a second @hanzogui/web, and /leadership died prerendering on `Missing theme.` reading a singleton nobody set. pnpm.overrides states the invariant, because pnpm keeps a satisfied lockfile entry rather than re-resolving a caret that now admits 8.1.0. Build green on node 22.23.1: tsc clean, 773 pages exported, 21 withheld. Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Hanzo AI Website
The Hanzo AI marketing site — Next.js 15, React 19, TypeScript, and @hanzo/ui on the @hanzo/gui substrate with @hanzo/design tokens. Tailwind is still present but is being retired: the utility classNames are converted to gui style props file by file, and the build drops it once the last one is gone.
Project Structure
The project follows a component-based architecture with the following structure:
src/
├── components/ # React components
│ ├── ui/ # UI components (buttons, cards, etc.)
│ ├── platform/ # Platform-specific components
│ ├── cloud/ # Cloud-specific components
│ └── index3/ # Homepage components
├── constants/ # Constants and configuration
├── hooks/ # React hooks
├── lib/ # Utility functions
└── pages/ # Page components
Styling and Layout Guidelines
Typography
- We use a consistent typographic scale across all pages
- Main headings:
text-5xl md:text-6xl lg:text-7xlwithfont-bold tracking-tight - Secondary headings:
text-3xl md:text-5xlwithfont-bold - Body text:
text-lgfor normal text,text-xlfor emphasized text - Every page should have a pre-heading with the format:
<span className="inline-block px-4 py-1 rounded-full bg-purple-900/30 border border-purple-500/30 text-purple-300 text-sm font-medium"> AI Engineering Platform </span>
Layout and Spacing
- Every section should have consistent vertical padding:
py-32 - Use a max-width container for content:
max-w-7xl mx-auto - Maintain consistent horizontal padding with:
px-4 sm:px-6 lg:px-8 - Use the grid system with responsive breakpoints:
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> - Always include sufficient whitespace between sections (min 8rem)
Hero Sections
All hero sections should follow this structure:
- Include the "AI Engineering Platform" pre-heading with purple background
- Use ChromeText for the main heading
- Include a concise subheading that explains the value proposition
- Add call-to-action buttons with gradient backgrounds
- Consider adding subtle animations with Framer Motion
- Ensure proper spacing (py-32) and responsive behavior
Chrome Text Component
The ChromeText component is used for headings with a metallic gradient effect:
<ChromeText
as="h2"
className="text-3xl md:text-5xl font-bold mb-4"
preHeading="Optional Pre-Heading"
preHeadingClassName="optional-additional-classes"
style={{
backgroundPosition: `${mouseX}% ${mouseY}%`,
}}
>
Your Heading Text
</ChromeText>
Props:
as: HTML element to render (h1, h2, etc.)className: Additional classes for the headingpreHeading: Optional text to show above the headingpreHeadingClassName: Additional classes for the pre-headingstyle: Additional styles including backgroundPosition for the reflection effect
Mockup Components
When adding UI mockups:
- Create self-contained components for mockups
- Use responsive design patterns
- Add subtle animations to enhance visual appeal
- Include realistic-looking data and UI elements
For cloud console mockups, follow the style in AIPlatformSection.tsx.
For platform mockups, follow the style in DXPlatform.tsx.
Making Updates
When making updates to the website:
- Keep styling consistent across all pages
- Maintain proper spacing between elements
- Ensure all components are responsive
- Keep large components refactored into smaller, focused pieces
- Follow the established UI patterns and color schemes
- Use the Chrome Text component for main headings
- Add appropriate pre-headings to each major section
Adding New Pages
When adding new pages:
- Create a new page component in the
src/pagesdirectory - Include the proper pre-heading and ChromeText heading
- Add the page to the appropriate routes in
App.tsx - Follow the established layout patterns:
- Pre-heading (AI Engineering Platform)
- ChromeText main heading
- Concise description
- Clear call-to-action buttons
- Consistent spacing (py-32)
- Ensure the page is fully responsive
Animations
The website uses Framer Motion for animations. When adding new animations:
- Use consistent animation patterns:
<motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }} > - Stagger animations for related elements
- Use viewport animations for scrolling sections:
<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} >
Modifying Feature Sections
When adding or modifying feature sections:
- Use a consistent grid layout (1, 2, or 3 columns depending on content)
- Use icons from lucide-react library with matching colors
- Keep descriptions concise and focused on benefits
- Use ChromeText for section headings
- Add subtle hover effects to interactive elements
- Include proper spacing between items
Responsive Design
All components must be fully responsive:
- Use flexible layouts with grid and flex
- Use responsive text sizes (text-base md:text-lg lg:text-xl)
- Stack elements vertically on mobile, horizontally on desktop
- Ensure sufficient spacing on all device sizes
- Test all changes across multiple viewport sizes
- Use gui's media props consistently (
$gtSm,$gtMd,$gtLg) — the same breakpoints, expressed where the styling lives
UI Component Library
Components come from @hanzo/ui (8.x) on the @hanzo/gui substrate — the
same library every Hanzo surface renders. src/components/ui/ is NOT a local
component library to copy into; there is no shadcn here. When building UI:
- Look in
@hanzo/uifirst (the component surface), then@hanzo/ui/product(DataTable, PageHeader, StatusTag, SiteNav, MetricCard, …), then@hanzo/guifor the primitives (YStack/XStack/Text/View). - Style with gui props against the tokens, never with utility classes:
<YStack padding="$4" gap="$2" backgroundColor="$card">. The token names come from@hanzo/designand are bound ingui.config.ts. - Reach for
components/marketing/page-kit.tsxfor page shapes (hero, section, card grid, CTA, prose) rather than re-laying them out. render="h2"— NOTtag=— is how a gui component picks its host element;tagleaks through as a DOM attribute and you silently ship a page with no headings.- Maintain accessibility: 44px minimum touch targets, real heading levels.
Typography Scale
Follow this typography scale consistently:
- Headings:
- h1:
text-5xl md:text-6xl lg:text-7xl font-bold tracking-tight - h2:
text-3xl md:text-5xl font-bold - h3:
text-2xl font-bold - h4:
text-xl font-semibold
- h1:
- Body:
- Large:
text-xl text-neutral-300 - Default:
text-lg text-neutral-400 - Small:
text-base text-neutral-500 - Caption:
text-sm text-neutral-500
- Large:
Color System
Use these color classes consistently:
- Primary text:
text-[var(--white)](headings and important text) - Secondary text:
text-neutral-300(body text) - Muted text:
text-neutral-400ortext-neutral-500(less important text) - Primary accent:
text-purple-400or backgroundbg-purple-600 - Secondary accent:
text-blue-400or backgroundbg-blue-600 - Backgrounds:
bg-[var(--black)],bg-gray-900/50, orbg-gray-900/20 - Borders:
border-gray-800orborder-purple-500/30for accents