diff --git a/Kanban/UI/Board/CardFaceView.swift b/Kanban/UI/Board/CardFaceView.swift index 1fa792a..4438013 100644 --- a/Kanban/UI/Board/CardFaceView.swift +++ b/Kanban/UI/Board/CardFaceView.swift @@ -512,6 +512,7 @@ struct CardFaceView: View, Equatable { ) .background(RoundedRectangle(cornerRadius: cornerRadius).fill(.background.secondary)) .overlay(alignment: .leading) { accentStripe } + .dragReplicaShadow() } // MARK: - Context menus diff --git a/Kanban/UI/Board/DragShadow.swift b/Kanban/UI/Board/DragShadow.swift index 1dec9e0..0aaeb7e 100644 --- a/Kanban/UI/Board/DragShadow.swift +++ b/Kanban/UI/Board/DragShadow.swift @@ -78,3 +78,23 @@ struct DragCountBadge: View { } } } + +/// The pickup lift's shadow figures — 03-board-ui.md § Motion's "the pickup lift (scale + shadow as +/// it detaches from the card)": the system drag session supplies the scale and the tracking, but +/// paints no shadow onto its preview image, so the shadow can only come from the replica view +/// itself. Values are the pathfinder's own constant ambient shadow, reused verbatim rather than +/// re-derived (`~/Documents/indie/Kanban` CardView.swift:623) — its drags read subtly raised, and +/// that read is the point. +enum DragReplicaStyle { + static let shadowColor = Color.black.opacity(0.16) + static let shadowRadius: CGFloat = 2.5 + static let shadowY: CGFloat = 1.5 +} + +extension View { + /// The pickup lift's shadow (`DragReplicaStyle`), for a drag replica's face — shared by the + /// card, lane, and trashed-lane replicas so the figures are spelled once. + func dragReplicaShadow() -> some View { + shadow(color: DragReplicaStyle.shadowColor, radius: DragReplicaStyle.shadowRadius, y: DragReplicaStyle.shadowY) + } +} diff --git a/Kanban/UI/Board/LaneView.swift b/Kanban/UI/Board/LaneView.swift index dd316e6..72c8ecb 100644 --- a/Kanban/UI/Board/LaneView.swift +++ b/Kanban/UI/Board/LaneView.swift @@ -650,6 +650,7 @@ struct LaneView: View, Equatable { .frame(width: replicaWidth, height: replicaHeight, alignment: .topLeading) .background(RoundedRectangle(cornerRadius: cornerRadius).fill(.background)) .clipShape(RoundedRectangle(cornerRadius: cornerRadius)) + .dragReplicaShadow() } /// The replica's size — **the lane's own**, floored for a lane that has not measured itself yet diff --git a/Kanban/UI/Board/TrashLaneRowView.swift b/Kanban/UI/Board/TrashLaneRowView.swift index 467a09c..c97a5e4 100644 --- a/Kanban/UI/Board/TrashLaneRowView.swift +++ b/Kanban/UI/Board/TrashLaneRowView.swift @@ -279,6 +279,7 @@ struct TrashLaneRowView: View { alignment: .leading ) .background(RoundedRectangle(cornerRadius: cornerRadius).fill(.background.tertiary)) + .dragReplicaShadow() } // MARK: - The row's two rows of menu