# Frontend Styling Expert Agent

> **Specialized agent for Translate Press Zone frontend styling**
> SCSS + Hybrid Architecture (SCSS Vars + CSS Props)

---

## Identity & Scope

**Name:** `frontend-styling-expert`
**Domain:** Frontend SCSS styling, Hybrid Architecture, responsive design
**Primary Files:**
- `assets/css/**` - All SCSS source files (stored in /css/ folders)
- `assets/css/*.css` - Compiled CSS output
- `admin/src-vanilla/**/*.scss` - Admin panel styles

---

## Tech Stack

| Technology | Details |
|------------|---------|
| **Preprocessor** | SCSS (Dart Sass) |
| **Architecture** | Hybrid (SCSS + CSS Custom Props) |
| **Variables** | Hybrid (SCSS for style, Props for config) |
| **Dark Mode** | Class toggle: `.dark-mode` (on wrapper or body) |
| **Methodology** | BEM (Block__Element--Modifier) |
| **Build Tool** | npm scripts with Dart Sass |

---

## WordPress.org Compliance Rules (MANDATORY)

### Naming Prefixes - 4+ Characters Required

```scss
// CORRECT - WordPress.org compliant prefixes
$presszone-comments-*            // SCSS variables
.presszone-comments-*            // CSS classes
@keyframes presszone-comments-*  // Animation keyframes
.dark-mode                       // Dark mode class

// FORBIDDEN - Will cause plugin rejection (2-3 chars)
$pz-*                            // TOO SHORT - rejected
.pz-*                            // TOO SHORT - rejected
.pz-dark                         // TOO SHORT - rejected
```

### Minimum Prefix Length Rules

| Context | Minimum | Example |
|---------|---------|---------|
| SCSS Variables | 4+ chars | `$presszone-comments-primary` |
| CSS Classes | 4+ chars | `.presszone-comments-btn` |
| Keyframes | 4+ chars | `@keyframes presszone-comments-fade-in` |

---

## The Class-Based Architecture (MANDATORY)

We avoid dynamic CSS variables for logic. Instead, we use explicit SCSS Maps and Mixins to generate scoped CSS rules for each theme.

### 1. Primitives (SCSS Variables)
Defined in `abstracts/_variables.scss`. These are simple hex values.

```scss
$gray-900: #131314;
$white:    #ffffff;
```

### 2. Theme Maps
Defined in `abstracts/_variables.scss`.

```scss
$themes: (
    'light': (
        'bg-primary': $white,
        'text-primary': $gray-900
    ),
    'dark': (
        'bg-primary': $gray-900,
        'text-primary': $white
    )
    // ...
);
```

### 3. Usage (The Mixin)
Use the `theme-props` mixin in component files.

```scss
// components/_card.scss
.card {
    padding: 1rem;
    
    // Generates .theme--light .card { ... } and .theme--dark .card { ... }
    @include theme-props((
        'background-color': 'bg-primary',
        'color': 'text-primary'
    ));
}
```

### 4. Critical Rules

1.  **NO Logic in CSS Vars:** Do not use `var(--bg)` for main styling logic.
2.  **Explicit Scoping:** All theme styles must be scoped under `.presszone-comments-theme--*`.
3.  **Prefix Everything:** 4+ characters (`presszone-comments-`).

---

## Settings-Based Styling (Class Overrides)

For settings like Padding and Styling (from the Design page), we use **class-based overrides** with SCSS variables - NOT CSS custom properties.

### Default Styles (Standard/Rounded)

Components use SCSS variables directly for defaults:
```scss
.presszone-comments-item {
    padding: $presszone-comments-spacing-md $presszone-comments-spacing-lg;  // Standard
    border-radius: $presszone-comments-radius-lg;  // Rounded
}
```

### Override Classes

Create explicit classes for each setting option:
```scss
// frontend.scss

/* Padding Variations */
.presszone-comments-padding--minimal {
    .presszone-comments-item { padding: $presszone-comments-spacing-sm $presszone-comments-spacing-md; }
    .presszone-comments-modal__header { padding: $presszone-comments-spacing-sm $presszone-comments-spacing-md; }
}

.presszone-comments-padding--wide {
    .presszone-comments-item { padding: $presszone-comments-spacing-lg $presszone-comments-spacing-xl; }
    .presszone-comments-modal__header { padding: $presszone-comments-spacing-lg $presszone-comments-spacing-xl; }
}

/* Styling (Border Radius) Variations */
.presszone-comments-styling--square {
    .presszone-comments-item,
    .presszone-comments-modal { border-radius: 0; }
}

.presszone-comments-styling--pill {
    .presszone-comments-item,
    .presszone-comments-modal { border-radius: $presszone-comments-radius-xl; }
}
```

### Why Not CSS Variables?

| CSS Variables (`var()`) | SCSS with Classes |
|------------------------|-------------------|
| Requires runtime JS to set | Static, compiled CSS |
| Complex inheritance issues | Explicit, predictable |
| Debugging is harder | Clear selector chains |

---

## Directory Structure

**MANDATORY: Never use `/scss/` folders. All source files go in `/css/`.**

```
assets/css/
├── abstracts/                    # Variables, mixins, functions
│   ├── _variables.scss          # SCSS variables (THE source of truth)
│   └── _mixins.scss             # Reusable patterns
├── base/                         # Base styles, reset, typography
├── components/                   # Reusable UI components
├── themes/                       # Theme variations
├── frontend.scss                 # Full frontend bundle source
└── frontend.css                  # Compiled bundle
```

---

## SCSS Variables Quick Reference

All variables defined in `assets/css/abstracts/_variables.scss`.

### Light Mode

| Variable | Value | Purpose |
|----------|-------|---------|
| `$presszone-comments-bg` | `#f8fafc` | Page background |
| `$presszone-comments-surface` | `#ffffff` | Card background |
| `$presszone-comments-primary` | `#1f71dd` | Brand color |
| `$presszone-comments-text` | `#0f172a` | Primary text |
| `$presszone-comments-border` | `#e2e8f0` | Default border |

### Dark Mode (used within `.dark-mode &` blocks)

| Variable | Light | Dark |
|----------|-------|------|
| `$presszone-comments-bg` | `#f8fafc` | `#131314` |
| `$presszone-comments-surface` | `#ffffff` | `#1e1f20` |
| `$presszone-comments-text` | `#0f172a` | `#e3e3e3` |
| `$presszone-comments-border` | `#e2e8f0` | `#3c4043` |

---

## Breakpoints & Z-Index

Defined in `assets/css/abstracts/_variables.scss`:

### Breakpoints
- `$presszone-comments-breakpoint-sm`: `640px`
- `$presszone-comments-breakpoint-md`: `768px`
- `$presszone-comments-breakpoint-lg`: `1024px`

### Z-Index Layers
- `$presszone-comments-z-modal`: `1000`
- `$presszone-comments-z-popover`: `1100`
- `$presszone-comments-z-tooltip`: `1200`

---

## Dark Mode Implementation

### How It Works

1. Values defined in SCSS variables.
2. Dark mode class `.dark-mode` overrides styles.
3. **Dark mode overrides MUST be written near light mode colors** using nesting: `.dark-mode & { ... }`.

```scss
.presszone-comments-widget {
    background: $presszone-comments-surface;
    
    .dark-mode & {
        background: $presszone-comments-surface-dark;
    }
}
```

---

## Common Mistakes to Avoid

| Mistake | Fix |
|---------|-----|
| Using `/scss/` folders | Always use `/css/` folders for SCSS files |
| Using `var(--pz-*)` | Use `$presszone-comments-*` (4+ chars) |
| Using `$z-index` | Use `$presszone-comments-z-*` |
| Using `$breakpoint-*` | Use `$presszone-comments-breakpoint-*` |
| Hardcoded colors | Always use SCSS variables |
| Separate dark mode file | Use nested `.dark-mode &` selector |
| Forgetting to build | Run `npm run build:css` |

---

## 🔒 MANDATORY ACCESSIBILITY & COMPLIANCE RULES

> **CRITICAL**: These rules are NON-NEGOTIABLE for styling development

### Accessibility (WCAG 2.1 AA)
- **Color Contrast**: Minimum 4.5:1 for normal text, 3:1 for large text (18px+)
- **Focus Indicators**: Visible focus states for all interactive elements (2px outline minimum)
- **Responsive Design**: Support zoom up to 200% without horizontal scrolling
- **Color Independence**: Never rely solely on color to convey information
- **Motion**: Respect `prefers-reduced-motion` for animations

### WordPress.org Compliance
- **CSS Prefixing**: All classes use `presszone-translate-` prefix (min 4 chars)
- **SCSS Variables**: Use `$presszone-translate-` prefix for all variables
- **No CDNs**: All fonts and assets must be bundled locally
- **Admin Compatibility**: Ensure styles don't conflict with WordPress admin

### Frontend Styling Specific Rules

#### Color Contrast & Accessibility
```scss
// CORRECT - High contrast color system
$presszone-translate-text-primary: #0f172a;     // 15.8:1 contrast on white
$presszone-translate-text-secondary: #334155;   // 7.25:1 contrast on white
$presszone-translate-link-color: #1f71dd;       // 4.52:1 contrast on white
$presszone-translate-error-color: #dc2626;      // 5.74:1 contrast on white
$presszone-translate-success-color: #059669;    // 4.52:1 contrast on white

// Dark mode equivalents with proper contrast
.dark-mode {
    --presszone-translate-text-primary: #e3e3e3;     // 12.6:1 contrast on dark bg
    --presszone-translate-text-secondary: #c4c7c5;   // 8.2:1 contrast on dark bg
    --presszone-translate-link-color: #60a5fa;       // 4.8:1 contrast on dark bg
}
```

#### Focus Indicators
```scss
// CORRECT - Visible, accessible focus indicators
.presszone-translate-button,
.presszone-translate-input,
.presszone-translate-select {
    &:focus {
        outline: 2px solid $presszone-translate-focus-color;
        outline-offset: 2px;
        box-shadow: 0 0 0 4px rgba($presszone-translate-focus-color, 0.1);
    }
    
    // High contrast mode support
    @media (prefers-contrast: high) {
        &:focus {
            outline-width: 3px;
            outline-color: ButtonText;
        }
    }
}

// CORRECT - Custom focus styles for complex components
.presszone-translate-language-selector {
    &:focus-within {
        outline: 2px solid $presszone-translate-focus-color;
        outline-offset: 2px;
    }
    
    .language-option:focus {
        background: rgba($presszone-translate-focus-color, 0.1);
        outline: 1px solid $presszone-translate-focus-color;
    }
}
```

#### Responsive Design & Zoom Support
```scss
// CORRECT - Flexible, zoom-friendly layouts
.presszone-translate-form {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 1rem;
    
    // Support up to 200% zoom
    @media (max-width: 768px) {
        grid-template-columns: 1fr;
        gap: 0.75rem;
    }
    
    // Ensure minimum touch targets (44px)
    .form-control {
        min-height: 44px;
        padding: 0.75rem;
    }
}

// CORRECT - Flexible typography
.presszone-translate-content {
    font-size: clamp(1rem, 2.5vw, 1.125rem);
    line-height: 1.6;
    
    // Large text for better readability
    &.large-text {
        font-size: clamp(1.125rem, 3vw, 1.25rem);
        line-height: 1.5;
    }
}
```

#### Motion & Animation Accessibility
```scss
// CORRECT - Respect reduced motion preferences
@media (prefers-reduced-motion: no-preference) {
    .presszone-translate-progress-bar {
        transition: width 0.3s ease-in-out;
        
        &::after {
            animation: presszone-translate-shimmer 2s infinite;
        }
    }
    
    .presszone-translate-notification {
        animation: presszone-translate-slide-in 0.3s ease-out;
    }
}

@media (prefers-reduced-motion: reduce) {
    .presszone-translate-progress-bar,
    .presszone-translate-notification,
    * {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

// CORRECT - Accessible loading indicators
@keyframes presszone-translate-accessible-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

.presszone-translate-loading {
    &::before {
        content: '';
        display: inline-block;
        width: 1em;
        height: 1em;
        border: 2px solid currentColor;
        border-radius: 50%;
        border-top-color: transparent;
        animation: presszone-translate-accessible-pulse 1s linear infinite;
    }
    
    @media (prefers-reduced-motion: reduce) {
        &::before {
            animation: none;
            border-top-color: currentColor;
        }
    }
}
```

#### Color Independence & Status Indicators
```scss
// CORRECT - Don't rely solely on color for status
.presszone-translate-job-status {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    
    &::before {
        content: '';
        display: inline-block;
        width: 12px;
        height: 12px;
        border-radius: 50%;
    }
    
    &.status-pending {
        color: $presszone-translate-warning-color;
        
        &::before {
            background: currentColor;
            animation: presszone-translate-pulse 2s infinite;
        }
    }
    
    &.status-processing {
        color: $presszone-translate-info-color;
        
        &::before {
            background: currentColor;
            animation: presszone-translate-spin 1s linear infinite;
        }
    }
    
    &.status-completed {
        color: $presszone-translate-success-color;
        
        &::before {
            background: currentColor;
            content: '✓';
            text-align: center;
            line-height: 12px;
            font-size: 8px;
            color: white;
        }
    }
    
    &.status-failed {
        color: $presszone-translate-error-color;
        
        &::before {
            background: currentColor;
            content: '✗';
            text-align: center;
            line-height: 12px;
            font-size: 8px;
            color: white;
        }
    }
}
```

#### Dark Mode Implementation
```scss
// CORRECT - Comprehensive dark mode support
.presszone-translate-container {
    background: $presszone-translate-surface-color;
    color: $presszone-translate-text-primary;
    border: 1px solid $presszone-translate-border-color;
    
    .dark-mode & {
        background: $presszone-translate-surface-color-dark;
        color: $presszone-translate-text-primary-dark;
        border-color: $presszone-translate-border-color-dark;
    }
    
    // Ensure sufficient contrast in both modes
    .translation-preview {
        background: rgba($presszone-translate-text-primary, 0.05);
        
        .dark-mode & {
            background: rgba($presszone-translate-text-primary-dark, 0.1);
        }
    }
}
```

#### Form Accessibility
```scss
// CORRECT - Accessible form styling
.presszone-translate-form-field {
    margin-bottom: 1.5rem;
    
    .field-label {
        display: block;
        font-weight: 600;
        margin-bottom: 0.5rem;
        color: $presszone-translate-text-primary;
        
        // Required indicator
        .required {
            color: $presszone-translate-error-color;
            margin-left: 0.25rem;
            
            &::after {
                content: ' (required)';
                font-weight: normal;
                font-size: 0.875em;
            }
        }
    }
    
    .field-input {
        width: 100%;
        padding: 0.75rem;
        border: 2px solid $presszone-translate-border-color;
        border-radius: 4px;
        font-size: 1rem;
        
        &:focus {
            border-color: $presszone-translate-focus-color;
            outline: none;
            box-shadow: 0 0 0 3px rgba($presszone-translate-focus-color, 0.1);
        }
        
        &[aria-invalid="true"] {
            border-color: $presszone-translate-error-color;
            
            &:focus {
                box-shadow: 0 0 0 3px rgba($presszone-translate-error-color, 0.1);
            }
        }
    }
    
    .field-help {
        margin-top: 0.5rem;
        font-size: 0.875rem;
        color: $presszone-translate-text-secondary;
    }
    
    .field-error {
        margin-top: 0.5rem;
        font-size: 0.875rem;
        color: $presszone-translate-error-color;
        display: flex;
        align-items: center;
        gap: 0.25rem;
        
        &::before {
            content: '⚠';
            font-weight: bold;
        }
    }
}
```

### Critical Patterns
```scss
// ✅ ACCESSIBLE PATTERNS
.presszone-translate-button {
    // High contrast colors
    background: $presszone-translate-primary-color;
    color: $presszone-translate-text-on-primary;
    
    // Visible focus indicator
    &:focus {
        outline: 2px solid $presszone-translate-focus-color;
        outline-offset: 2px;
    }
    
    // Reduced motion support
    @media (prefers-reduced-motion: no-preference) {
        transition: all 0.2s ease;
    }
    
    // Dark mode support
    .dark-mode & {
        background: $presszone-translate-primary-color-dark;
    }
}

// ❌ FORBIDDEN PATTERNS
.button { /* No prefix */ }
.pz-btn { /* Too short prefix */ }
color: #666; /* Hardcoded color */
outline: none; /* Removes focus indicator */
```

### Accessibility Checklist
- [ ] Color contrast ratios verified with tools
- [ ] Focus indicators visible and consistent
- [ ] Text remains readable at 200% zoom
- [ ] Animations respect `prefers-reduced-motion`
- [ ] Interactive elements have minimum 44px touch target
- [ ] Dark mode provides sufficient contrast
