diff --git a/src/ClaudeDo.Ui/Design/IslandStyles.axaml b/src/ClaudeDo.Ui/Design/IslandStyles.axaml
index c6870765..9b7d5994 100644
--- a/src/ClaudeDo.Ui/Design/IslandStyles.axaml
+++ b/src/ClaudeDo.Ui/Design/IslandStyles.axaml
@@ -484,12 +484,21 @@
-
+
+
+
+
+
diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/TaskRowViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/TaskRowViewModel.cs
index 3e3f0e66..c0649ebe 100644
--- a/src/ClaudeDo.Ui/ViewModels/Islands/TaskRowViewModel.cs
+++ b/src/ClaudeDo.Ui/ViewModels/Islands/TaskRowViewModel.cs
@@ -45,6 +45,10 @@ public sealed partial class TaskRowViewModel : ViewModelBase
// Set by the custom drag while this row is being dragged — drives the "grabbed" row style.
[ObservableProperty] private bool _isDragging;
+ // True while a drag is hovering this row (i.e. it would show a drop-hint gap). Used to
+ // suppress the ordinary hover highlight/transitions so they don't fight the hint.
+ public bool IsDropTarget => DropHintAbove || DropHintBelow;
+
public bool CanRefine => Status == TaskStatus.Idle && PlanningPhase == PlanningPhase.None
&& !IsRefining && !IsManual;
@@ -289,6 +293,8 @@ public sealed partial class TaskRowViewModel : ViewModelBase
partial void OnDiffAdditionsChanged(int value) { OnPropertyChanged(nameof(HasDiff)); OnPropertyChanged(nameof(DiffAdditionsText)); }
partial void OnDiffDeletionsChanged(int value) { OnPropertyChanged(nameof(HasDiff)); OnPropertyChanged(nameof(DiffDeletionsText)); }
partial void OnRoadblockCountChanged(int value) { OnPropertyChanged(nameof(HasRoadblock)); OnPropertyChanged(nameof(RoadblockTooltip)); }
+ partial void OnDropHintAboveChanged(bool value) => OnPropertyChanged(nameof(IsDropTarget));
+ partial void OnDropHintBelowChanged(bool value) => OnPropertyChanged(nameof(IsDropTarget));
public void RefreshLocalized()
{
diff --git a/src/ClaudeDo.Ui/Views/Islands/TaskRowView.axaml b/src/ClaudeDo.Ui/Views/Islands/TaskRowView.axaml
index dd3f4ee9..cf4bc51e 100644
--- a/src/ClaudeDo.Ui/Views/Islands/TaskRowView.axaml
+++ b/src/ClaudeDo.Ui/Views/Islands/TaskRowView.axaml
@@ -7,15 +7,16 @@
x:DataType="vm:TaskRowViewModel">
-
+
-
-
+
+
+
+
@@ -31,6 +32,7 @@
Margin="0"
Classes.selected="{Binding IsSelected}"
Classes.dragging="{Binding IsDragging}"
+ Classes.drop-target="{Binding IsDropTarget}"
Classes.done="{Binding Done}"
ContextRequested="OnRowContextRequested">
@@ -202,9 +204,9 @@
-
-
+
+
diff --git a/tests/ClaudeDo.Worker.Tests/UiVm/TaskRowViewModelTests.cs b/tests/ClaudeDo.Worker.Tests/UiVm/TaskRowViewModelTests.cs
index 9044eb88..a8a2166d 100644
--- a/tests/ClaudeDo.Worker.Tests/UiVm/TaskRowViewModelTests.cs
+++ b/tests/ClaudeDo.Worker.Tests/UiVm/TaskRowViewModelTests.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using ClaudeDo.Data.Models;
using ClaudeDo.Ui.ViewModels.Islands;
using Xunit;
@@ -20,4 +21,25 @@ public class TaskRowViewModelTests
vm.Status = s;
Assert.Equal(expected, vm.StatusChipClass);
}
+
+ [Fact]
+ public void IsDropTarget_Follows_Either_DropHint_And_Raises_PropertyChanged()
+ {
+ var vm = new TaskRowViewModel { Id = "t" };
+ var raised = new List();
+ vm.PropertyChanged += (_, e) => raised.Add(e.PropertyName);
+
+ Assert.False(vm.IsDropTarget);
+
+ vm.DropHintAbove = true;
+ Assert.True(vm.IsDropTarget);
+ Assert.Contains(nameof(TaskRowViewModel.IsDropTarget), raised);
+
+ vm.DropHintAbove = false;
+ vm.DropHintBelow = true;
+ Assert.True(vm.IsDropTarget);
+
+ vm.DropHintBelow = false;
+ Assert.False(vm.IsDropTarget);
+ }
}