# Tab Restructure — Kill Canvas, Separate Previz + Render

> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

**Goal:** Replace the 5-tab layout (Script, Previz, Board, Dailies, Canvas) with a cleaner 5-tab layout (Script, Board, Previz, Render, Dailies) — killing the Canvas wrapper, deleting the legacy previz.js strangler fig, and giving Previz and Render their own top-level tabs with the 3-column layout.

**Architecture:** Both Previz and Render tabs share `CanvasState` (singleton), `CanvasViewport`, data fetching, polling, and all API actions from `canvas/main.js`. Each tab creates its own 3-column DOM (shot list | workspace | viewport) in its own `<div class="tab-panel">`. The workspace sub-tab toggle (STORYBOARD/PREVIZ/RENDER) is removed — which tab you're on determines what the workspace renders. The storyboard grid moves into Board as a visual view mode.

**Tech Stack:** Vanilla JS (IIFE pattern), morphdom, CSS custom properties. No build step.

---

## Current File Inventory

| File | Lines | Role | Fate |
|------|-------|------|------|
| `tabs/previz.js` | 1,919 | Old strangler-fig previz tab | **DELETE** |
| `tabs/canvas/state.js` | 68 | CanvasState singleton | Keep, remove 'storyboard' mode |
| `tabs/canvas/viewport.js` | 77 | Viewport renderer | Keep as-is |
| `tabs/canvas/storyboard.js` | 68 | Storyboard grid builder | **DELETE** (move grid into board.js) |
| `tabs/canvas/previz.js` | 204 | Previz workspace builder | Keep as-is |
| `tabs/canvas/production.js` | 327 | Render workspace builder | Keep as-is |
| `tabs/canvas/main.js` | 1,178 | Orchestrator + actions | Modify: register 2 tabs, remove storyboard mode |
| `tabs/board.js` | 419 | Board tab | Modify: add storyboard grid view |

---

## Task 1: Update HTML — New Tab Buttons + Panels

**File:** `editors/production-console.html`

**Step 1:** Replace the console-bar-tabs section. Remove old PREVIZ (02) and CANVAS (05) buttons. Add new PREVIZ (03) and RENDER (04) buttons. Renumber BOARD to 02 and DAILIES to 05.

Old tab buttons:
```html
<button class="tab-btn active" data-tab="script"><span class="tab-num">01</span> SHOOTING SCRIPT</button>
<button class="tab-btn" data-tab="previz"><span class="tab-num">02</span> PREVIZ</button>
<button class="tab-btn" data-tab="board"><span class="tab-num">03</span> BOARD</button>
<button class="tab-btn" data-tab="dailies"><span class="tab-num">04</span> DAILIES ...</button>
<button class="tab-btn" data-tab="canvas"><span class="tab-num">05</span> CANVAS</button>
```

New tab buttons:
```html
<button class="tab-btn active" data-tab="script"><span class="tab-num">01</span> SHOOTING SCRIPT</button>
<button class="tab-btn" data-tab="board"><span class="tab-num">02</span> BOARD</button>
<button class="tab-btn" data-tab="previz"><span class="tab-num">03</span> PREVIZ</button>
<button class="tab-btn" data-tab="render"><span class="tab-num">04</span> RENDER</button>
<button class="tab-btn" data-tab="dailies"><span class="tab-num">05</span> DAILIES ...</button>
```

**Step 2:** Replace the panel divs in the workspace section:

Old panels:
```html
<div id="panel-script" class="tab-panel active"></div>
<div id="panel-previz" class="tab-panel"></div>
<div id="panel-board" class="tab-panel"></div>
<div id="panel-dailies" class="tab-panel"></div>
<div id="panel-canvas" class="tab-panel"></div>
```

New panels:
```html
<div id="panel-script" class="tab-panel active"></div>
<div id="panel-board" class="tab-panel"></div>
<div id="panel-previz" class="tab-panel"></div>
<div id="panel-render" class="tab-panel"></div>
<div id="panel-dailies" class="tab-panel"></div>
```

**Step 3:** Remove all `<script>` tags for old previz.js and canvas sub-files. Replace with new load order:

```html
<!-- Shared canvas infrastructure -->
<script src="/editors/tabs/canvas/state.js?v=VERSION"></script>
<script src="/editors/tabs/canvas/viewport.js?v=VERSION"></script>
<!-- Workspace builders -->
<script src="/editors/tabs/canvas/previz.js?v=VERSION"></script>
<script src="/editors/tabs/canvas/production.js?v=VERSION"></script>
<!-- Tab orchestrator (registers both previz + render tabs) -->
<script src="/editors/tabs/canvas/main.js?v=VERSION"></script>
```

Remove the old `<script src="/editors/tabs/previz.js">` line entirely.
Remove the old `<script src="/editors/tabs/canvas/storyboard.js">` line entirely.

**Step 4:** Update `validTabs` in the inline init script and the keyboard shortcut map in `console_app.js`.

---

## Task 2: Modify CanvasState — Remove Storyboard Mode

**File:** `editors/tabs/canvas/state.js`

**Step 1:** Remove 'storyboard' from workspaceMode. The mode is now determined by which tab is active, not by a sub-toggle. Change default from `'storyboard'` to `'previz'`.

```javascript
workspaceMode: 'previz', // 'previz' | 'production' — set by active tab
```

**Step 2:** Remove storyboard scroll position:
```javascript
scrollPositions: {
  previz: 0,
  production: 0
}
```

---

## Task 3: Modify main.js — Register Two Tabs

**File:** `editors/tabs/canvas/main.js`

This is the biggest change. The orchestrator needs to register as two separate tabs and manage two separate panel DOMs.

**Step 1:** Track which panel belongs to which tab. Add panel references:

```javascript
let previzPanel = null;
let renderPanel = null;
let activeCanvasTab = null; // 'previz' or 'render'
```

**Step 2:** Create a shared `initPanel(panelEl, mode)` function that builds the 3-column layout in the given panel:

```javascript
function initPanel(panelEl, mode) {
  panelEl.innerHTML = `
    <div class="cv-layout">
      <div id="${mode}-shot-list" class="cv-shot-list"></div>
      <div id="${mode}-workspace-content" class="cv-workspace-content">
        <div class="cv-workspace-body" data-mode="${mode}">
          <div class="cv-storyboard-empty">SELECT AN EPISODE</div>
        </div>
      </div>
      <div id="${mode}-viewport" class="cv-viewport">
        <div class="cv-vp-empty">
          <div class="cv-vp-empty-icon">&#9655;</div>
          <div class="cv-vp-empty-text">SELECT A FRAME</div>
        </div>
      </div>
    </div>
    <div id="${mode}-status-bar" class="cv-status-bar">
      <span class="cv-status-mode cv-mode-command">COMMAND</span>
      <span class="cv-status-context">${mode.toUpperCase()}</span>
      <span class="cv-status-cost"></span>
    </div>`;
}
```

**Step 3:** Remove the workspace sub-tab toggle from `renderWorkspace()`. The workspace body just renders based on `activeCanvasTab`:

- If `activeCanvasTab === 'previz'` → `CanvasPreviz.buildMode(shot)`
- If `activeCanvasTab === 'render'` → `CanvasProduction.buildMode(shot)`

Remove the `<div class="cv-workspace-tabs">` with STORYBOARD/PREVIZ/RENDER buttons entirely.

**Step 4:** Update `renderShotList()`, `renderWorkspace()`, `renderViewport()`, `updateStatusBar()` to target the active panel's DOM elements using the `activeCanvasTab` prefix:

```javascript
function _el(suffix) {
  return document.getElementById(`${activeCanvasTab}-${suffix}`);
}
// Then use: _el('shot-list'), _el('workspace-content'), _el('viewport'), _el('status-bar')
```

**Step 5:** Update `selectShot()` — remove the auto-routing from storyboard to previz/production. Just select the shot; the workspace mode is determined by which tab you're on.

**Step 6:** Remove `switchMode()` function and all references to mode switching (keyboard shortcuts 1/2/3 for storyboard/previz/production).

**Step 7:** Update `_setupEventDelegation()` — need to set up listeners on BOTH panels. The click/input/mouseover handlers need to work on whichever panel is active.

**Step 8:** Register two tabs at the bottom:

```javascript
ConsoleApp.registerTab('previz', {
  init(panelEl) {
    previzPanel = panelEl;
    initPanel(panelEl, 'previz');
    _setupEventDelegation(panelEl, 'previz');
  },
  activate() {
    activeCanvasTab = 'previz';
    CanvasState.data.workspaceMode = 'previz';
    fetchData();
    startPolling();
  },
  deactivate() {
    if (activeCanvasTab === 'previz') stopPolling();
  }
});

ConsoleApp.registerTab('render', {
  init(panelEl) {
    renderPanel = panelEl;
    initPanel(panelEl, 'render');
    _setupEventDelegation(panelEl, 'render');
  },
  activate() {
    activeCanvasTab = 'render';
    CanvasState.data.workspaceMode = 'production';
    fetchData();
    startPolling();
  },
  deactivate() {
    if (activeCanvasTab === 'render') stopPolling();
  }
});
```

Remove the old `ConsoleApp.registerTab('canvas', ...)` registration.

**Step 9:** Update keyboard shortcut map in `_handleKeyboard()`:
- Remove `case '1':` (storyboard), `case '2':` (previz), `case '3':` (production) — mode switching is gone
- Keep j/k/g/r/a/p/h shortcuts — they work regardless of which tab
- The keyboard handler should check for both 'previz' and 'render' active tabs

**Step 10:** Update the `_handleWorkspaceAction` function — remove `case 'switch-mode':` action handler.

---

## Task 4: Update console_app.js — Keyboard Shortcuts + Valid Tabs

**File:** `editors/console_app.js`

**Step 1:** Update the Cmd+1-5 tab map:
```javascript
const tabMap = { '1': 'script', '2': 'board', '3': 'previz', '4': 'render', '5': 'dailies' };
```

**Step 2:** Update `validTabs` array in `init()`:
```javascript
const validTabs = ['script', 'board', 'previz', 'render', 'dailies'];
```

---

## Task 5: Move Storyboard Grid into Board

**File:** `editors/tabs/board.js`

**Step 1:** Add a view toggle to the Board tab — LIST view (existing) vs GRID view (storyboard). Add a toggle button in the board header.

**Step 2:** Port the storyboard grid rendering from `canvas/storyboard.js` into board.js. The grid shows 9:16 shot cards with thumbnails and status tags. Clicking a card navigates to the Previz tab for that shot.

The grid rendering is only 68 lines (CanvasStoryboard.buildMode). Inline it into board.js.

**Step 3:** Wire the grid card click to navigate to Previz tab:
```javascript
// On card click:
ConsoleApp.selectEpisode(ep); // if needed
ConsoleApp.activateTab('previz');
// After previz tab loads, select the shot
```

---

## Task 6: Delete Legacy Files

**Step 1:** Delete `editors/tabs/previz.js` (1,919 lines — the old strangler fig)
**Step 2:** Delete `editors/tabs/canvas/storyboard.js` (68 lines — moved to board)

---

## Task 7: CSS Cleanup

**File:** `editors/styles/canvas.css`

**Step 1:** Remove `.cv-mode-storyboard` layout class and related storyboard-specific styles.

**Step 2:** Remove `.cv-workspace-tabs` styles (the sub-tab toggle bar).

**Step 3:** Keep all `.cv-sb-*` styles (storyboard grid) — they're now used by Board.

---

## Task 8: Update Version Cache Busters

**File:** `editors/production-console.html`

Bump all `?v=` strings to `v=20260308d`.

---

## Validation Checklist

1. Hard refresh console — 5 tabs visible: Script, Board, Previz, Render, Dailies
2. Cmd+1 through Cmd+5 switch tabs correctly
3. Select EP 001, click a shot in Previz tab — shot list, workspace (take gallery), viewport all render
4. Switch to Render tab — same shot stays selected, render workspace shows (filmstrip, anchor position, model selector)
5. Generate previz from Previz tab — task monitor tracks it, completion updates both tabs
6. Navigate j/k in both tabs — shared shot selection
7. Board tab — verify grid view toggle works, cards show thumbnails
8. Click board grid card — navigates to Previz tab with that shot selected
9. Hash navigation works: `#previz`, `#render`, `#board`
10. Browser back/forward navigates tabs correctly
