30 KiB
Phase 9 — Wave 8: Remediation
Status: spec (CMS + public tracks) / design-pending-interview (Mix Visualizer, 8.K). Author: product-designer. Date: 2026-06-13. Plan only — no code edits made by this doc.
Cross-references: PLAN.md §9.8 (the concise Wave 8 entry), COMPLETED.md §9.1–9.7
(the landed Phase 9 waves this remediates), product-notes/phase-9-release-medium-types.md
(the originating design — §3 CMS surface, §5 public surface), product-notes/phase-9-mix-visualizer-redesign.md
(the 8.K interview question set), memory One source, multiple views.
0. What this wave is, and what it is not
Daniel tested the landed Phase 9 surface (Waves 1–7, all on dev) and produced a punch-list. This
wave is the gap between what the specs built and what hands-on use wants. It is remediation, not
new feature work — every item corrects or reshapes a surface that already exists.
Three clusters:
- CMS Release Archive (8.A–8.E) — the card-grid landing is the wrong shape. Daniel wants the
medium varieties as tab modes that swap the grid in place, with an
ALLtab on the left, and working edit + add affordances in every mode. The currentReleaseArchiveBrowser(three cards that navigate to separate/tracks/sessions,/tracks/mixespages) is retired. - CMS upload/label polish (8.F–8.G) — compose the Session hero image into the upload form (retire the two-step), and rename "Album Name" → "Release Name."
- Public site (8.H–8.J) — the three-card
/archiveoverview is dead weight; the searchable all-releases view should be the archive. Slim the nav, drop GENRES, fix the stuck-open popover.
Not in this wave: the Mix Visualizer redesign (8.K). Daniel has explicitly asked to be
interviewed before it is designed. It is carried as [design pending interview] with a structured
question set in phase-9-mix-visualizer-redesign.md. No implementation spec exists or should be
authored until the interview runs.
1. Verified current state (read against live source 2026-06-13)
CMS:
TrackList.razor(/tracks) has aMudToggleGroupwith three items: Tracks, Releases (BrowseMode.Albums), Release Archive (BrowseMode.Archive). Routes/tracks,/tracks/albums,/tracks/archive,/tracks/genresall resolve here; Genres has no toggle item but is reachable by URL.BrowseMode.ArchiverendersReleaseArchiveBrowser.razor— aMudGridof three navigate-away cards (Cut →/tracks/albums, Session →/tracks/sessions, Mix →/tracks/mixes), driven offEnum.GetValues<ReleaseMedium>()+ aMediumCardslookup. The cards leave the page entirely.BrowseMode.AlbumsrendersCmsAlbumBrowser— the cross-medium releases grid with a Type column rendering<MudChip>@context.Release.ReleaseType</MudChip>unconditionally, plus a working batch-edit button (/tracks/album/{title}/edit). This grid shows all releases regardless of medium (CUTS, SESSIONS, MIXES together), and the Type chip always shows the Cut-onlyReleaseType(Single/EP/Album) — wrong for Session/Mix rows.CmsSessionBrowser(/tracks/sessions) andCmsMixBrowser(/tracks/mixes) are standalone routable pages inheritingCmsMediumBrowserBase, each with a "Back to Release Archive" button and a per-row Edit button (added in §9.5.E). They are not embedded inTrackList; they are navigated to.CmsTrackGrid(theTracksmode) has an Add Track button (Href="/tracks/upload") gated onShowAddButton. The album/archive modes have no add button.SessionFields.razor(shown in the upload form forMedium == Session) is only aMudAlert: "After upload, set the hero image from the Release Archive → Sessions browser." No hero upload input — the hero is set afterward, per-row, inCmsSessionBrowser. This is the two-step Daniel wants collapsed.AlbumHeaderFields.razorlabels the first field "Album Name" (Label="Album Name",RequiredError="Album Name is required").- Hero-image endpoint is resource-addressed:
POST api/release/{id}/session/hero-image— it needs a release id, which does not exist until the release is created. This is whySessionFieldspunts to a post-upload step. Composing it into the form means deferring the hero upload to after the create call returns an id, within the same submit handler (see 8.F note).
Public site:
ArchiveView.razor(/archive) is the three-card overview (Cuts / Sessions / Mixes), each an<a href>to the medium view.TracksView.razor(/tracks) is the flat track gallery — search field, album/genre filter pills, grid/list of tracks (track-cardinal). Title: "DeepDrft Track Gallery."AlbumsView.razor(/cuts) is the release-cardinal Cuts gallery (album cards).Pages.csMenuPages: ARCHIVE (route/archive, children Cuts/Sessions/Mixes) + Tracks (/tracks) + Genres (/genres).DeepDrftMenu.razordesktop renders ARCHIVE as a dual-role node: parent<a href="/archive">plus a pure-CSS hover dropdown (.dd-nav-dropdown, shown via:hover/:focus-withininDeepDrftMenu.razor.css). There is no JS dismissal — the dropdown hides only when the cursor leaves the parent region or focus moves out. On SPA navigation (Blazor enhanced nav keeps the DOM), the cursor often remains over the parent, so the dropdown stays visible: the "stuck open" bug (8.J).- All three medium views (
/cuts,/sessions,/mixes) and theReleaseClient/ReleaseProxyControllerread family exist and work.
2. CMS tracks — 8.A through 8.G
8.A — Release Archive as medium tabs, not navigate-away cards
Goal. Replace the Release Archive card grid with an in-page tab strip of medium modes that swap
the grid below in place, instead of navigating to separate pages. Add an ALL tab to the left of the
medium tabs. Retire the redundant top-level Releases toggle item — the ALL tab subsumes it.
User-visible change. Opening the Release Archive (or the CMS tracks page in its archive role) shows
a tab strip: ALL · CUTS · SESSIONS · MIXES. Selecting a tab swaps the grid below without leaving
the page. The old three-card "click to go to another page" interaction is gone, as is the separate
Releases toggle button (it is now the ALL tab).
Shape (informing, not prescribing — staff-engineer owns implementation).
- The cleanest structure folds the medium dimension into
TrackList's existing mode model. Today the top-level toggle isTracks / Releases / Release Archive. Daniel's ask collapses Releases and Release Archive into one release view with an inner medium tab strip (ALL / Cut / Session / Mix). Whether the medium tabs live as a second toggle group inside the Archive mode, or the whole top-level toggle is restructured, is an implementation call — the user-visible requirement is the four-tab strip swapping the grid in place. ReleaseArchiveBrowser(the card grid) is retired as the archive landing. The medium→display lookup it holds (label/descriptor) may survive as tab labels.- The standalone
/tracks/sessionsand/tracks/mixesroutes: keep them reachable (a hard 404 on a previously-working URL is hostile), but they are no longer the primary path — the tabs are. The "Back to Release Archive" buttons inCmsSessionBrowser/CmsMixBrowserlose their meaning if those browsers become embedded tab content; resolve their fate as part of 8.C.
Acceptance criteria.
- The Release Archive surface shows a tab strip with
ALL, plus one tab perReleaseMedium,ALLleft-most. (Tabs driven off the enum + a label lookup, not a hardcoded three-arm switch — preserve the Phase 9 extension discipline so a fourth medium surfaces a tab automatically.) - Selecting a tab swaps the grid below in place; no navigation to a separate page occurs.
- The top-level Releases toggle item is removed; its grid is reachable via the
ALLtab. - A fourth medium added to the enum surfaces a new tab with no markup change beyond one lookup entry.
Dependencies. Consumes the shared grid contract from 8.B (the ALL grid) and the per-medium
grids from 8.C. Land 8.B first (it defines the grid each tab renders), then 8.A wires the tab strip,
then 8.C/8.E layer the per-tab affordances. 8.A is the structural spine of the CMS cluster.
8.B — ALL tab: all-releases grid with working edit
Goal. The left-most ALL tab shows the current cross-medium releases grid (every release,
all media) with working edit buttons — the surface the retired Releases toggle showed.
User-visible change. The ALL tab presents the full releases list (CUTS, SESSIONS, MIXES together)
exactly as the current Releases grid does today, with an edit affordance per row.
Shape. This is essentially the current CmsAlbumBrowser grid (which already lists all releases and
already has a working batch-edit button) re-homed as the ALL tab's content. The main new work is
making it the default tab and ensuring the Type column behaves (that correctness fix is 8.D, which
this tab consumes). No new data path — CmsAlbumBrowser already loads the cross-medium release list.
Acceptance criteria.
- The
ALLtab lists every release regardless of medium. - Each row has a working Edit button routing to the release's edit page.
- The grid matches the behaviour of today's Releases toggle grid (no regression in sort, delete, expand-tracks).
Dependencies. Foundation for 8.A (the tab renders this grid). Independent of 8.C/8.D/8.E for build, though 8.D's Type-chip fix lands in this grid. Recommend: 8.B + 8.D land together (same grid), then 8.A wires tabs.
8.C — Per-medium tab grids gain working edit affordances
Goal. The Cut / Session / Mix tab grids each get an Edit action that routes intuitively to the correct edit page for that medium.
User-visible change. In each medium tab, every row has an Edit button. Clicking it opens the edit
form appropriate to that medium (Cut → batch/release edit with ReleaseType; Session/Mix → the
single-track edit with the medium-appropriate fields, no ReleaseType).
Shape. CmsSessionBrowser and CmsMixBrowser already have per-row Edit buttons (added §9.5.E)
routing to /tracks/album/{title}/edit (BatchEdit). The Cut tab reuses CmsAlbumBrowser's existing
edit button. The work here is (a) ensuring each tab's grid carries the edit action when embedded as tab
content rather than a standalone page, and (b) confirming the edit destination is the right one per
medium — BatchEdit already collapses to single-track for Session/Mix (§9.6.B), so the same route
works for all three; verify it presents correctly.
Acceptance criteria.
- Every row in the Cut, Session, and Mix tab grids has a working Edit button.
- Cut edit opens with
ReleaseTypevisible; Session/Mix edit opens single-track with noReleaseType(consistent with the landed §9.6.B collapse). - Edit from any medium tab loads the correct release and returns to a sensible place after save.
Dependencies. Depends on 8.A (the tabs must exist to host the grids). Parallel with 8.D and 8.E once 8.A lands.
8.D — Type column chip reads "Session" / "DJ Mix" for non-Cuts
Goal. The cross-medium grid's Type column must not show a Cut-only ReleaseType (Single/EP/
Album) chip for Session/Mix rows. For non-Cut media the chip reads the medium name — "Session" or
"DJ Mix".
User-visible change. In the ALL grid (and anywhere the cross-medium Type column appears), a Cut
row shows its release type (Single/EP/Album) as today; a Session row shows "Session"; a Mix row
shows "DJ Mix".
Shape. The Type cell currently renders @context.Release.ReleaseType unconditionally. Per the
Phase 9 read-model design, ReleaseDto.ReleaseType is nullable and nulled for non-Cut media at the
mapping point — so for Session/Mix the chip is rendering a default/empty or stale value. The cell
becomes medium-aware: when Medium == Cut, show ReleaseType; otherwise show the medium's display
name ("Session", "DJ Mix"). Drive the display-name from a medium→label lookup (the same extension
discipline — not an inline if session ... else if mix), so a future medium's label comes free. Note
Daniel's exact wording: "DJ Mix" for the Mix medium, not "Mix."
Acceptance criteria.
- A Cut row's Type chip shows Single/EP/Album as today.
- A Session row's Type chip shows "Session"; a Mix row's shows "DJ Mix".
- No row shows a Cut-only
ReleaseTypevalue for a non-Cut medium.
Dependencies. Independent — a self-contained cell-rendering fix. Lands naturally with 8.B (same grid). Can be built and tested before the tab restructure.
8.E — Add-Track buttons in all modes, medium-aware routing
Goal. An Add Track button appears in every CMS mode/tab, routing to the correct upload page pre-set to the selected tab's medium.
User-visible change. Whatever tab the admin is on (ALL, Cut, Session, Mix), an Add Track button is
present. Clicking it opens the upload page with the medium already set to that tab (a Session tab's Add
Track opens the upload form in Session mode; a Mix tab's opens it in Mix mode). On the ALL tab, Add
Track opens the upload page at its default (Cut) — or whatever Daniel prefers as the neutral default
(flag below).
Shape. CmsTrackGrid already has an Add Track button (Href="/tracks/upload"). The work is (a)
surfacing it in the release/archive modes too, and (b) carrying the medium to the upload page. The
upload page (TrackNew/BatchUpload) already has a MediumFields selector defaulting to Cut; the
cleanest route is a query param (e.g. /tracks/upload?medium=session) that pre-selects the medium on
load. This mirrors how /cuts-style routes carry a medium filter — a single query-param convention,
not a per-medium route fork.
Acceptance criteria.
- Add Track is present on every tab (
ALL, Cut, Session, Mix). - Add Track on a medium tab opens the upload form with that medium pre-selected.
- The pre-selected medium drives the conditional form fields immediately (Session shows the hero field
per 8.F; Cut shows
ReleaseType; etc.).
Dependencies. Depends on 8.A (tabs exist to host the buttons). Pairs with 8.F (a Session Add-Track that pre-selects Session should land the admin on a form that has the hero field).
Open question (minor, recommend a default). What medium does the ALL tab's Add Track default to?
Recommend Cut (the existing default and the most common case); the admin can switch the selector. Not
worth blocking.
8.F — Session hero image in the upload form (retire the two-step)
Goal. Author a Session — including its hero image — in a single upload pass. Remove the "set the hero image later from the Release Archive → Sessions browser" message; compose the polymorphic metadata fields so the Session form carries its hero-image input.
User-visible change. Uploading a Session no longer shows the "do it in two steps" alert. The Session
upload form has a hero-image file input alongside cover art; on submit, both the release and its hero
image are created in one flow. The post-upload per-row hero step in CmsSessionBrowser becomes a
correction path (replace/fix), not the required authoring path.
Shape (the ordering subtlety is the crux). The hero endpoint is resource-addressed —
POST api/release/{id}/session/hero-image needs a release id that does not exist until the release is
created. This is precisely why SessionFields punts today. Composing it into the form does not
require a new endpoint; it requires the submit handler to sequence:
- create the release via the existing upload path (returns the release id),
- then POST the held hero-image file to
…/{id}/session/hero-image, all within one user gesture. The hero file is selected in the form, held client-side, and uploaded after the create returns. This is the same deferred-upload patternAlbumHeaderFieldsalready uses for cover art ("Will upload on submit"). The hero input belongs inSessionFields(replacing the alert) or in theMediumFieldsdispatch — staff-engineer's call — but the user sees one form, one submit.
SessionFields.razor's current body (a MudAlert only) is replaced by a real hero-image input.
Acceptance criteria.
- The Session upload form presents a hero-image input (in addition to cover art).
- Submitting a Session with a chosen hero image creates the release and sets
HeroImageEntryKeyin one flow — no separate manual step required. - The "set hero from the browser later" alert is removed.
- The per-row hero upload in
CmsSessionBrowserstill works as a replace/correct path. - A Session uploaded with no hero image still succeeds (hero optional), and can have one set later via the browser (back-compat with the existing per-row path).
Dependencies. Independent of the tab restructure (8.A–8.E). Touches the upload form and the submit sequencing. Pairs naturally with 8.E (Session Add-Track should land on this improved form). Can be built in parallel with the tab work.
Open question (flag, recommend). Is the hero image required for a Session, or optional? Daniel's note says "the form should allow uploading all metadata including the hero image" — allow, not require. Recommend optional (consistent with cover art being optional, and with the existing per-row set-later path remaining valid). Confirm with Daniel; if required, the form gains a validation gate.
8.G — "Album Name" → "Release Name" label
Goal. The AlbumHeaderFields first-field label reads "Release Name", not "Album Name."
User-visible change. The upload/edit form's first field is labelled "Release Name" (and its required-error message matches). Since the field now covers Cuts, Sessions, and Mixes — not just albums — "Release Name" is the accurate noun.
Shape. Rename Label="Album Name" → Label="Release Name" and the RequiredError string in
AlbumHeaderFields.razor. Trivial. (Check whether any other surface labels the same field "Album" and
should follow for consistency — e.g. placeholder/help text — but the named change is the label.)
Acceptance criteria.
- The first field of the release header form reads "Release Name."
- The required-validation message references "Release Name."
Dependencies. Fully independent. Trivial. Can land any time.
3. Public site — 8.H through 8.J
8.H — Archive page becomes the searchable all-releases browser
Goal. Retarget /archive from the dead three-card overview to the searchable view of all
releases. The searchable all-releases browser is the archive.
User-visible change. Visiting /archive (or clicking ARCHIVE) lands on a searchable, filterable
browser of all releases — not three static cards. The cards are gone; the archive is the browse
surface.
Shape — and the framing tension that needs a decision. Daniel's note says the Archive should be "what the TRACKS page links to now — the searchable view of all releases," and that "naming everything TRACKS is misleading." There is a real cardinality mismatch to resolve:
- The current
/tracks(TracksView) is track-cardinal — it lists individual tracks with search and album/genre filter pills. It is the searchable view that exists today. - The medium browsers (
/cuts,/sessions,/mixes) are release-cardinal. - Daniel says "all releases" — which reads release-cardinal — but points at
TracksView, which is track-cardinal.
Two readings, and Daniel should pick:
- (H1) Archive = the existing track gallery, renamed. Move/retarget
TracksView's searchable gallery to/archive, drop the misleading "Tracks" naming, and treat the flat searchable list as the archive. Lowest effort — it is the view that exists, relabelled and re-homed. But it is track-cardinal, which sits oddly with "all releases" and with the release-cardinal medium views it sits beside. - (H2) Archive = a new searchable all-releases browser. Build a release-cardinal searchable
browser (search + medium/genre filter) at
/archive, consistent with the/cutsrelease-cardinal model and theapi/releaseread family. More work (a new browse surface), but coherent: the archive is releases, the medium tabs filter the archive, search filters within. This matches the CMS tab model (8.A) — the public archive and the CMS archive would share the "all releases, filter by medium, search within" mental model.
Recommendation: (H2) if the release is the unit Daniel thinks in; (H1) if speed matters most. The
CMS side (8.A) is moving to a release-cardinal, medium-filtered archive — symmetry argues for (H2) on
the public side too (One source, multiple views: the same browse model, CMS and public). But (H1) is
materially cheaper and may be all Daniel wants. This is a product decision — flag for Daniel before
building 8.H. Do not pick by default; the cardinality choice cascades into 8.I (what ARCHIVE links to)
and the fate of /tracks.
Acceptance criteria (conditional on the framing decision).
/archiverenders a searchable browse surface (search + filter), not the three-card overview.- The surface covers all releases (H2) or all tracks (H1) per the decision.
- The old three-card overview is retired (or repurposed — see 8.I, the mobile question).
- The misleading "Tracks"-as-everything naming is resolved (the route/label reflects "archive").
Dependencies. Gated on the framing decision above. Gates 8.I (8.I links ARCHIVE to whatever 8.H produces). Independent of 8.J.
Open question (carry-over from §5.1 of the medium-types spec). The original ARCHIVE design used
/archive as the mobile overview (three cards) since the desktop popover is hover-only. If /archive
becomes the searchable browser, what is the mobile ARCHIVE destination? Options: ARCHIVE on mobile
goes straight to the searchable browser (the three medium modes are reachable via in-page filter/tabs),
or the mobile hamburger keeps the three medium links indented under ARCHIVE (already does — see 8.I).
Recommend: mobile ARCHIVE → the searchable browser; the medium links live in the hamburger sub-list
(8.I) so the three-card overview is fully retired. Confirm with Daniel.
8.I — Nav slimmed: ARCHIVE + three medium modes inline, GENRES removed
Goal. Above the medium breakpoint the appbar carries ARCHIVE (→ all-releases browser) and the three medium modes (CUTS / SESSIONS / MIXES → their view pages) directly; GENRES is eliminated from the nav.
User-visible change. The desktop nav shows ARCHIVE plus the three medium links laid out across the appbar (Daniel: "The ARCHIVE popover items can fill the appbar above the medium breakpoint"). GENRES no longer appears in the nav. ARCHIVE links to the all-releases browser (8.H); each medium link goes to its view page.
Shape. Pages.cs MenuPages currently nests Cuts/Sessions/Mixes as Children of ARCHIVE (a hover
popover) and carries Tracks + Genres as siblings. Daniel's ask flattens this above the breakpoint: the
three medium items become top-level appbar links (not hidden in a popover), ARCHIVE is its own link to
the browser, and Genres is dropped. Below the breakpoint (mobile) the existing hamburger indented-child
pattern can keep the medium links under ARCHIVE.
Note this changes the popover model: if the three media are inline above the breakpoint, the desktop ARCHIVE popover may no longer be needed there at all — which also dissolves the 8.J stuck-open bug at the desktop breakpoint (though 8.J should still be fixed for any breakpoint where a popover survives, e.g. mobile or a narrow-desktop fallback). Coordinate 8.I and 8.J: 8.I may reduce where the popover exists, 8.J fixes the dismissal wherever it remains.
/genres route and GenresView — Daniel says eliminate GENRES from the nav. Recommend the same
posture Phase 9 took with CMS genre browse: drop the nav item, keep the route reachable (no active
development, no hard removal) unless Daniel says retire it wholesale. Flag.
Acceptance criteria.
- Above the medium breakpoint, ARCHIVE and CUTS / SESSIONS / MIXES appear as appbar links.
- ARCHIVE links to the all-releases browser (8.H's output).
- Each medium link navigates to its view page (
/cuts,/sessions,/mixes). - GENRES no longer appears in the nav.
- Below the breakpoint, the nav remains usable (medium links reachable via the hamburger).
Dependencies. Depends on 8.H (ARCHIVE's target). Coordinates with 8.J (popover fate).
Open question (flag). Eliminate GENRES from the nav only (keep /genres route reachable), or
retire GenresView entirely? Recommend nav-only removal (consistent with the CMS genre-browse
disposition; the route is built and harmless). Confirm with Daniel.
8.J — ARCHIVE popover click does not close (bug)
Goal. Clicking an item in the ARCHIVE popover closes the popover. Today it stays stuck open.
User-visible change. Clicking a popover child (Cuts/Sessions/Mixes) navigates and the dropdown dismisses, instead of remaining visible over the destination page.
Shape (root cause, verified). The desktop dropdown is pure CSS — .dd-nav-dropdown is shown by
.dd-nav-item-parent:hover / :focus-within in DeepDrftMenu.razor.css, with no JS dismissal.
Clicking a child is an <a href> SPA navigation (Blazor enhanced nav preserves the DOM), so after
navigation the cursor is often still over the parent region — :hover remains true — and the dropdown
stays visible. A pure-CSS hover dropdown has no "I was clicked, now dismiss" state.
Fix direction (informing, not prescribing): give the dropdown a dismissal trigger on child click — e.g.
blur the active element / move focus, or add a small interactivity hook that collapses the dropdown on
navigation, or restructure so a click toggles a closable state. The mobile menu already closes on click
(@onclick="CloseMobileMenu"); the desktop popover needs an equivalent. Note: if 8.I removes the
desktop popover (medium links inline above the breakpoint), this bug may only remain on whatever
breakpoint still shows a popover — fix it there. Confirm the surviving popover surfaces with 8.I before
implementing.
Acceptance criteria.
- Clicking a popover child navigates to the target and the dropdown is no longer visible afterward.
- Hover-to-open still works (no regression to the open behaviour).
- Keyboard focus dismissal still behaves (no trap).
Dependencies. Independent bug fix, but coordinate with 8.I (which may change where the popover exists). Can be specced and fixed independently; sequence after 8.I if 8.I reshapes the popover.
4. Mix Visualizer — 8.K [design pending interview]
Do not write an implementation spec for this track. Daniel has explicitly asked to be interviewed
before the Mix Visualizer is redesigned. His seed idea: the waveform scrolls bottom-to-top in high
resolution, with a slider controlling scroll speed / zoom level (higher resolution moves faster) —
not a static background image (which is what MixWaveformVisualizer renders today: a single static
full-viewport mirrored silhouette).
The structured interview question set is in product-notes/phase-9-mix-visualizer-redesign.md. It is
grounded in the current implementation (read 2026-06-13): an SVG silhouette built from a stored loudness
profile, full-page background, with an inert click-to-seek seam already present. The questions probe the
motion model, zoom/resolution coupling, aesthetics, interaction, and performance so the eventual design
is built on Daniel's actual intent, not a guess.
This track stays [design pending interview] until the interview runs and a design is captured. It
must not be dispatched for implementation from this document.
5. Dependency and parallelization summary
CMS cluster:
- 8.B (all-releases grid) + 8.D (Type chip fix) — land together (same grid), foundational.
- 8.A (tab strip) — consumes 8.B; the structural spine. Land after 8.B.
- 8.C (per-medium edit), 8.E (medium-aware Add Track) — layer onto 8.A; parallel with each other once 8.A lands.
- 8.F (Session hero in form), 8.G (label rename) — independent of the tab work; land in parallel any time. 8.F pairs with 8.E (Session Add-Track → hero-capable form).
Public cluster:
- 8.J (popover dismissal bug) — independent; can land immediately (but coordinate with 8.I if 8.I reshapes the popover).
- 8.H (archive = searchable browser) — gated on Daniel's cardinality decision (H1 vs H2).
- 8.I (nav slim + GENRES out) — depends on 8.H (ARCHIVE target); coordinates with 8.J.
Mix Visualizer:
- 8.K — blocked on the interview. Not implementable from this doc.
Recommended sequencing. Land the independent/trivial items first (8.G, 8.D, 8.J, 8.F) — they unblock nothing and need nothing. Then the CMS spine (8.B → 8.A → 8.C/8.E). On the public side, get Daniel's H1/ H2 decision, then 8.H → 8.I. Run the 8.K interview in parallel with all of it; it gates only itself.
6. Decisions needed from Daniel before / during build
- (8.H) Archive cardinality — H1 vs H2. Is the public archive the existing track gallery relabelled (H1, cheap), or a new release-cardinal searchable browser (H2, coherent with the CMS archive and the medium views)? This is the load-bearing product decision of the public cluster. Recommend H2 for model symmetry, H1 if speed dominates.
- (8.H) Mobile ARCHIVE destination. With
/archivebecoming the searchable browser, does mobile ARCHIVE go to the browser (recommended) or keep a card overview? Affects whether the three-card view is fully retired. - (8.I) GENRES — nav-only removal vs full retirement. Recommend nav-only (keep
/genresreachable). Confirm. - (8.F) Session hero image — optional vs required. Daniel's wording ("allow") reads optional. Recommend optional. Confirm.
- (8.E, minor)
ALL-tab Add Track default medium. Recommend Cut. Not blocking.
Items 1–4 are genuine product calls; 5 has a safe default and should not block.