Skip to main content
This guide outlines the coding standards and conventions used in the Chitagá Tech project. Following these guidelines ensures consistency and maintainability across the codebase.

Technology Stack

Chitagá Tech is built with:
  • Astro (v5.17.1) - Static site framework
  • React (v19.2.4) - For interactive components
  • TypeScript - Using strict mode configuration
  • Tailwind CSS (v4.2.1) - For styling
  • Framer Motion (v12.34.4) - For animations

Project Structure

The project follows this directory structure:
/
├── public/          # Static assets (images, favicon)
├── src/
│   ├── components/  # Astro and React components
│   ├── layouts/     # Page layouts
│   ├── pages/       # Route pages
│   └── styles/      # Global styles
├── astro.config.mjs # Astro configuration
├── tsconfig.json    # TypeScript configuration
└── package.json     # Dependencies and scripts

File Naming Conventions

Components

  • Astro components: Use lowercase with hyphens or camelCase
    • hero.astro
    • about.astro
    • services.astro
  • React components: Use camelCase with .jsx extension
    • buttonToggle.jsx
    • toggleTheme.jsx
    • ScrollAnimation.jsx
  • Layouts: Use PascalCase
    • Layout.astro

Styles

  • Use lowercase with hyphens: global.css

TypeScript Configuration

The project uses Astro’s strict TypeScript configuration:
{
  "extends": "astro/tsconfigs/strict",
  "include": [".astro/types.d.ts", "**/*"],
  "exclude": ["dist"]
}
Always enable TypeScript strict mode features:
  • Type all props interfaces
  • Avoid using any
  • Enable strict null checks

Component Structure

Astro Components

Follow this structure for Astro components:
---
// 1. Imports first
import ScrollAnimation from './ScrollAnimation.jsx';

// 2. Type definitions
interface Props {
    title?: string;
    subtitle?: string;
    cta?: string;
    ctaHref?: string;
}

// 3. Props with defaults
const {
    title = "Default Title",
    subtitle = "Default subtitle",
    cta = "Click here",
    ctaHref = "#",
} = Astro.props;
---

<!-- 4. Component markup -->
<section id="section-id" class="section-class">
    <div class="inner-container">
        <ScrollAnimation className="content" delay={0.2} client:load as="div">
            <h2 class="title">{title}</h2>
            <p class="subtitle">{subtitle}</p>
        </ScrollAnimation>
    </div>
</section>

<!-- 5. Component-scoped styles -->
<style>
    .section-class {
        padding: 3rem 2rem;
        background: #ffffff;
    }

    :global(.dark) .section-class {
        background: #191919;
    }

    /* Mobile-first responsive design */
    @media (min-width: 768px) {
        .section-class {
            padding: 4rem 3rem;
        }
    }
</style>

React Components

Use functional components with hooks:
import { motion, useInView } from 'framer-motion';
import { useRef } from 'react';

const ScrollAnimation = ({
  children,
  variants = {},
  initial = "hidden",
  animate = "visible",
  transition = { duration: 0.6, ease: "easeOut" },
  className = "",
  delay = 0,
  as = "div",
  style = {}
}) => {
  const ref = useRef(null);
  const isInView = useInView(ref, { 
    once: true, 
    amount: 0.3,
    margin: "0px 0px -100px 0px"
  });

  const defaultVariants = {
    hidden: { opacity: 0, y: 50 },
    visible: { opacity: 1, y: 0 }
  };

  const animationVariants = { ...defaultVariants, ...variants };
  const MotionComponent = motion[as];

  return (
    <MotionComponent
      ref={ref}
      initial={initial}
      animate={isInView ? animate : initial}
      variants={animationVariants}
      transition={{ ...transition, delay }}
      className={className}
      style={style}
    >
      {children}
    </MotionComponent>
  );
};

export default ScrollAnimation;

Styling Guidelines

CSS Custom Properties

Use the defined CSS variables from global.css:
/* Colors */
--color-orange: #B93A05;
--color-white: #EAE8EB;
--color-skin: #E6B9A6;
--color-green-dark: #184014;
--color-green-light: #086842;

/* Fonts */
--font-pop: 'Poppins', sans-serif;
--font-sans: 'Source Sans 3', sans-serif;
--font-o-sans: 'Open Sans', sans-serif;
--font-montserrat: 'Montserrat', sans-serif;

Dark Mode

Always provide dark mode variants:
.hero-section {
    background: #ffffff;
}

:global(.dark) .hero-section {
    background: #191919;
}

Responsive Design

Use mobile-first approach with these breakpoints:
/* Mobile: default styles */
.element {
    padding: 2rem;
}

/* Tablet */
@media (min-width: 768px) {
    .element {
        padding: 3rem;
    }
}

/* Desktop */
@media (min-width: 1024px) {
    .element {
        padding: 4rem;
    }
}

/* Large desktop */
@media (min-width: 1280px) {
    .element {
        padding: 5rem;
    }
}

Tailwind CSS

Use Tailwind utilities with @apply or directly in markup:
.nav-desktop {
    @apply hidden md:flex;
}

.nav-desktop ul {
    @apply flex items-center gap-0.5;
}

Global Styles

For React-rendered elements that need Astro styles, use :global():
:global(.hero-content) {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

Props and Interfaces

Type All Props

Always define TypeScript interfaces for component props:
interface Props {
    title?: string;        // Optional with default
    subtitle?: string;     // Optional with default
    imgSrc?: string;       // Optional with default
    imgAlt?: string;       // Optional with default
}

Provide Defaults

Set sensible defaults for optional props:
const {
    title = "Tu futuro no debería depender de irte de Chitagá",
    subtitle = "Default subtitle",
    cta = "Quiero ser parte",
    ctaHref = "#contacto",
} = Astro.props;

Animation Guidelines

Use ScrollAnimation Component

For scroll-triggered animations, use the ScrollAnimation wrapper:
<ScrollAnimation 
  className="hero-content" 
  delay={0.2} 
  client:load 
  as="div"
>
  <h1 class="hero-title">{title}</h1>
  <p class="hero-subtitle">{subtitle}</p>
</ScrollAnimation>

Custom Variants

Define custom animation variants when needed:
<ScrollAnimation 
  delay={0.4} 
  variants={{
    hidden: { opacity: 0, scale: 0.9 },
    visible: { opacity: 1, scale: 1 }
  }} 
  client:load 
  as="div"
>
  <!-- Content -->
</ScrollAnimation>

Client Directives

Use appropriate Astro client directives:
  • client:load - For interactive components needed immediately
  • client:visible - For components that become interactive when visible
  • client:idle - For lower priority interactive components
<ButtonToggle client:load />
<ScrollAnimation client:load as="div">
  <!-- Content -->
</ScrollAnimation>

Accessibility

Semantic HTML

Use semantic HTML elements:
<header id="site-header">
  <nav class="nav-desktop">
    <ul>
      <li><a href="#inicio">Inicio</a></li>
    </ul>
  </nav>
</header>

ARIA Labels

Add ARIA labels for interactive elements:
<button id="menu-toggle" aria-label="Abrir menú" aria-expanded="false">
  <span></span>
</button>

Image Alt Text

Always provide descriptive alt text:
<img src="/parque.jpg" alt="Chitagá, Norte de Santander" loading="eager" />

Performance Best Practices

Image Loading

  • Use loading="eager" for above-the-fold images
  • Use loading="lazy" for below-the-fold images

CSS Optimization

  • Use CSS custom properties for repeated values
  • Minimize use of !important
  • Scope styles to components when possible

JavaScript

  • Keep client-side JavaScript minimal
  • Use Astro’s partial hydration
  • Defer non-critical scripts

Git Commit Messages

Follow this format:
Type: Brief description

Detailed explanation if needed
Types:
  • Add - New features or files
  • Update - Enhancements to existing features
  • Fix - Bug fixes
  • Refactor - Code restructuring
  • Docs - Documentation changes
  • Style - Formatting, styling changes
Examples:
Add: contact form validation
Fix: mobile menu not closing on link click
Update: hero section responsive layout
Refactor: extract ScrollAnimation to shared component

Code Review Checklist

Before submitting a PR, ensure:
  • Code follows TypeScript strict mode
  • Components have proper type definitions
  • Responsive design works on all breakpoints
  • Dark mode styles are included
  • Accessibility attributes are present
  • Code is properly formatted
  • No console errors in development
  • Build completes successfully (npm run build)
  • Commit messages follow conventions

Additional Resources

By following these guidelines, you help maintain a clean, consistent, and professional codebase for Chitagá Tech!

Build docs developers (and LLMs) love