Manual search buckets and attribute chips #79

Merged
naps62-yolo merged 2 commits from issue/31-search-buckets into main 2026-08-22 22:42:51 +01:00
5 changed files with 991 additions and 14 deletions
+21 -8
View File
@@ -2,13 +2,13 @@
version: 1
slug: "web-src-main-ts"
primary_target: "web/src/main.ts"
related_targets: ["web/index.html","web/src/search.ts","web/src/style.css"]
related_targets: ["web/index.html","web/src/search.ts","web/src/releases.ts","web/src/style.css"]
---
# Surface: unified search (web/src/main.ts, §9.2)
# Surface: unified search + release deck (web/src/main.ts, §9.2 + §9.3)
Mode: Operate. The operator finds or adds a title without knowing which of
the two they are doing.
the two they are doing, and picks a release from decisions, not name dumps.
- Audience: the household operator; desktop mostly, phone sometimes.
- Task: one rail-mounted command input. Typing swaps the chain board for the
@@ -17,10 +17,23 @@ the two they are doing.
engraved micro-label headings, machined rows, chips on the right.
- Add flow: inline panel under a TMDB row — root radio cards (audience name,
policy name, path), main pre-selected, one confirm. Never a separate page.
- Release deck (§9.3, issue #31): a library row opens the buckets view.
ELIGIBLE leads with fixed-width attribute chips in aligned mono columns
(rem-width `.cw-*` classes shared by chips and the column header, so the
pseudo-table survives flex wrapping); WAIVED and REJECTED collapse to
counts behind cyan show/hide toggles. Release name is a secondary
truncated line, full string plus indexer/date/bytes on row expand. Every
waived/rejected row carries a verdict chip naming the rule. Grab is its
own control per row; on a waived row it is "waive + grab" and writes the
per-title override (rule→override mapping in releases.ts — bookkeeping,
never policy; verdicts always come from the API). Esc steps back one
layer: deck → search results → board.
- Manual intake: magnet / .torrent input routes to a MANUAL GRAB panel showing
parsed display name and btih; grab wiring lands with the release buckets
(issue #31/#22), and the panel says so honestly.
parsed display name and btih; magnet grab wiring is issue #22, and the
panel says so honestly.
- Constraints: 250 ms debounce, AbortController cancellation, token-gated CSS,
cyan for interaction only, dead-air rule (no idle animation).
- Unresolved: library rows are informational until the library view (#32)
gives them a destination; TMDB search is movie-only until series land (#39).
cyan for interaction only, dead-air rule (no idle animation), no horizontal
scroll at any viewport (§9.3 acceptance criterion).
- Unresolved: releases land in the persisted store only once the daemon
consumes search commands (#68-adjacent); TMDB search is movie-only until
series land (#39).
+87
View File
@@ -35,6 +35,14 @@
a pasted magnet or .torrent routes to a manual-intake panel. There is
no separate add page, ever. Esc returns to the board; "/" focuses the
box from anywhere.
BUCKETS (§9.3, issue #31): a library row opens the release deck — the
policy engine's verdicts, inverted from Radarr: ELIGIBLE rows lead with
fixed-width attribute chips (score res source hdr audio size seed) in
aligned mono columns; WAIVED and REJECTED collapse to counts. The
release name is secondary, truncated, full on expand. Every rejected
row names its killing rule; one click on a waived row writes the
override and grabs. No horizontal scroll at any viewport. Esc returns
to the search deck.
-->
<header class="rail">
<div class="rail-id">
@@ -87,6 +95,85 @@
</section>
</main>
<main class="deck releases" id="releases" hidden>
<header class="releases-head">
<button type="button" class="control" id="releases-back">back</button>
<div class="releases-id">
<h2 class="releases-title" id="releases-title">—</h2>
<span class="releases-year readout dim" id="releases-year">—</span>
</div>
<button type="button" class="control" id="releases-sweep">search indexers</button>
</header>
<p class="deck-status readout" id="releases-status" role="status" hidden></p>
<section class="deck-group" id="bucket-eligible" hidden aria-labelledby="label-eligible">
<header class="deck-head">
<h3 class="deck-label" id="label-eligible">eligible</h3>
<span class="deck-count readout" id="count-eligible"></span>
</header>
<div class="colhead" aria-hidden="true">
<span class="cw cw-score">score</span>
<span class="cw cw-res">res</span>
<span class="cw cw-src">source</span>
<span class="cw cw-hdr">hdr</span>
<span class="cw cw-aud">audio</span>
<span class="cw cw-size">size</span>
<span class="cw cw-seed">seed</span>
</div>
<ul class="deck-rows" id="rows-eligible"></ul>
</section>
<section class="deck-group" id="bucket-waived" hidden aria-labelledby="label-waived">
<header class="deck-head bucket-head">
<h3 class="deck-label" id="label-waived">waived</h3>
<button
type="button"
class="bucket-toggle readout"
id="toggle-waived"
aria-expanded="false"
aria-controls="wrap-waived"
></button>
</header>
<div id="wrap-waived" hidden>
<div class="colhead" aria-hidden="true">
<span class="cw cw-score">score</span>
<span class="cw cw-res">res</span>
<span class="cw cw-src">source</span>
<span class="cw cw-hdr">hdr</span>
<span class="cw cw-aud">audio</span>
<span class="cw cw-size">size</span>
<span class="cw cw-seed">seed</span>
</div>
<ul class="deck-rows" id="rows-waived"></ul>
</div>
</section>
<section class="deck-group" id="bucket-rejected" hidden aria-labelledby="label-rejected">
<header class="deck-head bucket-head">
<h3 class="deck-label" id="label-rejected">rejected</h3>
<button
type="button"
class="bucket-toggle readout"
id="toggle-rejected"
aria-expanded="false"
aria-controls="wrap-rejected"
></button>
</header>
<div id="wrap-rejected" hidden>
<div class="colhead" aria-hidden="true">
<span class="cw cw-score">score</span>
<span class="cw cw-res">res</span>
<span class="cw cw-src">source</span>
<span class="cw cw-hdr">hdr</span>
<span class="cw cw-aud">audio</span>
<span class="cw cw-size">size</span>
<span class="cw cw-seed">seed</span>
</div>
<ul class="deck-rows" id="rows-rejected"></ul>
</div>
</section>
</main>
<main class="board">
<section class="chain" aria-label="signal chain">
<article class="module area-tmdb" data-check="tmdb">
+400 -6
View File
@@ -1,4 +1,22 @@
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
import { type CheckStatus, type Probe, probeHealth } from "./health";
import {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucketOf,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
formatAudio,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
formatHdr,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
formatPublishDate,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
formatResolution,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
formatScore,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
formatSeeders,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
formatSize,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
formatSource,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
grabRelease,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
type MovieRelease,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
movieReleases,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
queueSearch,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
ruleLabel,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
waiveAndGrab,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
waiverOverride,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
} from "./releases";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
import {
addMovie,
type LibraryMovie,
@@ -165,7 +183,7 @@ function main() {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}, POLL_MS);
void probe();
searchMain(board);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
searchMain(board, releasesMain());
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
const DEBOUNCE_MS = 250;
@@ -181,7 +199,7 @@ interface DeckRefs {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
manualIntake: HTMLElement;
}
function searchMain(board: HTMLElement) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function searchMain(board: HTMLElement, releases: ReleasesView) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const input = must<HTMLInputElement>("#search");
const hint = must<HTMLElement>("#search-hint");
const refs: DeckRefs = {
@@ -222,11 +240,13 @@ function searchMain(board: HTMLElement) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function showBoard() {
controller?.abort();
controller = null;
releases.hide();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
refs.deck.hidden = true;
board.hidden = false;
}
function showDeck() {
releases.hide();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
board.hidden = true;
refs.deck.hidden = false;
}
@@ -290,7 +310,7 @@ function searchMain(board: HTMLElement) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
refs.groups.library.section.hidden = false;
refs.groups.library.count.textContent = String(response.library.length);
for (const movie of response.library) {
refs.groups.library.rows.append(libraryRow(movie, roots));
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
refs.groups.library.rows.append(libraryRow(movie, roots, releases.open));
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
}
if (response.tmdb.length > 0) {
@@ -403,9 +423,15 @@ function rowTitle(title: string, year: number | null): HTMLElement {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return wrap;
}
function libraryRow(movie: LibraryMovie, roots: Root[]): HTMLLIElement {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function libraryRow(
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
movie: LibraryMovie,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
roots: Root[],
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
open: (movie: LibraryMovie, origin: HTMLElement) => void,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
): HTMLLIElement {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const item = document.createElement("li");
item.className = "row";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const row = document.createElement("button");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
row.type = "button";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
row.className = "row row-tmdb";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const chips = document.createElement("span");
chips.className = "row-chips";
const root = roots.find((candidate) => candidate.id === movie.root_id);
@@ -421,7 +447,15 @@ function libraryRow(movie: LibraryMovie, roots: Root[]): HTMLLIElement {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (movie.blocked) {
chips.append(chip("blocked"));
}
item.append(rowTitle(movie.title, movie.year), chips);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const affordance = document.createElement("span");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
affordance.className = "row-add readout";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
affordance.textContent = "releases";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
chips.append(affordance);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
row.append(rowTitle(movie.title, movie.year), chips);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
row.addEventListener("click", () => {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
open(movie, row);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
});
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
item.append(row);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return item;
}
@@ -586,6 +620,366 @@ function addPanel(movie: TmdbMovie, roots: Root[], row: HTMLButtonElement): HTML
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return panel;
}
/* ---- release deck (§9.3, issue #31) ---------------------------------- */
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
interface ReleasesView {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
open: (movie: LibraryMovie, origin: HTMLElement) => void;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
hide: () => void;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
interface BucketRefs {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
section: HTMLElement;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
rows: HTMLUListElement;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function releasesMain(): ReleasesView {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const view = must<HTMLElement>("#releases");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const deck = must<HTMLElement>("#deck");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const back = must<HTMLButtonElement>("#releases-back");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const title = must<HTMLElement>("#releases-title");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const year = must<HTMLElement>("#releases-year");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const sweep = must<HTMLButtonElement>("#releases-sweep");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const status = must<HTMLElement>("#releases-status");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const eligible: BucketRefs & { count: HTMLElement } = {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
section: must<HTMLElement>("#bucket-eligible"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
count: must<HTMLElement>("#count-eligible"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
rows: must<HTMLUListElement>("#rows-eligible"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
};
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const collapsed = {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
waived: {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
section: must<HTMLElement>("#bucket-waived"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
toggle: must<HTMLButtonElement>("#toggle-waived"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
wrap: must<HTMLElement>("#wrap-waived"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
rows: must<HTMLUListElement>("#rows-waived"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
},
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
rejected: {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
section: must<HTMLElement>("#bucket-rejected"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
toggle: must<HTMLButtonElement>("#toggle-rejected"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
wrap: must<HTMLElement>("#wrap-rejected"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
rows: must<HTMLUListElement>("#rows-rejected"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
},
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
} as const;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
let current: LibraryMovie | null = null;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
let origin: HTMLElement | null = null;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const actions: ReleaseActions = {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
reload: () => load(),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
notify: (text, tone) => setStatus(text, tone),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
};
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
// guards a stale fetch from painting over a newer view
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
let sequence = 0;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
let refetchTimer: number | undefined;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function setStatus(text: string | null, tone?: "fault") {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
status.hidden = text === null;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
status.textContent = text ?? "";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (tone) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
status.dataset.tone = tone;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
} else {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
delete status.dataset.tone;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function clearBuckets() {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
eligible.section.hidden = true;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
eligible.rows.replaceChildren();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
for (const bucket of [collapsed.waived, collapsed.rejected]) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucket.section.hidden = true;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucket.wrap.hidden = true;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucket.toggle.setAttribute("aria-expanded", "false");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucket.rows.replaceChildren();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function setToggle(bucket: (typeof collapsed)["waived"], count: number) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const open = !bucket.wrap.hidden;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucket.toggle.textContent = open ? `hide ${count}` : `show ${count}`;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucket.toggle.setAttribute("aria-expanded", String(open));
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
for (const bucket of [collapsed.waived, collapsed.rejected]) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucket.toggle.addEventListener("click", () => {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucket.wrap.hidden = !bucket.wrap.hidden;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
setToggle(bucket, bucket.rows.childElementCount);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
});
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function render(releases: MovieRelease[]) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const movie = current;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (!movie) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
clearBuckets();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (releases.length === 0) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
setStatus("no releases indexed for this title — search indexers runs a sweep now");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
setStatus(null);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
// the API pre-sorts by bucket then score; splitting preserves order
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const buckets = {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
eligible: releases.filter((release) => bucketOf(release) === "eligible"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
waived: releases.filter((release) => bucketOf(release) === "waived"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
rejected: releases.filter((release) => bucketOf(release) === "rejected"),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
};
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
eligible.section.hidden = false;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
eligible.count.textContent = String(buckets.eligible.length);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (buckets.eligible.length > 0) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
for (const release of buckets.eligible) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
eligible.rows.append(releaseRow(release, movie, "eligible", actions));
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
} else {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
// §9.3: over-strict filters must be visible, not silently absent
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const none = document.createElement("li");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
none.className = "rel rel-none readout dim";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
none.textContent = "none — every candidate was waived or rejected by policy";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
eligible.rows.append(none);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
for (const name of ["waived", "rejected"] as const) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const rows = buckets[name];
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (rows.length === 0) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
continue;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const bucket = collapsed[name];
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucket.section.hidden = false;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
for (const release of rows) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucket.rows.append(releaseRow(release, movie, name, actions));
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
setToggle(bucket, rows.length);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
async function load() {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const movie = current;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (!movie) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
sequence += 1;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const ticket = sequence;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
setStatus("reading releases…");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const outcome = await movieReleases(movie.id);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (ticket !== sequence || current !== movie) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (outcome.kind === "error") {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
clearBuckets();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
setStatus(`releases unavailable — ${outcome.detail}`, "fault");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
render(outcome.releases);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function open(movie: LibraryMovie, from: HTMLElement) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
current = movie;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
origin = from;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
title.textContent = movie.title;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
year.textContent = movie.year === null ? "—" : String(movie.year);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
deck.hidden = true;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
view.hidden = false;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
clearBuckets();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
sweep.disabled = false;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
back.focus();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
void load();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function hide() {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
view.hidden = true;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
current = null;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
sequence += 1;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
window.clearTimeout(refetchTimer);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function close() {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const target = origin;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
hide();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
deck.hidden = false;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
target?.focus();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
back.addEventListener("click", close);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
// capture + stopPropagation: one Escape steps back one layer, instead
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
// of falling through to the search deck's own Escape handler
naps62-yolo marked this conversation as resolved Outdated
Outdated
Review

Closing the release deck unhides #deck; the existing window Escape handler then receives this same event and immediately sends the user to the board. Stop propagation here, or make that handler ignore Escape while the release view is active.

Closing the release deck unhides `#deck`; the existing window Escape handler then receives this same event and immediately sends the user to the board. Stop propagation here, or make that handler ignore Escape while the release view is active. <!-- agent-meta: {"model":"gpt-5","session":"01a02b62"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
window.addEventListener(
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
"keydown",
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
(event) => {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (event.key === "Escape" && !view.hidden) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
event.stopPropagation();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
close();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
},
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
true,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
sweep.addEventListener("click", () => {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const movie = current;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (!movie) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
sweep.disabled = true;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
void queueSearch(movie.id).then((outcome) => {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (current !== movie) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
sweep.disabled = false;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (outcome.kind === "error") {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
setStatus(`search failed — ${outcome.detail}`, "fault");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
setStatus("search queued — indexers answer asynchronously, rereading shortly");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
window.clearTimeout(refetchTimer);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
refetchTimer = window.setTimeout(() => {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
void load();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}, 3000);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
});
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
});
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return { open, hide };
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
interface ReleaseActions {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
reload: () => Promise<void>;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
notify: (text: string, tone?: "fault") => void;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
/** One classified release: chips lead, the name is secondary (§9.3). */
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function releaseRow(
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
release: MovieRelease,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
movie: LibraryMovie,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucket: "eligible" | "waived" | "rejected",
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
actions: ReleaseActions,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
): HTMLLIElement {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const item = document.createElement("li");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
item.className = "rel";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const line = document.createElement("button");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
line.type = "button";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
line.className = "rel-line";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
line.setAttribute("aria-expanded", "false");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const columns: [string, string, string][] = [
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
["cw-score", "score", formatScore(release.score)],
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
["cw-res", "resolution", formatResolution(release.parsed)],
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
["cw-src", "source", formatSource(release.parsed)],
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
["cw-hdr", "hdr", formatHdr(release.parsed)],
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
["cw-aud", "audio", formatAudio(release.parsed)],
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
["cw-size", "size", formatSize(release.size)],
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
["cw-seed", "seeders", formatSeeders(release.seeders)],
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
];
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
for (const [width, label, value] of columns) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
line.append(
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
chip(value, (span) => {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
span.classList.add("cw", width);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
span.setAttribute("aria-label", value === "—" ? `${label} unclaimed` : `${label} ${value}`);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (value === "—") {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
span.classList.add("dim");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
// the world's non-colour eligible mark rides the leading chip
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (bucket === "eligible" && width === "cw-score") {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
span.dataset.verdict = "eligible";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (bucket !== "eligible") {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
line.append(
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
chip(`${bucket} · ${ruleLabel(release.rejected_rule)}`, (span) => {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
span.dataset.verdict = bucket;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const name = document.createElement("span");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
name.className = "rel-name readout";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
name.textContent = release.name;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
line.append(name);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
item.append(line);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const note = document.createElement("span");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
note.className = "rel-note readout";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
note.setAttribute("role", "status");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
note.hidden = true;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (bucket !== "rejected") {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const grab = document.createElement("button");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
grab.type = "button";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
grab.className = "control rel-grab";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const writesOverride = bucket === "waived" && waiverOverride(release.rejected_rule) !== null;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
grab.textContent = writesOverride ? "waive + grab" : "grab";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
grab.addEventListener("click", () => {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
grab.disabled = true;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
note.hidden = false;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
delete note.dataset.tone;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
note.textContent = "grabbing…";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const action =
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
bucket === "waived"
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
? waiveAndGrab(movie.id, release.id, release.rejected_rule)
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
: grabRelease(movie.id, release.id).then((outcome) =>
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
outcome.kind === "done"
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
? ({ kind: "done", overrideWritten: false } as const)
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
: ({ kind: "error", detail: outcome.detail, overrideWritten: false } as const),
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
void action.then((outcome) => {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const text =
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
outcome.kind === "error"
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
? `${outcome.overrideWritten ? "override written · " : ""}grab failed — ${outcome.detail}`
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
: `${outcome.overrideWritten ? "override written · " : ""}grab sent`;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (outcome.kind === "error") {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
grab.disabled = false;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
note.textContent = text;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
note.dataset.tone = "fault";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
} else {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
note.textContent = text;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (outcome.overrideWritten) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
// the override changed classification; reread the verdicts and
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
// keep the outcome visible past the re-render
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
void actions.reload().then(() => {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
actions.notify(text, outcome.kind === "error" ? "fault" : undefined);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
});
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
});
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
});
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
item.append(grab);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
item.append(note);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const full = document.createElement("div");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
full.className = "rel-full";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
full.hidden = true;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
line.addEventListener("click", () => {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (full.childElementCount === 0) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const raw = document.createElement("p");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
raw.className = "rel-raw readout";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
raw.textContent = release.name;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
full.append(raw);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const meta = document.createElement("p");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
meta.className = "rel-meta readout dim";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const published = formatPublishDate(release.publish_date);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
meta.textContent = [
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
`indexer ${release.indexer_id}`,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
published === null ? null : `published ${published}`,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
`${release.size} bytes`,
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
]
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
.filter((part) => part !== null)
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
.join(" · ");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
full.append(meta);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
if (bucket === "waived" && waiverOverride(release.rejected_rule) !== null) {
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
const waiver = document.createElement("p");
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
waiver.className = "rel-meta readout dim";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
waiver.textContent = "waive + grab writes this title's override, then grabs";
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
full.append(waiver);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
full.hidden = !full.hidden;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
line.setAttribute("aria-expanded", String(!full.hidden));
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
});
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
item.append(full);
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
return item;
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
}
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
function renderManual(intake: HTMLElement, kind: "magnet" | "torrent_url", raw: string) {
const parsed = parseManualInput(kind, raw);
intake.replaceChildren();
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
Review

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser.

Fixed in fb7fe49 — the release deck's Escape handler now runs in the capture phase and stops propagation, so one press steps releases → search deck → board one layer at a time. Verified with real key events in the browser. <!-- agent-meta: {"model":"claude-fable-5","session":"62e4c09a"} -->
+261
View File
@@ -0,0 +1,261 @@
// Hand-written mirror of arr-api's /api/movies/{id}/releases, grab and
// override schemas — same reasoning as search.ts: the generated client
// (src/api/) is uncommitted, so CI's tsc cannot see it.
export type Bucket = "eligible" | "waived" | "rejected";
/** What the release name claims (arr-parse `NameClaims`, §5.6). */
export interface ParsedClaims {
resolution?: string | null;
source?: string | null;
codec?: string | null;
hdr?: string[];
languages?: string[];
}
export interface MovieRelease {
id: number;
indexer_id: number;
guid: string;
name: string;
size: number;
seeders: number | null;
publish_date: string | null;
download_url: string;
parsed: ParsedClaims;
score: number | null;
verdict: string | null;
rejected_rule: string | null;
}
export type ReleasesOutcome =
| { kind: "results"; releases: MovieRelease[] }
| { kind: "error"; detail: string };
export async function movieReleases(movieId: number): Promise<ReleasesOutcome> {
try {
const response = await fetch(`/api/movies/${movieId}/releases`);
if (!response.ok) {
return { kind: "error", detail: await errorDetail(response) };
}
return { kind: "results", releases: (await response.json()) as MovieRelease[] };
} catch {
return { kind: "error", detail: "daemon unreachable" };
}
}
export type ActionOutcome = { kind: "done" } | { kind: "error"; detail: string };
/** §6.2 manual trigger: one targeted sweep, user-initiated. */
export async function queueSearch(movieId: number): Promise<ActionOutcome> {
try {
const response = await fetch(`/api/movies/${movieId}/search`, { method: "POST" });
if (!response.ok) {
return { kind: "error", detail: await errorDetail(response) };
}
return { kind: "done" };
} catch {
return { kind: "error", detail: "daemon unreachable" };
}
}
export async function grabRelease(movieId: number, releaseId: number): Promise<ActionOutcome> {
try {
const response = await fetch(`/api/movies/${movieId}/releases/${releaseId}/grab`, {
method: "POST",
});
if (!response.ok) {
return { kind: "error", detail: await errorDetail(response) };
}
return { kind: "done" };
} catch {
return { kind: "error", detail: "daemon unreachable" };
}
}
/**
* The per-title override one click on a waived row writes (§5.2, §9.3).
* Mapping a rule name to its override is bookkeeping, not policy — the
* verdict itself always comes from the API.
*/
export function waiverOverride(rule: string | null): Record<string, unknown> | null {
switch (rule) {
case "required_audio":
return { allow_english_audio: true };
case "resolution":
return { only_4k: false };
default:
return null;
}
}
export type WaiveOutcome =
| { kind: "done"; overrideWritten: boolean }
| { kind: "error"; detail: string; overrideWritten: boolean };
/** One click on a waived row: write the override, then grab (§9.3). */
export async function waiveAndGrab(
movieId: number,
releaseId: number,
rule: string | null,
): Promise<WaiveOutcome> {
const override = waiverOverride(rule);
let overrideWritten = false;
if (override) {
try {
const current = await fetch(`/api/movies/${movieId}`);
if (!current.ok) {
return { kind: "error", detail: await errorDetail(current), overrideWritten };
}
const movie = (await current.json()) as { overrides: Record<string, unknown> };
const patch = await fetch(`/api/movies/${movieId}`, {
method: "PATCH",
headers: { "content-type": "application/json" },
body: JSON.stringify({ overrides: { ...movie.overrides, ...override } }),
});
if (!patch.ok) {
return { kind: "error", detail: await errorDetail(patch), overrideWritten };
}
overrideWritten = true;
} catch {
return { kind: "error", detail: "daemon unreachable", overrideWritten };
}
}
const grabbed = await grabRelease(movieId, releaseId);
if (grabbed.kind === "error") {
return { kind: "error", detail: grabbed.detail, overrideWritten };
}
return { kind: "done", overrideWritten };
}
export function bucketOf(release: MovieRelease): Bucket {
if (release.verdict === "eligible") {
return "eligible";
}
if (release.verdict === "waived") {
return "waived";
}
return "rejected";
}
/* ---- chip formatting: parsed attributes to fixed-width mono values ---- */
const SOURCE_LABEL: Record<string, string> = {
Cam: "cam",
Telesync: "ts",
Telecine: "tc",
Screener: "scr",
Dvd: "dvd",
Hdtv: "hdtv",
WebRip: "webrip",
WebDl: "web-dl",
BluRay: "bluray",
Remux: "remux",
};
const HDR_LABEL: Record<string, string> = {
DolbyVision: "DV",
Hdr10Plus: "HDR10+",
Hdr10: "HDR10",
Hdr: "HDR",
Hlg: "HLG",
Sdr: "SDR",
};
const LANGUAGE_LABEL: Record<string, string> = {
PtBr: "pt-BR",
PtPt: "pt-PT",
Portuguese: "pt",
English: "en",
French: "fr",
German: "de",
Spanish: "es",
Italian: "it",
Multi: "multi",
Dual: "dual",
};
/** §5.7 rule names as short chip words. */
const RULE_LABEL: Record<string, string> = {
required_audio: "audio",
dub_blacklist: "dub",
portuguese_unverified: "pt unverified",
dolby_vision_profile: "dv profile",
resolution: "resolution",
source: "source",
size: "size",
};
export function formatScore(score: number | null): string {
return score === null ? "—" : String(Math.round(score));
}
export function formatResolution(parsed: ParsedClaims): string {
return parsed.resolution ?? "—";
}
export function formatSource(parsed: ParsedClaims): string {
if (!parsed.source) {
return "—";
}
return SOURCE_LABEL[parsed.source] ?? parsed.source.toLowerCase();
}
export function formatHdr(parsed: ParsedClaims): string {
const markers = parsed.hdr ?? [];
if (markers.length === 0) {
return "—";
}
return markers.map((marker) => HDR_LABEL[marker] ?? marker).join(" ");
}
export function formatAudio(parsed: ParsedClaims): string {
const markers = parsed.languages ?? [];
if (markers.length === 0) {
return "—";
}
return markers.map((marker) => LANGUAGE_LABEL[marker] ?? marker.toLowerCase()).join(" ");
}
export function formatSize(bytes: number): string {
if (bytes <= 0) {
return "—";
}
const gib = bytes / 2 ** 30;
if (gib >= 100) {
return `${Math.round(gib)}G`;
}
if (gib >= 1) {
return `${gib.toFixed(1)}G`;
}
return `${Math.round(bytes / 2 ** 20)}M`;
}
export function formatSeeders(seeders: number | null): string {
return seeders === null ? "—" : String(seeders);
}
export function ruleLabel(rule: string | null): string {
if (rule === null) {
return "unclassified";
}
return RULE_LABEL[rule] ?? rule.replaceAll("_", " ");
}
/** The publish date as a calendar day; the exact instant is noise here. */
export function formatPublishDate(date: string | null): string | null {
if (date === null) {
return null;
}
const day = date.slice(0, 10);
return /^\d{4}-\d{2}-\d{2}$/.test(day) ? day : date;
}
async function errorDetail(response: Response): Promise<string> {
try {
const body = (await response.json()) as { error?: string };
return body.error ?? `http ${response.status}`;
} catch {
return `http ${response.status}`;
}
}
+222
View File
@@ -629,6 +629,18 @@ body {
border-color: oklch(from var(--verdict-eligible) l c h / 45%);
}
/* the dashed border is the visible mark of a relaxed rule */
.chip[data-verdict="waived"] {
color: var(--verdict-waived);
border-style: dashed;
border-color: oklch(from var(--verdict-waived) l c h / 55%);
}
/* rejected is the policy working, never fault red */
.chip[data-verdict="rejected"] {
color: var(--verdict-rejected);
}
.chip[data-movie-state="imported"] {
color: var(--ink);
}
@@ -745,6 +757,201 @@ body {
color: var(--verdict-eligible);
}
/* ---- release deck (§9.3) ---------------------------------------------- */
.releases-head {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: var(--space-2) var(--space-3);
margin: 0 0 var(--space-6);
}
.releases-id {
flex: 1;
min-width: 0;
display: flex;
align-items: baseline;
gap: var(--space-2);
}
.releases-title {
margin: 0;
font-family: var(--font-display);
font-size: var(--text-lg);
font-weight: 700;
letter-spacing: 0.04em;
line-height: 1.1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.releases-year {
font-size: var(--text-xs);
}
.bucket-head {
align-items: center;
}
.bucket-toggle {
margin-left: auto;
min-height: 2.75rem;
padding: 0 var(--space-2);
font-size: var(--text-xs);
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--accent);
background: none;
border: 0;
cursor: pointer;
transition: color 150ms var(--ease-out);
}
.bucket-toggle:hover {
color: var(--accent-bright);
}
/* fixed-width mono columns: chips and header labels share rem widths, so
the pseudo-table survives font-size differences and flex wrapping alike */
.cw {
display: inline-block;
flex: none;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
line-height: 1.25rem;
}
.cw-score {
width: 4.5rem;
text-align: right;
}
.cw-res {
width: 4rem;
}
.cw-src {
width: 4.5rem;
}
.cw-hdr {
width: 6rem;
}
.cw-aud {
width: 7.5rem;
}
.cw-size {
width: 4.5rem;
text-align: right;
}
.cw-seed {
width: 3.5rem;
text-align: right;
}
.colhead {
display: flex;
flex-wrap: wrap;
gap: var(--space-1);
padding: var(--space-2) var(--space-1) 0;
}
.colhead .cw {
padding: 0 var(--space-2);
border: 1px solid transparent;
font-family: var(--font-readout);
font-size: var(--text-2xs);
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--ink-faint);
}
.rel {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: var(--space-1) var(--space-2);
padding: var(--space-2) var(--space-1);
border-bottom: 1px solid oklch(from var(--line) l c h / 45%);
}
/* the whole line is the expand affordance; grab is its own control */
.rel-line {
flex: 1;
min-width: 0;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: var(--space-1);
padding: 0;
font: inherit;
text-align: left;
color: inherit;
background: none;
border: 0;
border-radius: var(--radius);
cursor: pointer;
transition: background 150ms var(--ease-out);
}
.rel-line:hover,
.rel-line:focus-visible {
background: var(--panel);
}
/* §9.3: the release name is secondary — evidence, not the primary key */
.rel-name {
flex-basis: 100%;
min-width: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: var(--text-xs);
color: var(--ink-faint);
}
.rel-none {
padding: var(--space-2) var(--space-1);
font-size: var(--text-xs);
border-bottom: 1px solid oklch(from var(--line) l c h / 45%);
}
.rel-note {
font-size: var(--text-xs);
color: var(--ink-muted);
}
.rel-note[data-tone="fault"] {
color: var(--signal-fault);
}
.rel-full {
flex-basis: 100%;
padding: var(--space-2) var(--space-3);
background: var(--panel);
border: 1px solid var(--line);
border-radius: var(--radius);
box-shadow: inset 0 1px var(--highlight);
}
.rel-raw {
margin: 0;
overflow-wrap: anywhere;
font-size: var(--text-xs);
color: var(--ink);
}
.rel-meta {
margin: var(--space-1) 0 0;
font-size: var(--text-2xs);
}
/* ---- manual intake ---------------------------------------------------- */
.intake .module-detail {
@@ -779,6 +986,21 @@ body {
flex-basis: 100%;
}
.releases-id {
order: -1;
flex-basis: 100%;
}
/* the row and the column header must wrap at the same width, so the
grab control drops below the line instead of narrowing it */
.rel-line {
flex-basis: 100%;
}
.rel-grab {
margin-left: auto;
}
.board {
padding: var(--space-6) var(--space-4);
}