@namespace DeepDrftPublic.Client.Controls @* Invariant trio shared by every medium's detail page: a back link, a masthead (title + artist), a play/share affordance row wired to the streaming player, and slots for the medium-specific hero visual and metadata block. The Cut/Session/Mix detail pages all compose this; per-medium variance rides the Hero and MetaContent render fragments. *@ @* Ambient environment layer (Phase 12 §3c/§3f mode B): an optional full-bleed layer rendered BEHIND the scaffold content. The visualizer mounted here positions itself fixed/inset:0 (its own CSS), so this slot's only job is to render it before the content and put the content into a foreground stacking context above it. Absent slot = no ambient layer and no foreground promotion → today's plain background, byte-for-byte (Liskov). *@ @if (Ambient is not null) { @Ambient }
@* Two-end top row: back link (left) | optional action (right), on one SpaceBetween row. The action slot stays null for media that don't supply it (Track/Cut/Session), so SpaceBetween collapses to the back link alone at the left edge. The Mix detail page fills the action with its lava-lamp toggle and renders its knob band below via TopContent. *@
← @BackLabel @TopContent @TopRightAction
@* The header region. A composer that wants the default masthead+play row supplies nothing; one that needs a different arrangement (e.g. the Cut album's left-meta / right-cover split) supplies its own Header fragment. Layout variance rides this slot, never a boolean flag (Phase 9 §5.3). ShowHeader (a gate, not a layout flag) suppresses the region entirely for composers that carry title/artist/play elsewhere — Mix overlays them on its hero. *@ @if (ShowHeader) { @if (Header is not null) { @Header } else {
@Title @Artist
@* Play only makes sense once a playable track is resolved. *@ @if (Track is not null) { }
} } @Hero @if (MetaContent is not null && ShowMeta) {
@MetaContent
} @* Multi-track body region (the Cut album's track list). Single-track media leave it null. *@ @BodyContent @* The default share row is bound to the single resolved track. A composer that owns its own share affordance (the Cut header carries Play + Share inline) suppresses it via ShowShareRow. *@ @if (Track is not null && ShowShareRow) {
}