Files
aperonight/docs/theme-rules.md
2025-08-28 15:11:42 +02:00

6.1 KiB
Executable File

Theme Rules for Aperonight

Core Design System

Color Palette

/* Primary - Purple gradient system */
--color-primary-50: #faf5ff;
--color-primary-100: #f3e8ff;
--color-primary-200: #e9d5ff;
--color-primary-300: #d8b4fe;
--color-primary-400: #c084fc;
--color-primary-500: #a855f7;
--color-primary-600: #9333ea;
--color-primary-700: #7e22ce;
--color-primary-800: #6b21a8;
--color-primary-900: #581c87;

/* Accent - Pink gradient */
--color-accent-400: #f472b6;
--color-accent-500: #ec4899;
--color-accent-600: #db2777;

/* Neutral - Slate system */
--color-neutral-50: #f8fafc;
--color-neutral-100: #f1f5f9;
--color-neutral-200: #e2e8f0;
--color-neutral-300: #cbd5e1;
--color-neutral-400: #94a3b8;
--color-neutral-500: #64748b;
--color-neutral-600: #475569;
--color-neutral-700: #334155;
--color-neutral-800: #1e293b;
--color-neutral-900: #0f172a;

Typography

/* Font families */
--font-sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;

/* Font sizes */
--text-xs: 0.75rem;      /* 12px */
--text-sm: 0.875rem;     /* 14px */
--text-base: 1rem;       /* 16px */
--text-lg: 1.125rem;     /* 18px */
--text-xl: 1.25rem;      /* 20px */
--text-2xl: 1.5rem;      /* 24px */
--text-3xl: 1.875rem;    /* 30px */

Spacing

--space-1: 0.25rem;      /* 4px */
--space-2: 0.5rem;       /* 8px */
--space-3: 0.75rem;      /* 12px */
--space-4: 1rem;         /* 16px */
--space-5: 1.25rem;      /* 20px */
--space-6: 1.5rem;        /* 24px */
--space-8: 2rem;         /* 32px */
--space-10: 2.5rem;      /* 40px */
--space-12: 3rem;        /* 48px */

Component Rules

Buttons

/* Primary button */
.btn-primary {
  @apply bg-gradient-to-r from-purple-600 to-pink-600 text-white font-medium py-2 px-4 rounded-lg shadow-sm hover:shadow-md transition-all duration-200;
}

/* Secondary button */
.btn-secondary {
  @apply bg-white text-purple-600 border border-purple-200 font-medium py-2 px-4 rounded-lg hover:bg-purple-50 transition-colors duration-200;
}

/* Destructive button */
.btn-destructive {
  @apply bg-red-600 text-white font-medium py-2 px-4 rounded-lg shadow-sm hover:bg-red-700 transition-colors duration-200;
}

Cards

.card {
  @apply bg-white rounded-lg shadow-sm border border-slate-200 p-6 hover:shadow-md transition-shadow duration-200;
}

.card-header {
  @apply pb-4 border-b border-slate-200 mb-4;
}

.card-body {
  @apply space-y-4;
}

Forms

.form-input {
  @apply block w-full rounded-md border-slate-300 shadow-sm focus:border-purple-500 focus:ring-purple-500 sm:text-sm;
}

.form-label {
  @apply block text-sm font-medium text-slate-700 mb-1;
}

.form-error {
  @apply text-sm text-red-600 mt-1;
}

Navigation

.nav-link {
  @apply text-slate-600 hover:text-purple-600 px-3 py-2 rounded-md text-sm font-medium transition-colors duration-200;
}

.nav-link-active {
  @apply text-purple-600 bg-purple-50;
}

Layout Rules

Grid System

.container {
  @apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8;
}

.grid-responsive {
  @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6;
}

.grid-cards {
  @apply grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6;
}

Responsive Breakpoints

/* Mobile-first approach */
@media (min-width: 640px) { /* sm */ }
@media (min-width: 768px) { /* md */ }
@media (min-width: 1024px) { /* lg */ }
@media (min-width: 1280px) { /* xl */ }

Component States

Hover States

.hover-lift {
  @apply transition-transform duration-200 hover:-translate-y-1;
}

.hover-glow {
  @apply transition-all duration-200 hover:shadow-lg hover:shadow-purple-500/25;
}

Focus States

.focus-ring {
  @apply focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2;
}

Disabled States

.disabled {
  @apply opacity-50 cursor-not-allowed;
}

Animation Rules

Transitions

.transition-fast {
  @apply transition-all duration-150 ease-in-out;
}

.transition-normal {
  @apply transition-all duration-200 ease-in-out;
}

.transition-slow {
  @apply transition-all duration-300 ease-in-out;
}

Micro-animations

/* Subtle pulse for notifications */
.animate-pulse-subtle {
  @apply animate-pulse;
  animation-duration: 3s;
}

/* Gentle fade in */
.fade-in {
  @apply animate-in fade-in-0 duration-500;
}

Dark Mode Rules

Dark mode color tokens

@media (prefers-color-scheme: dark) {
  :root {
    --color-background: #0f172a;
    --color-surface: #1e293b;
    --color-border: #334155;
    --color-text-primary: #f1f5f9;
    --color-text-secondary: #cbd5e1;
    --color-text-muted: #64748b;
  }
}

Dark mode components

.dark .card {
  @apply bg-slate-800 border-slate-700;
}

.dark .form-input {
  @apply bg-slate-700 border-slate-600 text-white placeholder-slate-400;
}

Accessibility Rules

Focus Indicators

.focus-visible {
  @apply focus:outline-none focus-visible:ring-2 focus-visible:ring-purple-500 focus-visible:ring-offset-2;
}

Color Contrast

/* Ensure WCAG 2.1 AA compliance */
.text-primary {
  @apply text-slate-900 dark:text-slate-100;
}

.text-secondary {
  @apply text-slate-600 dark:text-slate-400;
}

Naming Conventions

CSS Classes

  • Use kebab-case: btn-primary, form-input
  • Prefix utilities with u-: u-flex, u-text-sm
  • State modifiers: is-active, has-error

JavaScript/React

  • Components: PascalCase (UserProfile.jsx)
  • Utilities: camelCase (formatDate.js)
  • Constants: UPPER_SNAKE_CASE (API_ENDPOINTS)

File Structure

app/javascript/
├── components/
│   ├── ui/           # Reusable UI components
│   ├── forms/        # Form-specific components
│   └── layouts/        # Layout components
├── lib/              # Utilities and helpers
└── controllers/        # Stimulus controllers