semillero-special-hotel/docs/STYLE_GUIDE.md

6.9 KiB

Vanilla CSS & CSS Modules Style Guide

Variable Remuneration, Compensation, and Commissions System - Hoteles Estelar


This document outlines the strict guidelines for styling the application using Vanilla CSS and CSS Modules. By sticking to these guidelines, we ensure absolute isolation of component styles, prevent class name collisions, maintain a centralized token system, and support robust theme modifications (light/dark mode).


1. Centralized Design Tokens (globals.css)

All colors, spacing, typography, transitions, and layout presets must be defined as CSS custom properties (variables) inside src/app/globals.css. Global variables are declared in HSL (Hue, Saturation, Lightness) format to allow dynamic opacity control using alpha-value mixing.

:root {
  /* Color Palette - HSL values for premium dark/light mode */
  --primary-h: 220;
  --primary-s: 85%;
  --primary-l: 57%;
  --primary: hsl(var(--primary-h), var(--primary-s), var(--primary-l));
  
  --secondary-h: 260;
  --secondary-s: 70%;
  --secondary-l: 50%;
  --secondary: hsl(var(--secondary-h), var(--secondary-s), var(--secondary-l));

  --background-h: 0;
  --background-s: 0%;
  --background-l: 100%;
  --background: hsl(var(--background-h), var(--background-s), var(--background-l));

  --foreground-h: 220;
  --foreground-s: 40%;
  --foreground-l: 10%;
  --foreground: hsl(var(--foreground-h), var(--foreground-s), var(--foreground-l));

  --card: hsl(0, 0%, 97%);
  --border: hsl(220, 20%, 90%);

  /* Spacing Grid (8pt Grid System) */
  --space-1: 0.25rem; /* 4px */
  --space-2: 0.5rem;  /* 8px */
  --space-3: 0.75rem; /* 12px */
  --space-4: 1rem;    /* 16px */
  --space-6: 1.5rem;  /* 24px */
  --space-8: 2rem;    /* 32px */
  --space-12: 3rem;   /* 48px */

  /* Typography Scale */
  --font-sans: 'Inter', system-ui, -apple-system, sans-serif;
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
  --text-3xl: 1.875rem;
  --text-4xl: 2.25rem;

  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  /* Border Radius & Shadow Tokens */
  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;
  --radius-full: 9999px;

  --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
  --shadow-glow: 0 0 15px 2px hsla(var(--primary-h), var(--primary-s), var(--primary-l), 0.15);

  /* Transitions */
  --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-normal: 250ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-slow: 350ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Dark mode overrides (Activated via html[data-theme='dark'] or media queries) */
[data-theme='dark'] {
  --background-h: 220;
  --background-s: 40%;
  --background-l: 6%;
  --background: hsl(var(--background-h), var(--background-s), var(--background-l));

  --foreground-h: 220;
  --foreground-s: 15%;
  --foreground-l: 90%;
  --foreground: hsl(var(--foreground-h), var(--foreground-s), var(--foreground-l));

  --card: hsl(220, 30%, 11%);
  --border: hsl(220, 20%, 18%);
}

2. Theme Consistency & Background Rules

To prevent background mismatching or flashing layout inconsistencies when moving between pages:

  1. Container Backgrounds: Pages must use the radial gradient background that transitions smoothly across theme states:
    .container {
      background: radial-gradient(circle at top right, hsla(var(--primary-h), var(--primary-s), var(--primary-l), 0.08), transparent 45%),
                  var(--background);
      color: var(--foreground);
      font-family: var(--font-sans);
      transition: background var(--transition-slow);
      padding-bottom: var(--space-12);
    }
    
  2. Context-Backed Authentication & Theme: Fetching user profiles or auth tokens on page mount is handled by the central UserProvider context to avoid page rendering flashes.
  3. Typography: System default fonts are forbidden. Font tokens (var(--font-sans)) must be used on the body and all wrapper components.

3. Component Scoping with CSS Modules

All component-specific styles must live inside a .module.css file adjacent to the React component (e.g. Button.tsx pairs with Button.module.css).

3.1. Naming Conventions (Flat Local Names)

Since CSS Modules automatically generate unique identifiers at compile time (e.g., .container becomes .Button_container__u1a2x), complex BEM class names are not required. Use clear, semantic local names:

  • Good: .container, .card, .button, .badge
  • Avoid: .button-container-outer, .btn-v2

3.2. Scoped Styling in React

import styles from './Button.module.css';

interface ButtonProps {
  variant?: 'primary' | 'secondary';
  isActive?: boolean;
}

export function Button({ variant = 'primary', isActive, children }: ButtonProps) {
  return (
    <button 
      className={`
        ${styles.button} 
        ${styles[variant]} 
        ${isActive ? styles.isActive : ''}
      `}
    >
      {children}
    </button>
  );
}

4. Styling & Layout Guidelines

  • Layout Structure: Use CSS Grid for page structures and multi-column layouts. Use Flexbox for alignment inside rows, headers, and buttons. Never use tables or absolute positioning for structural layouts.
  • Sizing & Spacing: Use rem for typography, margin, padding, widths, and heights to ensure relative scaling. Always use variables from the spacing grid (var(--space-4)).
  • Responsive Design: Follow a mobile-first media query approach. Breakpoints are coded as:
    .container {
      display: grid;
      grid-template-columns: 1fr;
      gap: var(--space-4);
    }
    
    @media (min-width: 768px) {
      .container {
        grid-template-columns: repeat(2, 1fr);
      }
    }
    
    @media (min-width: 1024px) {
      .container {
        grid-template-columns: repeat(4, 1fr);
      }
    }
    

5. UI Polish & Animations

To deliver a premium visual experience:

  • Micro-interactions: Every interactive element (buttons, cards, inputs) must have a subtle hover effect using hardware-accelerated properties (transform, opacity, background-color).
    .card {
      background-color: var(--card);
      border: 1px solid var(--border);
      transition: transform var(--transition-normal), box-shadow var(--transition-normal);
    }
    
    .card:hover {
      transform: translateY(-2px);
      box-shadow: var(--shadow-lg), var(--shadow-glow);
    }
    
  • No Inline Styles: Inline styles (style={{ ... }}) are forbidden unless evaluating dynamically updated values that cannot be declared beforehand (e.g., progress bar percentage --progress: 73%).
  • Internationalization Integration: Never hardcode text strings inside CSS files or class names. Labels must be fetched from the client translation dictionary (t('key')) to support bilingual layout rendering seamlessly.