# RFCP - Iteration 10.2: Purple → Orange Gradient

**Goal:** Replace current warm palette (maroon→yellow) with purple→orange palette for better map contrast and intuitive UX  
**Priority:** P2 (UX Polish)  
**Estimated Time:** 15-20 minutes  
**Status:** Ready for Implementation

---

## 📋 Overview

After Iteration 10.1 fixed the cyan/green color conflict, user feedback indicated the current warm palette (yellow=good, red=bad) feels counter-intuitive. This iteration implements a purple→orange gradient that:
- Avoids map feature conflicts (no purple on maps)
- Provides intuitive "heat" visualization (orange = hot/strong signal)
- Maintains professional RF tool aesthetic

---

## 🐛 Current Issue

**User Feedback:** "тепер зона червона, а градієнт жовтий :) хз навіть як краще було"

**Problem:**
- Yellow (#ffeb3b) = excellent signal → near antenna center
- Red/Maroon (#8b0000) = weak signal → coverage edges
- This feels **counter-intuitive** (users expect red = danger/bad)

**Current Palette (Iteration 10.1):**
```
Deep Maroon → Red → Orange → Yellow
(weak)      ←──────────────→ (strong)
#4a0000 → #8b0000 → #ff9800 → #ffeb3b
```

---

## ✅ Solution: Purple → Orange Palette

**New Palette:**
```
Deep Purple → Purple → Lavender → Peach → Orange → Bright Orange
(weak)      ←────────────────────────────────────→ (strong)
```

**Color Values:**
```typescript
export function createRsrpGradient(): string[] {
  return [
    '#1a0033',  // Deep purple (very poor signal, -130 dBm)
    '#4a148c',  // Dark purple
    '#7b1fa2',  // Purple
    '#ab47bc',  // Light purple / Lavender
    '#ff8a65',  // Peach / Light orange
    '#ff6f00',  // Dark orange
    '#ffb74d',  // Bright orange (excellent signal, -50 dBm)
  ];
}
```

**Why Purple → Orange:**
- ✅ **No map conflicts:** Purple doesn't appear on OpenTopoMap or OpenStreetMap
- ✅ **Intuitive heat:** Orange = "hot" = strong signal (like thermal imaging)
- ✅ **Professional aesthetic:** Used in professional RF planning tools
- ✅ **Good contrast:** Purple/Orange highly distinguishable
- ✅ **Colorblind-friendly:** Purple-orange works for most color vision types

---

## 📁 Files to Modify

### 1. `src/utils/colorGradient.ts`

**Current Code (lines ~5-15):**
```typescript
export function createRsrpGradient(): string[] {
  return [
    '#4a0000',  // Deep maroon (very poor signal)
    '#8b0000',  // Dark red
    '#cc0000',  // Red
    '#ff0000',  // Bright red
    '#ff4444',  // Orange-red
    '#ff9800',  // Orange
    '#ffeb3b',  // Yellow (excellent signal)
  ];
}
```

**Replace With:**
```typescript
export function createRsrpGradient(): string[] {
  return [
    '#1a0033',  // Deep purple (very poor signal, -130 dBm)
    '#4a148c',  // Dark purple
    '#7b1fa2',  // Purple
    '#ab47bc',  // Light purple / Lavender
    '#ff8a65',  // Peach / Light orange
    '#ff6f00',  // Dark orange
    '#ffb74d',  // Bright orange (excellent signal, -50 dBm)
  ];
}
```

### 2. `src/constants/rsrp-thresholds.ts`

**Find and Update SIGNAL_COLORS:**
```typescript
// Old:
export const SIGNAL_COLORS = {
  excellent: '#ffeb3b',  // Yellow
  good: '#ff9800',       // Orange
  fair: '#ff4444',       // Orange-red
  poor: '#ff0000',       // Red
  veryPoor: '#cc0000',   // Dark red
  terrible: '#8b0000',   // Very dark red
};

// New:
export const SIGNAL_COLORS = {
  excellent: '#ffb74d',  // Bright orange (-50 to -70 dBm)
  good: '#ff6f00',       // Dark orange (-70 to -85 dBm)
  fair: '#ff8a65',       // Peach (-85 to -100 dBm)
  poor: '#ab47bc',       // Light purple (-100 to -110 dBm)
  veryPoor: '#7b1fa2',   // Purple (-110 to -120 dBm)
  terrible: '#4a148c',   // Dark purple (-120 to -130 dBm)
};
```

### 3. Check Legend Component (if exists)

**Search for hardcoded colors:**
```bash
grep -rn "#ffeb3b\|#ff9800\|#8b0000" src/
```

If found in legend or other components, update to match new palette.

---

## 🔍 Investigation Commands

**Before making changes, verify file locations:**
```bash
# Find gradient file
find /opt/rfcp/frontend/src -name "colorGradient.ts" -o -name "*gradient*"

# Find threshold constants
find /opt/rfcp/frontend/src -name "*threshold*" -o -name "*rsrp*"

# Check for hardcoded old colors
grep -rn "#ffeb3b\|#4a0000\|#8b0000" /opt/rfcp/frontend/src/

# Check legend component
find /opt/rfcp/frontend/src -name "*Legend*" -o -name "*legend*"
```

---

## 🧪 Testing Checklist

### Visual Testing

- [ ] **Gradient smoothness:** Colors transition smoothly from purple to orange
- [ ] **Center coverage:** Bright orange (#ffb74d) visible near antenna
- [ ] **Edge coverage:** Deep purple (#1a0033) visible at coverage edges
- [ ] **Map contrast:** No color conflicts with OpenTopoMap features
- [ ] **Different zoom levels:** Gradient looks correct at zoom 8, 12, 16

### Legend Testing

- [ ] **Legend colors match:** RSRP legend shows new color scheme
- [ ] **Labels correct:** dBm values still display correctly
- [ ] **Readability:** Legend text readable against new colors

### Regression Testing

- [ ] **50m resolution:** Still works without crash (Iteration 10.1 fix intact)
- [ ] **Delete confirmation:** Still shows dialog (Iteration 10.1 fix intact)
- [ ] **Keyboard shortcuts:** All shortcuts still functional
- [ ] **Multi-sector:** Coverage calculation still correct

### Edge Cases

- [ ] **Single site:** Gradient displays correctly
- [ ] **Multiple sites:** Overlapping coverage shows strongest signal
- [ ] **Terrain enabled:** Gradient still visible with terrain layer
- [ ] **Dark mode:** Colors work in dark mode (if applicable)

---

## 🏗️ Build & Deploy

```bash
# Navigate to frontend
cd /opt/rfcp/frontend

# Install dependencies (if needed)
npm install

# Run development server to test
npm run dev

# Build for production
npm run build

# Check for errors
# Expected: 0 TypeScript errors, 0 ESLint errors

# Deploy (reload Caddy)
sudo systemctl reload caddy

# Verify deployment
curl -s https://rfcp.eliah.one | head -20
```

---

## 📝 Commit Message

```
feat(heatmap): replace warm palette with purple→orange gradient

- Changed RSRP gradient from maroon→yellow to purple→orange
- Updated SIGNAL_COLORS constants to match new palette
- Better map contrast (purple not present on maps)
- More intuitive heat visualization (orange = strong signal)

Colors: #1a0033 (weak) → #ffb74d (strong)

Iteration: 10.2
Fixes: User feedback on gradient aesthetics
```

---

## ✅ Success Criteria

**Must Pass:**
1. ✅ Gradient displays purple (weak) → orange (strong)
2. ✅ No cyan, green, or blue colors anywhere
3. ✅ Legend matches new color scheme
4. ✅ No regression in 50m resolution performance
5. ✅ TypeScript: 0 errors
6. ✅ ESLint: 0 errors
7. ✅ Production build succeeds

**User Acceptance:**
- Олег confirms: "виглядає краще" or "норм"
- If not satisfied → Iteration 10.3 with alternative palette

---

## 🎨 Alternative Palettes (If Needed)

**Option C: Grayscale → Orange (Fallback)**
```typescript
return [
  '#1a1a1a',  // Near black (very poor)
  '#4a4a4a',  // Dark gray
  '#808080',  // Medium gray
  '#b3b3b3',  // Light gray
  '#ff6f00',  // Dark orange
  '#ff9800',  // Orange
  '#ffb74d',  // Light orange (excellent)
];
```

**Option D: Blue → Red (Classic Heat)**
```typescript
return [
  '#0d47a1',  // Dark blue (very poor)
  '#1976d2',  // Blue
  '#42a5f5',  // Light blue
  '#fff176',  // Yellow
  '#ff9800',  // Orange
  '#f44336',  // Red
  '#b71c1c',  // Dark red (excellent)
];
```

---

## 📊 Color Reference Table

| RSRP Range | Signal Quality | Old Color | New Color | Hex |
|------------|----------------|-----------|-----------|-----|
| > -70 dBm | Excellent | Yellow | Bright Orange | #ffb74d |
| -70 to -85 | Good | Orange | Dark Orange | #ff6f00 |
| -85 to -100 | Fair | Orange-Red | Peach | #ff8a65 |
| -100 to -110 | Poor | Red | Light Purple | #ab47bc |
| -110 to -120 | Very Poor | Dark Red | Purple | #7b1fa2 |
| < -120 dBm | Terrible | Maroon | Dark Purple | #4a148c |
| < -130 dBm | No Service | Deep Maroon | Deep Purple | #1a0033 |

---

## 🤖 Instructions for Claude Code

**Context:**
- Project: RFCP (RF Coverage Planning) - `/opt/rfcp/frontend/`
- Framework: React 18 + TypeScript + Vite + Leaflet
- This is a simple color palette change in 2-3 files

**Implementation Steps:**
1. Search for `colorGradient.ts` and update gradient array
2. Search for `rsrp-thresholds.ts` and update SIGNAL_COLORS
3. Search for any hardcoded old colors and update them
4. Run `npm run build` to verify no errors
5. Test at https://rfcp.eliah.one after deploy

**Priority:** Quick UX fix, should take ~15 minutes

**Success:** User sees purple (weak) → orange (strong) gradient on map

---

**Document Created:** 2025-01-30  
**Author:** Claude (Sonnet 4.5) + Олег  
**Status:** Ready for Implementation  
**Next:** Віддати Claude Code → Test → Screenshot → Confirm
