Skip to main content

Visita Design System

We have established a strict UI engineering standard utilizing Framer Motion for interactions and Lenis for scroll smoothing. This document outlines the required stack and enforcement rules for all frontend development.

Technology Stack

The Visita frontend is built on a specific set of technologies chosen for performance and aesthetic quality.
TechnologyRoleRequirement
Framer MotionAnimation EngineRequired for all interactive elements and page transitions.
LenisScroll SmoothingGlobal smooth scroll is active. Do not interfere with scroll behavior.
Tailwind CSSStylingUtility-first styling with our custom tailwind.config.ts.
shadcn/uiComponent LibraryBase accessible components, styled with Tailwind.

Motion Primitives

We have abstracted common animations into reusable components found in components/motion/. Use these instead of writing raw motion.div code where possible.

<FadeIn>

Use for general content entering the viewport. It provides a subtle rise and fade-in effect.
import { FadeIn } from "@/components/motion";

<FadeIn delay={0.2}>
  <h1>Welcome to Visita</h1>
</FadeIn>

<StaggerList>

Use for lists, feeds, or grids of items (e.g., voting stations, ward feeds). It orchestrates child animations.
import { StaggerList, StaggerItem } from "@/components/motion";

<StaggerList>
  {items.map((item) => (
    <StaggerItem key={item.id}>
      <Card item={item} />
    </StaggerItem>
  ))}
</StaggerList>

<ScaleButton>

Use for all primary actions and clickable cards. It adds a tactile scale effect on hover and tap.
import { ScaleButton } from "@/components/motion";

<ScaleButton>
  <Button>Click Me</Button>
</ScaleButton>

<ParallaxHero>

Use for top-level page headers (e.g., Ward Landing, Profile). It handles scroll-linked parallax effects for background images.
import { ParallaxHero } from "@/components/motion";

<ParallaxHero 
  imageUrl="/images/ward-bg.jpg" 
  title="Ward 115" 
  subtitle="City of Cape Town" 
/>

Best Practices & Enforcement

Adhere to these rules to maintain the “premium” feel of the platform.

Animation & Transitions

  • Always wrap page transitions. Use the PageTransition component or template.tsx to ensure smooth navigation between routes.
  • Do not use native CSS scroll-behavior: smooth. This conflicts with Lenis. Let Lenis handle all scrolling.

Typography

  • Tight Headings: Use tracking-tight on all H1 and H2 headers to create a modern, dense typographic feel.
  • Inter Font Features: Ensure the Inter font is loaded with cv05 (loops on ‘l’) and cv11 (flat top ‘3’) where appropriate for legibility.

Component Usage

  • Prefer shadcn/ui components for form elements and overlays.
  • Use components/motion primitives before writing custom animation logic.