diff --git a/DeepDrftPublic.Client/Controls/AddToQueueButton.razor b/DeepDrftPublic.Client/Controls/AddToQueueButton.razor
new file mode 100644
index 0000000..49de33b
--- /dev/null
+++ b/DeepDrftPublic.Client/Controls/AddToQueueButton.razor
@@ -0,0 +1,46 @@
+@namespace DeepDrftPublic.Client.Controls
+@using DeepDrftModels.DTOs
+@using DeepDrftPublic.Client.Services
+
+@* Append-only "Add to Queue" affordance placed beside a play control. Add is NOT play: it calls the
+ cascaded IQueueService's Enqueue/EnqueueRange (which append without disturbing current playback and
+ leave a coherent CurrentIndex on a first add into a dormant queue) — never PlayRelease/Start/Select.
+ Track mode (Track set) appends a single track; release mode (ReleaseTracks set) appends the whole
+ ordered list. Reads queue state from the layout-level cascade (C1); owns no data fetch. *@
+
+
+
+
+
+@code {
+ [CascadingParameter] public IQueueService? Queue { get; set; }
+
+ /// Single track to append (track mode). Mutually exclusive with .
+ [Parameter] public TrackDto? Track { get; set; }
+
+ /// Ordered release tracks to append (release mode). Mutually exclusive with .
+ [Parameter] public IReadOnlyList? ReleaseTracks { get; set; }
+
+ [Parameter] public Size Size { get; set; } = Size.Medium;
+ [Parameter] public Color Color { get; set; } = Color.Secondary;
+
+ private string Tooltip => ReleaseTracks is not null ? "Add release to queue" : "Add to queue";
+
+ private void AddToQueue()
+ {
+ if (Queue is null) return;
+
+ if (ReleaseTracks is not null)
+ {
+ Queue.EnqueueRange(ReleaseTracks);
+ }
+ else if (Track is not null)
+ {
+ Queue.Enqueue(Track);
+ }
+ }
+}
diff --git a/DeepDrftPublic.Client/Pages/CutDetail.razor b/DeepDrftPublic.Client/Pages/CutDetail.razor
index 54f9af6..a7ce2f3 100644
--- a/DeepDrftPublic.Client/Pages/CutDetail.razor
+++ b/DeepDrftPublic.Client/Pages/CutDetail.razor
@@ -94,6 +94,10 @@ else
Play
+ @* Append the whole album (TrackNumber order) to the queue — same ordered list
+ header Play uses. Append-only: does not start playback (AC7/AC8). *@
+
+
@* Release-mode share: copies the canonical /cuts/{entryKey} URL, not a single track (§3b). *@
@@ -138,6 +142,8 @@ else
OnToggle="@(() => PlayTrack(track, index))" />
@track.TrackName
+ @* Append this single track to the queue (append-only, does not play). *@
+
}
diff --git a/DeepDrftPublic.Client/Pages/MixDetail.razor b/DeepDrftPublic.Client/Pages/MixDetail.razor
index 2c774b9..9168ba2 100644
--- a/DeepDrftPublic.Client/Pages/MixDetail.razor
+++ b/DeepDrftPublic.Client/Pages/MixDetail.razor
@@ -81,6 +81,8 @@ else
@if (ViewModel.Track is not null)
{
+ @* Append-only: queues the mix's single track without starting playback. *@
+
}
diff --git a/DeepDrftPublic.Client/Pages/SessionDetail.razor b/DeepDrftPublic.Client/Pages/SessionDetail.razor
index eac0db3..fcfea65 100644
--- a/DeepDrftPublic.Client/Pages/SessionDetail.razor
+++ b/DeepDrftPublic.Client/Pages/SessionDetail.razor
@@ -79,6 +79,8 @@ else
@if (ViewModel.Track is not null)
{
+ @* Append-only: queues the session's single track without starting playback. *@
+
}