Files
Frank 2af477397e added more file type specific instructions
I hope that coding results will be better and more consistent
2025-12-21 08:39:29 +01:00

8.2 KiB

description, applyTo
description applyTo
Instructions for writing CSS following project conventions and best practices **/*.css,**/*.vue

CSS Development Instructions

Follow project-specific CSS conventions and modern best practices.

Scoped Styles in Vue Components

Always Use Scoped Styles

<style scoped>
.component-class {
  /* Styles only apply to this component */
}
</style>

Critical: Use scoped attribute to prevent style conflicts between components.

Layout Patterns

Flexbox for Component Layouts

Standard pattern for headers, modals, and lists:

.header-content {
  display: flex;
  align-items: center;
  gap: 15px; /* Use gap instead of margin */
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

Common Flex Patterns

/* Horizontal layout with spacing */
.horizontal-layout {
  display: flex;
  gap: 10px;
  align-items: center;
}

/* Vertical centering */
.centered {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

/* Space between items */
.space-between {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

Modal Dialog Styling

Standard Modal Pattern

/* Overlay - covers entire viewport */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

/* Modal content container */
.modal-content {
  background: white;
  border-radius: 8px;
  width: 90%;
  max-width: 500px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

/* Modal sections */
.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  border-bottom: 1px solid #dee2e6;
}

.modal-body {
  padding: 20px;
  position: relative; /* For loading overlays */
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 20px;
  border-top: 1px solid #dee2e6;
}

Button Styling

Standard Button Styles

/* Primary action button */
.btn-primary,
.btn-export {
  padding: 10px 20px;
  border: 1px solid #007bff;
  border-radius: 6px;
  background: #007bff;
  color: white;
  cursor: pointer;
  font-weight: 500;
  transition: all 0.2s ease;
}

.btn-primary:hover:not(:disabled) {
  background: #0056b3;
  border-color: #0056b3;
}

.btn-primary:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* Cancel/secondary button */
.btn-cancel {
  padding: 10px 20px;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  background: #f8f9fa;
  color: #495057;
  cursor: pointer;
  font-weight: 500;
  transition: all 0.2s ease;
}

.btn-cancel:hover {
  background: #e9ecef;
  border-color: #adb5bd;
}

/* Icon-only button */
.export-button-small {
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid #007bff;
  border-radius: 8px;
  background: #007bff;
  color: white;
  font-size: 1.2rem;
  cursor: pointer;
  transition: all 0.2s ease;
  flex-shrink: 0;
}

.export-button-small:hover {
  background: #0056b3;
  transform: scale(1.05);
}

Form Elements

Input Styling

.template-select,
input[type="text"],
input[type="email"] {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  background: white;
  color: #495057;
  font-size: 0.95rem;
}

.template-select:focus,
input:focus {
  outline: none;
  border-color: #007bff;
  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}

input:disabled,
select:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  background: #e9ecef;
}

Checkbox Styling

.checkbox-label {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  user-select: none;
}

.checkbox-label input[type="checkbox"] {
  width: 18px;
  height: 18px;
  cursor: pointer;
}

Loading Animations

Spinner Animation

.spinner {
  border: 4px solid #f3f3f3;
  border-top: 4px solid #007bff;
  border-radius: 50%;
  width: 50px;
  height: 50px;
  animation: spin 1s linear infinite;
  margin-bottom: 15px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

Loading Overlay

.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.95);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  z-index: 10;
}

.loading-overlay p {
  color: #007bff;
  font-weight: 500;
  margin: 0;
}

Color Scheme

Standard Colors

/* Primary */
--primary: #007bff;
--primary-hover: #0056b3;

/* Text */
--text-primary: #333;
--text-secondary: #495057;
--text-muted: #666;

/* Backgrounds */
--bg-light: #f8f9fa;
--bg-gray: #e9ecef;

/* Borders */
--border-light: #dee2e6;
--border-dark: #adb5bd;

/* Semantic colors */
--success: #28a745;
--danger: #dc3545;
--warning: #ffc107;

Use these consistently across components for visual coherence.

Spacing System

Use Consistent Spacing

/* Prefer these spacing values */
gap: 8px;   /* Tight spacing */
gap: 10px;  /* Default spacing */
gap: 15px;  /* Medium spacing */
gap: 20px;  /* Large spacing */

padding: 10px 12px; /* Inputs */
padding: 20px;      /* Modal sections */

Typography

Font Sizing

h2 {
  font-size: 1.5rem;
  margin: 0;
  color: #333;
}

h3 {
  font-size: 1.25rem;
  margin: 0;
  color: #333;
}

p, span {
  font-size: 0.95rem;
  color: #495057;
}

small {
  font-size: 0.875rem;
  color: #666;
}

Font Weight

font-weight: 400; /* Normal */
font-weight: 500; /* Medium (buttons, labels) */
font-weight: 600; /* Semibold (headings) */

Transitions and Animations

Standard Transitions

/* Buttons, interactive elements */
transition: all 0.2s ease;

/* Background changes */
transition: background 0.3s ease;

/* Transform animations */
transition: transform 0.2s ease;

Hover Effects

button:hover {
  transform: scale(1.02); /* Subtle scale */
}

.card:hover {
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
}

Responsive Design

Mobile-First Approach

/* Base styles (mobile) */
.modal-content {
  width: 90%;
  max-width: 500px;
}

/* Tablet and up */
@media (min-width: 768px) {
  .modal-content {
    width: 600px;
  }
}

/* Desktop */
@media (min-width: 1024px) {
  .modal-content {
    width: 700px;
  }
}

Best Practices

  1. Always use scoped on Vue component styles
  2. Use flexbox for layouts instead of floats or positioning
  3. Use gap property instead of margins for spacing
  4. Keep selectors simple - avoid deep nesting
  5. Use relative units (rem, em) for font sizes
  6. Add transitions for interactive elements
  7. Use CSS variables for repeated values
  8. Keep z-index organized (modals: 1000, dropdowns: 100, etc.)
  9. Test hover states for all interactive elements
  10. Include disabled states for buttons and inputs

Anti-Patterns to Avoid

Don't use !important unless absolutely necessary Don't use inline styles in templates - use classes Don't use fixed pixel widths for responsive layouts Don't nest selectors more than 3 levels deep Don't use IDs for styling - use classes Don't forget :hover, :focus, :disabled states Don't use position: absolute unless necessary Don't forget to test in different viewport sizes Don't use vendor prefixes manually - use autoprefixer

Common Component Patterns

Close Button

.close-button {
  background: none;
  border: none;
  font-size: 1.5rem;
  color: #999;
  cursor: pointer;
  padding: 0;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.close-button:hover {
  color: #333;
}

Full-Height Container

.character-details {
  width: 100%;
  height: 100%;
  padding: 20px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
}

Submenu/Tabs

.submenu {
  display: flex;
  gap: 10px;
  margin: 20px 0;
  flex-wrap: wrap;
}

.submenu button {
  padding: 10px 16px;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  background: #f8f9fa;
  color: #495057;
  cursor: pointer;
  transition: all 0.2s ease;
}

.submenu button.active {
  background: #007bff;
  color: white;
  border-color: #007bff;
}