semillero-special-hotel/docs/STYLE_GUIDE.md

201 lines
6.9 KiB
Markdown

# 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.
```css
: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:
```css
.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
```tsx
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:
```css
.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`).
```css
.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.