# Design System - Section Headers

## Overview
Section headers are toolbar components used at the top of main content pages (Research Hub, Strategy Hub, etc.). They follow the same pattern as the Page Editor header but with different actions and include a search input. Features the signature Orange→Pink→Blue ripple effect on the search input for consistency.

**Dimensions:** 967px × 55px

---

## Component Variants

| Variant | Primary Action | Description |
|---------|----------------|-------------|
| Research Hub | ← Upload existing docs | For research content management |
| Strategy Hub | Upload existing docs | For strategy content management |
| Page Editor | ← Back to strategy | For editing blueprint content |

---

## Section Header Specs

### Container

| Property | Value |
|----------|-------|
| Width | 967px |
| Height | 55px |
| Background | #FAFAFA |
| Border Bottom | 1px solid #E5E5E5 |
| Padding | 0 24px |
| Display | flex |
| Align Items | center |
| Justify Content | space-between |

### CSS

```css
.section-header {
  width: 967px;
  height: 55px;
  background: #FAFAFA;
  border-bottom: 1px solid #E5E5E5;
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
```

---

## Left Section (Actions)

### Action Item Specs

| Property | Value |
|----------|-------|
| Display | flex |
| Align Items | center |
| Gap | 6px |
| Font Family | Space Grotesk |
| Font Size | 14px |
| Font Weight | 300 |
| Color | #383737 |

### Primary Action (with back arrow)

| Property | Value |
|----------|-------|
| Font Weight | 400 |
| Text Decoration | underline |
| Text Underline Offset | 2px |

### Action Icons

| Property | Value |
|----------|-------|
| Width | 16px |
| Height | 16px |
| Stroke Width | 2px |

### CSS

```css
.header-left {
  display: flex;
  align-items: center;
  gap: 24px;
}

/* Action Button with Ripple Wrapper */
.action-wrapper {
  position: relative;
  display: inline-flex;
  border-radius: 4px;
  overflow: hidden;
}

.action-wrapper .ripple-grid {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  z-index: 1;
  overflow: hidden;
  border-radius: 4px;
}

.header-action {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 14px;
  font-weight: 300;
  color: #383737;
  background: rgba(250, 250, 250, 0.9);
  border: none;
  cursor: pointer;
  padding: 6px 10px;
  text-decoration: none;
  transition: color 0.2s ease;
  border-radius: 4px;
}

.header-action:hover {
  color: #1a1a2e;
}

.header-action.primary-action {
  font-weight: 400;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.action-icon {
  width: 16px;
  height: 16px;
}
```

### Action Button HTML Structure

```html
<div class="action-wrapper">
  <div class="ripple-grid"></div>
  <button class="header-action">
    <svg class="action-icon">...</svg>
    <span>Action Name</span>
  </button>
</div>
```

---

## Right Section (Search & View Toggle)

### Search Input Specs

| Property | Value |
|----------|-------|
| Width | 200px |
| Height | 32px |
| Background | #ffffff |
| Border | 1px solid #E5E5E5 |
| Border Radius | 6px |
| Padding | 0 12px |
| Font Family | Space Grotesk |
| Font Size | 12px |
| Color | #383737 |
| Placeholder Color | #9a9a9a |

### Search Input with Ripple

The search input container includes the signature ripple effect on hover for brand consistency.

| Property | Value |
|----------|-------|
| Position | relative |
| Overflow | hidden |
| Border Radius | 6px |

### View Toggle Specs

| Property | Value |
|----------|-------|
| Width | 28px |
| Height | 28px |
| Border Radius | 4px |
| Color (default) | #9a9a9a |
| Color (active) | #383737 |
| Icon Size | 18px |

### CSS

```css
.header-right {
  display: flex;
  align-items: center;
  gap: 16px;
}

/* Search Input with Ripple Container */
.search-wrapper {
  position: relative;
  width: 200px;
  height: 32px;
  border-radius: 6px;
  overflow: hidden;
}

.search-wrapper .ripple-grid {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  z-index: 1;
  overflow: hidden;
  border-radius: 6px;
}

.search-content {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.95);
  border: 1px solid #E5E5E5;
  border-radius: 6px;
}

.search-input {
  width: 100%;
  height: 100%;
  background: transparent;
  border: none;
  padding: 0 12px;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 12px;
  color: #383737;
  outline: none;
}

.search-input::placeholder {
  color: #9a9a9a;
}

/* View Toggle */
.view-toggles {
  display: flex;
  align-items: center;
  gap: 8px;
}

.view-toggle {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  cursor: pointer;
  border-radius: 4px;
  color: #9a9a9a;
  transition: background 0.2s ease, color 0.2s ease;
}

.view-toggle:hover {
  background: rgba(0, 0, 0, 0.05);
  color: #383737;
}

.view-toggle.active {
  color: #383737;
}

.view-toggle svg {
  width: 18px;
  height: 18px;
}
```

---

## Research Hub Header

### Actions

| Action | Icon | Style |
|--------|------|-------|
| ← Upload existing docs | left arrow | primary (underlined) |
| Analyse | document | secondary |
| Create Blank | plus/create | secondary |

### HTML

```html
<div class="section-header">
  <div class="header-left">
    <a href="#" class="header-action primary-action">
      <svg class="action-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <polyline points="15 18 9 12 15 6"/>
      </svg>
      <span>Upload existing docs</span>
    </a>
    <button class="header-action">
      <svg class="action-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
        <polyline points="14 2 14 8 20 8"/>
      </svg>
      <span>Analyse</span>
    </button>
    <button class="header-action">
      <svg class="action-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
        <polyline points="14 2 14 8 20 8"/>
        <line x1="12" y1="18" x2="12" y2="12"/>
        <line x1="9" y1="15" x2="15" y2="15"/>
      </svg>
      <span>Create Blank</span>
    </button>
  </div>
  <div class="header-right">
    <div class="search-wrapper">
      <div class="ripple-grid"></div>
      <div class="search-content">
        <input type="text" class="search-input" placeholder="Search Blueprints...">
      </div>
    </div>
    <div class="view-toggles">
      <button class="view-toggle active" title="Grid view">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <rect x="3" y="3" width="7" height="7"/>
          <rect x="14" y="3" width="7" height="7"/>
          <rect x="3" y="14" width="7" height="7"/>
          <rect x="14" y="14" width="7" height="7"/>
        </svg>
      </button>
      <button class="view-toggle" title="List view">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <line x1="8" y1="6" x2="21" y2="6"/>
          <line x1="8" y1="12" x2="21" y2="12"/>
          <line x1="8" y1="18" x2="21" y2="18"/>
          <line x1="3" y1="6" x2="3.01" y2="6"/>
          <line x1="3" y1="12" x2="3.01" y2="12"/>
          <line x1="3" y1="18" x2="3.01" y2="18"/>
        </svg>
      </button>
    </div>
  </div>
</div>
```

---

## Strategy Hub Header

### Actions

| Action | Icon | Style |
|--------|------|-------|
| Upload existing docs | upload | secondary (no arrow, no underline) |
| Analyse | document | secondary |
| Create Blank | plus/create | secondary |

### HTML

```html
<div class="section-header">
  <div class="header-left">
    <button class="header-action">
      <svg class="action-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
        <polyline points="17 8 12 3 7 8"/>
        <line x1="12" y1="3" x2="12" y2="15"/>
      </svg>
      <span>Upload existing docs</span>
    </button>
    <button class="header-action">
      <svg class="action-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
        <polyline points="14 2 14 8 20 8"/>
      </svg>
      <span>Analyse</span>
    </button>
    <button class="header-action">
      <svg class="action-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
        <polyline points="14 2 14 8 20 8"/>
        <line x1="12" y1="18" x2="12" y2="12"/>
        <line x1="9" y1="15" x2="15" y2="15"/>
      </svg>
      <span>Create Blank</span>
    </button>
  </div>
  <div class="header-right">
    <div class="search-wrapper">
      <div class="ripple-grid"></div>
      <div class="search-content">
        <input type="text" class="search-input" placeholder="Search Blueprints...">
      </div>
    </div>
    <div class="view-toggles">
      <button class="view-toggle active" title="Grid view">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <rect x="3" y="3" width="7" height="7"/>
          <rect x="14" y="3" width="7" height="7"/>
          <rect x="3" y="14" width="7" height="7"/>
          <rect x="14" y="14" width="7" height="7"/>
        </svg>
      </button>
      <button class="view-toggle" title="List view">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <line x1="8" y1="6" x2="21" y2="6"/>
          <line x1="8" y1="12" x2="21" y2="12"/>
          <line x1="8" y1="18" x2="21" y2="18"/>
          <line x1="3" y1="6" x2="3.01" y2="6"/>
          <line x1="3" y1="12" x2="3.01" y2="12"/>
          <line x1="3" y1="18" x2="3.01" y2="18"/>
        </svg>
      </button>
    </div>
  </div>
</div>
```

---

## Shared: Ripple Effect

The search input uses the signature Orange→Pink→Blue ripple effect on hover.

### CSS

```css
.ripple-cell {
  background-color: rgba(0, 0, 0, 0.02);
  border: 0.5px solid rgba(0, 0, 0, 0.03);
  opacity: 0.5;
  transition: opacity 0.15s ease, background-color 0.15s ease;
}

.ripple-cell.ripple-active {
  animation: cellRipple var(--duration, 150ms) ease-out var(--delay, 0ms);
}

@keyframes cellRipple {
  0% {
    background-color: rgba(251, 146, 60, 0.85);
    opacity: 1;
  }
  40% {
    background-color: rgba(244, 114, 182, 0.75);
    opacity: 1;
  }
  70% {
    background-color: rgba(147, 197, 253, 0.6);
    opacity: 0.9;
  }
  100% {
    background-color: rgba(0, 0, 0, 0.02);
    opacity: 0.5;
  }
}
```

### JavaScript

```javascript
function setupSearchRipple(wrapper) {
  const grid = wrapper.querySelector('.ripple-grid');
  const width = wrapper.offsetWidth;
  const height = wrapper.offsetHeight;
  const cellSize = 6;
  const cols = Math.ceil(width / cellSize);
  const rows = Math.ceil(height / cellSize);

  grid.style.gridTemplateColumns = `repeat(${cols}, ${cellSize}px)`;
  grid.style.gridTemplateRows = `repeat(${rows}, ${cellSize}px)`;

  const cells = [];
  for (let i = 0; i < rows * cols; i++) {
    const cell = document.createElement('div');
    cell.className = 'ripple-cell';
    cell.dataset.row = Math.floor(i / cols);
    cell.dataset.col = i % cols;
    grid.appendChild(cell);
    cells.push(cell);
  }

  function triggerRipple(targetRow, targetCol) {
    cells.forEach((cell, idx) => {
      const row = Math.floor(idx / cols);
      const col = idx % cols;
      const distance = Math.hypot(targetRow - row, targetCol - col);
      const delay = distance * 12;
      const duration = 100 + distance * 15;

      cell.classList.remove('ripple-active');
      void cell.offsetWidth;

      cell.style.setProperty('--delay', `${delay}ms`);
      cell.style.setProperty('--duration', `${duration}ms`);
      cell.classList.add('ripple-active');

      setTimeout(() => {
        cell.classList.remove('ripple-active');
      }, delay + duration);
    });
  }

  let lastRippleTime = 0;
  wrapper.addEventListener('mouseenter', (e) => {
    const now = Date.now();
    if (now - lastRippleTime > 400) {
      const rect = grid.getBoundingClientRect();
      const x = e.clientX - rect.left;
      const y = e.clientY - rect.top;
      triggerRipple(Math.floor(y / cellSize), Math.floor(x / cellSize));
      lastRippleTime = now;
    }
  });

  // Also trigger on focus
  const input = wrapper.querySelector('.search-input');
  if (input) {
    input.addEventListener('focus', () => {
      const now = Date.now();
      if (now - lastRippleTime > 400) {
        triggerRipple(Math.floor(rows / 2), 0);
        lastRippleTime = now;
      }
    });
  }
}
```

---

## Design Tokens

### Colors

| Token | Value | Usage |
|-------|-------|-------|
| `--color-header-bg` | #FAFAFA | Header background |
| `--color-border` | #E5E5E5 | Border color |
| `--color-text-action` | #383737 | Action text |
| `--color-text-action-hover` | #1a1a2e | Action hover |
| `--color-placeholder` | #9a9a9a | Search placeholder |
| `--color-toggle-default` | #9a9a9a | Inactive toggle |
| `--color-toggle-active` | #383737 | Active toggle |

### Typography

| Element | Font | Size | Weight |
|---------|------|------|--------|
| Action (secondary) | Space Grotesk | 14px | 300 |
| Action (primary) | Space Grotesk | 14px | 400 |
| Search Input | Space Grotesk | 12px | 400 |
| Search Placeholder | Space Grotesk | 12px | 400 |

### Spacing

| Token | Value |
|-------|-------|
| Header height | 55px |
| Header padding | 0 24px |
| Action gap | 32px |
| Action icon gap | 6px |
| Search width | 200px |
| Search height | 32px |
| Right section gap | 16px |
| Toggle gap | 8px |

### Dimensions

| Token | Value |
|-------|-------|
| Header width | 967px |
| Header height | 55px |
| Action icon size | 16px |
| Toggle icon size | 18px |
| Toggle button size | 28px |

---

## Interaction States

### Actions
- **Default:** color #383737, weight 300
- **Hover:** color #1a1a2e
- **Primary:** underlined, weight 400

### Search Input
- **Default:** border #E5E5E5
- **Focus:** ripple effect triggers
- **Hover:** ripple effect triggers

### View Toggle
- **Default:** color #9a9a9a
- **Hover:** background rgba(0,0,0,0.05), color #383737
- **Active:** color #383737

---

## Prototype
`section-headers-prototype/index.html`
