# src/shell/panel — the docked bank-panel shell + the shared LICE draw kit

## Scope

The REAPER-facing shell for the docked bank panel: the eight `bank_panel` split TUs
(`panel_window` / `panel_layout` / `panel_render` / `panel_input` / `panel_drag` /
`panel_thumbnails` / `panel_audition` / `panel_bank_ops`, sharing state via
`panel_state.h`), plus `draw_kit`, the shared LICE draw shell also consumed by the
VST3 editor (`shell/instrument/`).

Pure layout/hit-test/palette modules the panel draws through (`theme`,
`component_geometry`, `bank_grid`, `tab_strip`, `mode_switch`, `action_bar`,
`footer_bar`, `overflow_menu`, `prune_button`, `mode_enable`, `tooltip`, `card_drag`,
`card_meta`) live in `core/ui` / `core/model` and are documented there — this
directory consumes them but does not own them. The promptless bank-mutation verbs
(`bankOpCreate`/`Rename`/`Delete`/… + `persistBankOp`) that `panel_bank_ops` skins
live in `shell/bank_ops`, a sibling directory, not here.

## Invariants

- **Draw through the kit, by palette ROLE, not hardcoded hue.** The shared LICE-based
  drawing kit is the one source of drawing for the whole system — a button, row,
  slider, or waveform looks identical in the bank panel, the embed strip, and the VST
  editor because it is the same kit function, drawn against palette roles (`bg/base`,
  `bg/panel`, `bg/cell`, `accent/primary`, `accent/secondary`, `accent/tertiary`,
  `accent/hot`, `text/primary`, `text/dim`, `line/hairline`, `warn`) rather than a
  literal color. The kit palette stays abstract (role→color, one constants block), so
  a whole visual direction is a single-file change (Phase L, DS-1/DS-2).
- **Dock-panel layout is a thorough redesign, not a light re-skin (DS-3).** The panel
  lays out the full button/affordance inventory intuitively and uncluttered, then
  applies the kit — but this does **not** restructure the panel bones: the
  vertical-split / grid / tab structure is sound and stays as-is; a redesign designs
  the layout of the button inventory *around* it, not through it.
- **What Phase L does not change (Precision / invariant implications):**
  - The pure/shell split holds — all layout/hit-test stays in pure CTest-covered
    geometry modules; the kit's *draw* half is shell, its *geometry* half is pure,
    even where a WDL piece is reused. No hit-test math moves into untestable code.
  - RT discipline is untouched — the kit is draw-thread only; nothing here touches
    `process` or any off-thread reload handoff (a VST3-instrument concern).
  - Read-only-over-bank is untouched — this is look-and-feel; no data-ownership
    change.
  - The capture/placement load-bearing principle is untouched — Phase L draws; it
    does not capture, place, or mutate the bank.
  - VST3 class UID / component-state contract is unchanged.
  - Windows-only (D5) — font/GDI/HFONT choices assume Windows; no cross-platform
    font-fallback concern.

## Modules

- `bank_panel` (`shell/panel/`: `panel_window` / `panel_layout` / `panel_render` / `panel_input` / `panel_drag` / `panel_thumbnails` / `panel_audition` / `panel_bank_ops`, sharing state via `panel_state.h` — Q-W2 split of the former god-module into eight TUs) — docked LICE-drawn grid with three-zone layout: top toolbar (Capture → Maintenance → Placement via `action_bar`, short labels, More (⋯) overflow menu via `overflow_menu`), bottom toolbar (four opposite-mode tag buttons + Show Both), and footer (`[Arrange|Design]` toggle, Tail button, Prune via `footer_bar`). Grid renders in sparse slot order with gap cells, drop dispatch, metadata overlay, and selection via `accent/tertiary` purple border. Draws through the L1 kit by palette role; OS drag-out via `drag_out` + `drag_out_win`. `panel_window` owns the SWELL dialog lifecycle + dialog proc + drop-target opt-in; `panel_layout` the toolbar/footer/menu rects + vertical-split geometry (the one geometry source both paint and hit-test read); `panel_render` the WM_PAINT draw; `panel_input` click/wheel/keyboard routing + the new-content auto-tag timer; `panel_drag` the hover + card-drag state machine + drop dispatch; `panel_thumbnails` the PCM→envelope thumbnail cache + the bank-change fingerprint pass; `panel_audition` the preview-playback engine; `panel_bank_ops` the menu/prompt UX skin over the promptless `shell/bank_ops` verbs. `draw_kit` (shared with the VST3 editor) stays a separate TU.
  - `panel_window` — SWELL dialog lifecycle + dialog proc + drop-target opt-in. The drop splits by extension: a `.rsbank` is a whole bank and routes to the package-import action (one NEW bank each), everything else keeps the audio-ingest route.
  - `panel_layout` — toolbar/footer/menu rects + vertical-split geometry (the one geometry source both paint and hit-test read).
  - `panel_render` — the WM_PAINT draw.
  - `panel_input` — click/wheel/keyboard routing + the new-content auto-tag timer.
  - `panel_drag` — the hover + card-drag state machine + drop dispatch.
  - `panel_thumbnails` — the PCM→envelope thumbnail cache + the bank-change fingerprint pass.
  - `panel_audition` — the preview-playback engine.
  - `panel_bank_ops` — the menu/prompt UX skin over the promptless `shell/bank_ops` verbs.
- `draw_kit` — shared LICE draw shell: `fillSurface`, `drawButton`/`drawSlider`/`drawListRow`/`drawWaveform`, cached-font `text()`, full interaction-state model, double-buffer preserved. Consumes `theme` + `component_geometry`. Its antialiasing contract — which surfaces alias, which cannot, and the LICE primitive each answers with — is the disposition table in `docs/product/visual-design-language.md` §8, which governs `drawWaveform` as much as this doc does. `drawWaveform`'s per-column vertical arithmetic is NOT here: it is the pure, unit-tested `component_geometry::waveformBand`/`waveformColumnSpan` pair, because this TU is DAW-verified and not unit-tested.

## Gotchas

- **No external UI framework.** iPlug2 / JUCE / VSTGUI are rejected (DS-1). LICE +
  reused WDL pieces are the toolkit; reject any path that pulls in a new framework.
- **No hit-test geometry in untestable shell code.** Even when reusing a WDL piece
  (e.g. a `vwnd` control for a long scroll list), layout/hit-test math stays in pure
  CTest-covered modules — do not import a WDL control's retained-mode object model
  wholesale, since its controls own their hit-test internally and that would move
  geometry into untestable shell code.
- Verify every LICE/WDL/SWELL API name/signature against `vendor/WDL` before use.
