Files
ar.badieiandCursor c2376b3b9e
Build & Push Docker Image / build (push) Has been cancelled
feat: redesign landing page with brand system and section blocks
Refresh the homepage around new hero/services/roadmap sections, shared design tokens, and updated brand assets.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 17:00:55 +03:30

3.7 KiB
Raw Permalink Blame History

Buttons

Every interactive CTA uses @/components/ui/button. Do not create parallel button styles, raw <button className="bg-…"> marketing CTAs, or one-off rounded pills.

Canonical implementation: components/ui/button.tsx + CSS tokens in app/globals.css.

Tokens

CSS variable Value Role
--btn-radius var(--radius) → 0.625rem Corner radius
--btn-height-sm 2rem (32px) Compact / cards
--btn-height-md 2.5rem (40px) Default
--btn-height-lg 3rem (48px) Hero / marketing
--btn-px-sm 0.75rem Horizontal padding sm
--btn-px-md 1.25rem Horizontal padding md
--btn-px-lg 1.5rem Horizontal padding lg
--btn-gap-sm/md/lg 0.375–0.5rem Icon ↔ label gap

Variants

Variant Prop Visual When to use
Primary default Solid primary, white label, soft shadow Main conversion CTA
Secondary secondary Transparent + border Supporting action
Outline outline Alias of secondary (Shadcn compat) Imported blocks
Ghost ghost No border, accent wash on hover Nav / tertiary
Destructive destructive Danger fill Delete / irreversible
Link link Text link, underline on hover Inline actions

Surfaces

Surface Prop Use
Default surface="default" Normal page canvas
Brand surface="brand" Teal / dark marketing panels (inverse contrast)

On brand surfaces:

  • Primary → white fill, dark text
  • Secondary/outline → white border, white text
  • Ghost → white text, white/10 hover

Sizes

Size Prop Height Text Icon size
Small sm 32px text-sm 0.875rem
Medium default 40px text-sm 1rem
Large lg 48px text-base 1.25rem
Icon sm icon-sm 32×32 — 0.875rem
Icon icon 40×40 — 1rem
Icon lg icon-lg 48×48 — 1.25rem

States

State Behavior
Hover Primary → primary-hover + shadow-glow-primary; secondary → border primary tint + accent fill + shadow-glow-sm
Active active:scale-[0.98] + darker fill
Focus focus-visible:ring-[3px] ring-ring/40 + border-ring
Disabled opacity-50, no pointer, no shadow
Invalid Destructive ring/border via aria-invalid

Motion

  • Transition: duration-200 ease-out
  • Properties: color, background, border, box-shadow, opacity, transform
  • Optional micro-lift on header CTA: hover:-translate-y-px (sparingly)

Usage

import { Button } from "@/components/ui/button";
import Link from "next/link";
import { ChevronLeft } from "lucide-react";

<Button size="lg">درخواست مشاوره</Button>

<Button variant="secondary" size="default">مشاهده نمونه کارها</Button>

<Button variant="ghost" size="icon" aria-label="باز کردن منو">
  <Menu className="size-5" />
</Button>

<Button asChild size="lg">
  <Link href="/contact-us">
    ادامه
    <ChevronLeft className="size-4" />
  </Link>
</Button>

{/* On dark teal CTA band */}
<Button surface="brand" size="lg">شروع کنید</Button>

Hierarchy in a section

  1. At most one primary button per viewport section.
  2. Secondary/outline for the alternate path.
  3. Ghost for low-emphasis actions.
  4. Do not place two equal primary buttons side by side.

Forbidden

  • Custom rounded-full CTA capsules that ignore --btn-radius.
  • Hardcoded bg-[#29a19c] buttons.
  • Re-implementing button styles in WordPress/HTML blocks without mapping to tokens (WP buttons are themed in globals.css to approximate primary).