Customization Guide

Complete guide for customizing your Modello template - from colors and fonts to components and pages.

Customization Overview

Modello templates are built with customization in mind. Using modern technologies like Next.js, Tailwind CSS, and TypeScript, you can easily modify every aspect of your template to match your brand and requirements.

Design System Approach

All templates follow a consistent design system with reusable components, making customization predictable and maintainable.

Project Structure

Understanding the project structure helps you navigate and customize your template effectively:

your-template/
├── app/                    # Next.js App Router pages
│   ├── globals.css        # Global styles
│   ├── layout.tsx         # Root layout
│   ├── page.tsx          # Homepage
│   └── [other-pages]/    # Additional pages
├── components/            # Reusable components
│   ├── ui/               # Base UI components
│   └── [feature-components]/ # Feature-specific components
├── lib/                  # Utility functions
│   ├── utils.ts          # General utilities
│   └── [other-utils]/    # Specific utilities
├── public/               # Static assets
│   ├── images/           # Images and graphics
│   └── icons/            # Icons and favicons
├── styles/               # Additional stylesheets (if any)
├── tailwind.config.ts    # Tailwind configuration
├── next.config.mjs       # Next.js configuration
└── package.json          # Dependencies and scripts

Tailwind CSS Customization

Tailwind CSS powers the styling system in all Modello templates. Customize the design system by modifying the tailwind.config.ts file.

Colors & Typography

Customize your brand colors and typography in the Tailwind config:

// tailwind.config.ts
import type { Config } from "tailwindcss"

const config: Config = {
  // ... other config
  theme: {
    extend: {
      colors: {
        // Custom brand colors
        primary: {
          50: '#eff6ff',
          100: '#dbeafe',
          500: '#3b82f6',  // Main brand color
          600: '#2563eb',
          900: '#1e3a8a',
        },
        // Custom accent colors
        accent: {
          500: '#10b981',
          600: '#059669',
        },
        // Override default colors
        background: 'hsl(var(--background))',
        foreground: 'hsl(var(--foreground))',
      },
      fontFamily: {
        // Custom fonts
        sans: ['Inter', 'system-ui', 'sans-serif'],
        heading: ['Poppins', 'system-ui', 'sans-serif'],
        mono: ['JetBrains Mono', 'monospace'],
      },
      fontSize: {
        // Custom font sizes
        'xs': '0.75rem',
        'sm': '0.875rem',
        'base': '1rem',
        'lg': '1.125rem',
        'xl': '1.25rem',
        '2xl': '1.5rem',
        '3xl': '1.875rem',
        '4xl': '2.25rem',
        '5xl': '3rem',
      }
    },
  },
}

Update your global CSS variables in app/globals.css:

/* app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  :root {
    /* Light mode colors */
    --background: 0 0% 100%;
    --foreground: 222.2 84% 4.9%;
    --primary: 221.2 83.2% 53.3%;
    --primary-foreground: 210 40% 98%;
    
    /* Add your custom CSS variables */
    --brand-primary: 221.2 83.2% 53.3%;
    --brand-secondary: 210 40% 98%;
  }

  .dark {
    /* Dark mode colors */
    --background: 222.2 84% 4.9%;
    --foreground: 210 40% 98%;
    --primary: 217.2 91.2% 59.8%;
    --primary-foreground: 222.2 84% 4.9%;
  }
}

Spacing & Sizing

Customize spacing, sizing, and layout utilities:

// tailwind.config.ts - extend spacing
theme: {
  extend: {
    spacing: {
      '18': '4.5rem',
      '88': '22rem',
      '128': '32rem',
    },
    maxWidth: {
      '8xl': '88rem',
      '9xl': '96rem',
    },
    borderRadius: {
      'xl': '1rem',
      '2xl': '1.5rem',
      '3xl': '2rem',
    },
    boxShadow: {
      'soft': '0 2px 15px -3px rgba(0, 0, 0, 0.07), 0 10px 20px -2px rgba(0, 0, 0, 0.04)',
      'strong': '0 10px 25px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
    }
  }
}

Custom Utilities

Add custom utility classes for common patterns:

/* app/globals.css */
@layer utilities {
  /* Custom gradient backgrounds */
  .bg-gradient-brand {
    background: linear-gradient(135deg, theme('colors.primary.500'), theme('colors.primary.600'));
  }
  
  /* Custom text gradients */
  .text-gradient {
    background: linear-gradient(135deg, theme('colors.primary.500'), theme('colors.accent.500'));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
  }
  
  /* Custom animations */
  .animate-fade-in {
    animation: fadeIn 0.5s ease-in-out;
  }
  
  @keyframes fadeIn {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
  }
}

Component Customization

Modello templates use a component-based architecture that makes customization straightforward and maintainable.

Modifying Existing Components

Most components are located in the components/ directory. Here's how to customize them:

// components/ui/button.tsx - Example button customization
import { cn } from "@/lib/utils"
import { ButtonHTMLAttributes, forwardRef } from "react"

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'default' | 'primary' | 'secondary' | 'outline' | 'ghost'
  size?: 'sm' | 'md' | 'lg'
}

const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant = 'default', size = 'md', ...props }, ref) => {
    return (
      <button
        className={cn(
          // Base styles
          "inline-flex items-center justify-center rounded-md font-medium transition-colors",
          "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
          "disabled:pointer-events-none disabled:opacity-50",
          
          // Variant styles
          {
            'bg-primary text-primary-foreground hover:bg-primary/90': variant === 'primary',
            'bg-secondary text-secondary-foreground hover:bg-secondary/80': variant === 'secondary',
            'border border-input hover:bg-accent hover:text-accent-foreground': variant === 'outline',
            'hover:bg-accent hover:text-accent-foreground': variant === 'ghost',
          },
          
          // Size styles
          {
            'h-8 px-3 text-sm': size === 'sm',
            'h-10 px-4': size === 'md',
            'h-12 px-6 text-lg': size === 'lg',
          },
          
          className
        )}
        ref={ref}
        {...props}
      />
    )
  }
)

export { Button }

Creating New Components

Follow these patterns when creating new components:

// components/custom/feature-card.tsx - Example new component
import { cn } from "@/lib/utils"
import { ReactNode } from "react"

interface FeatureCardProps {
  title: string
  description: string
  icon?: ReactNode
  className?: string
  variant?: 'default' | 'highlighted'
}

export function FeatureCard({ 
  title, 
  description, 
  icon, 
  className,
  variant = 'default' 
}: FeatureCardProps) {
  return (
    <div
      className={cn(
        "rounded-lg border p-6 transition-all hover:shadow-md",
        {
          'bg-card text-card-foreground': variant === 'default',
          'bg-primary text-primary-foreground': variant === 'highlighted',
        },
        className
      )}
    >
      {icon && (
        <div className="mb-4 flex h-12 w-12 items-center justify-center rounded-lg bg-primary/10">
          {icon}
        </div>
      )}
      <h3 className="mb-2 text-lg font-semibold">{title}</h3>
      <p className="text-sm text-muted-foreground">{description}</p>
    </div>
  )
}

Component Patterns

Follow these patterns for consistent, maintainable components:

1. Use TypeScript interfaces for props

Define clear interfaces for component props to ensure type safety and better developer experience.

2. Implement variant patterns

Use variant props to create different visual styles while maintaining a single component.

3. Use the cn() utility for className merging

Always use the cn() utility from lib/utils.ts to properly merge Tailwind classes.

4. Forward refs when necessary

Use forwardRef for components that need to expose DOM element references.

Page Customization

Modello templates use Next.js App Router for page management. Here's how to customize, add, and remove pages.

Editing Existing Pages

Pages are located in the app/ directory. Each folder represents a route:

// app/about/page.tsx - Example page customization
import type { Metadata } from "next"

export const metadata: Metadata = {
  title: "About Us | Your Company",
  description: "Learn more about our company and mission",
}

export default function AboutPage() {
  return (
    <div className="container mx-auto px-4 py-16">
      <div className="max-w-4xl mx-auto">
        <h1 className="text-4xl font-bold mb-8">About Our Company</h1>
        
        <div className="prose prose-lg max-w-none">
          <p>
            Your company story and mission statement goes here. 
            Customize this content to reflect your brand and values.
          </p>
          
          <h2>Our Mission</h2>
          <p>
            Describe your company's mission and what drives you to do what you do.
          </p>
          
          <h2>Our Team</h2>
          <p>
            Introduce your team members and their roles.
          </p>
        </div>
      </div>
    </div>
  )
}

Adding New Pages

Create new pages by adding folders and page.tsx files:

# Create a new page structure
mkdir app/services
touch app/services/page.tsx

# For nested routes
mkdir -p app/services/web-development
touch app/services/web-development/page.tsx

# This creates routes:
# /services
# /services/web-development
// app/services/page.tsx - New services page
import type { Metadata } from "next"
import { FeatureCard } from "@/components/custom/feature-card"

export const metadata: Metadata = {
  title: "Our Services | Your Company",
  description: "Explore our comprehensive range of services",
}

const services = [
  {
    title: "Web Development",
    description: "Custom web applications built with modern technologies",
    icon: "🌐"
  },
  {
    title: "Mobile Apps",
    description: "Native and cross-platform mobile applications",
    icon: "📱"
  },
  // Add more services...
]

export default function ServicesPage() {
  return (
    <div className="container mx-auto px-4 py-16">
      <div className="text-center mb-12">
        <h1 className="text-4xl font-bold mb-4">Our Services</h1>
        <p className="text-lg text-muted-foreground max-w-2xl mx-auto">
          We offer a comprehensive range of services to help your business succeed
        </p>
      </div>
      
      <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
        {services.map((service, index) => (
          <FeatureCard
            key={index}
            title={service.title}
            description={service.description}
            icon={<span className="text-2xl">{service.icon}</span>}
          />
        ))}
      </div>
    </div>
  )
}

Removing Pages

Remove pages by deleting their directories and updating navigation:

# Remove a page directory
rm -rf app/unwanted-page

# Update navigation components to remove links
# Edit components/header.tsx or similar navigation components

Update Navigation

Remember to update your navigation components and any internal links when removing pages to avoid broken links.

Layout Customization

Customize the overall layout structure by modifying layout files:

// app/layout.tsx - Root layout customization
import type { Metadata } from "next"
import { Inter } from 'next/font/google'
import { Header } from "@/components/header"
import { Footer } from "@/components/footer"
import "./globals.css"

const inter = Inter({ subsets: ["latin"] })

export const metadata: Metadata = {
  title: {
    default: "Your Company Name",
    template: "%s | Your Company Name"
  },
  description: "Your company description",
  keywords: ["keyword1", "keyword2", "keyword3"],
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body className={inter.className}>
        <div className="min-h-screen flex flex-col">
          <Header />
          <main className="flex-1">
            {children}
          </main>
          <Footer />
        </div>
      </body>
    </html>
  )
}

Assets & Media

Manage images, icons, and other static assets:

Images

  • Place images in public/images/
  • Use Next.js Image component for optimization
  • Provide alt text for accessibility
  • Use appropriate formats (WebP, AVIF for modern browsers)

Icons

  • Templates use Lucide React icons by default
  • Replace favicon.ico in the public directory
  • Update app/icon.tsx for dynamic icons
  • Consider using SVG icons for scalability
// Example of using images in components
import Image from "next/image"

export function HeroSection() {
  return (
    <section className="relative">
      <Image
        src="/images/hero-background.jpg"
        alt="Hero background"
        width={1920}
        height={1080}
        className="object-cover"
        priority // Load immediately for above-the-fold content
      />
      <div className="absolute inset-0 bg-black/50">
        <div className="container mx-auto px-4 py-16">
          <h1 className="text-4xl font-bold text-white">
            Your Hero Title
          </h1>
        </div>
      </div>
    </section>
  )
}

Best Practices

Follow these best practices to maintain a high-quality, maintainable codebase:

Code Organization

  • Keep components small and focused
  • Use consistent naming conventions
  • Group related components in folders
  • Extract reusable logic into custom hooks

Performance

  • Use Next.js Image component for images
  • Implement lazy loading for heavy components
  • Minimize bundle size with tree shaking
  • Use dynamic imports for code splitting

Accessibility

  • Use semantic HTML elements
  • Provide alt text for images
  • Ensure proper color contrast
  • Test with keyboard navigation

SEO

  • Use proper meta tags and titles
  • Implement structured data
  • Optimize page loading speeds
  • Create XML sitemaps

Ready to Customize

With these customization techniques, you can transform your Modello template into a unique, branded experience that perfectly fits your needs.