|
|
@@ -93,6 +93,64 @@ private final class PremiumPlansViewController: NSViewController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// Footer text actions: accent color + pointing hand on hover (matches pricing-card tracking behavior).
|
|
|
+ private final class FooterLinkButton: NSButton {
|
|
|
+ private var trackingAreaRef: NSTrackingArea?
|
|
|
+ private var didPushCursor = false
|
|
|
+
|
|
|
+ override func updateTrackingAreas() {
|
|
|
+ super.updateTrackingAreas()
|
|
|
+ if let trackingAreaRef {
|
|
|
+ removeTrackingArea(trackingAreaRef)
|
|
|
+ }
|
|
|
+ let options: NSTrackingArea.Options = [.activeInActiveApp, .mouseEnteredAndExited, .inVisibleRect]
|
|
|
+ let area = NSTrackingArea(rect: .zero, options: options, owner: self, userInfo: nil)
|
|
|
+ addTrackingArea(area)
|
|
|
+ trackingAreaRef = area
|
|
|
+ }
|
|
|
+
|
|
|
+ override func mouseEntered(with event: NSEvent) {
|
|
|
+ super.mouseEntered(with: event)
|
|
|
+ setHoverVisuals(hovered: true)
|
|
|
+ if !didPushCursor {
|
|
|
+ NSCursor.pointingHand.push()
|
|
|
+ didPushCursor = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override func mouseExited(with event: NSEvent) {
|
|
|
+ super.mouseExited(with: event)
|
|
|
+ setHoverVisuals(hovered: false)
|
|
|
+ if didPushCursor {
|
|
|
+ NSCursor.pop()
|
|
|
+ didPushCursor = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override func viewWillMove(toWindow newWindow: NSWindow?) {
|
|
|
+ super.viewWillMove(toWindow: newWindow)
|
|
|
+ if newWindow == nil, didPushCursor {
|
|
|
+ NSCursor.pop()
|
|
|
+ didPushCursor = false
|
|
|
+ }
|
|
|
+ if newWindow == nil {
|
|
|
+ setHoverVisuals(hovered: false, animated: false)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private func setHoverVisuals(hovered: Bool, animated: Bool = true) {
|
|
|
+ let color = hovered ? Theme.accent : Theme.secondaryText
|
|
|
+ if animated {
|
|
|
+ NSAnimationContext.runAnimationGroup { context in
|
|
|
+ context.duration = 0.15
|
|
|
+ self.animator().contentTintColor = color
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ contentTintColor = color
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private struct Plan {
|
|
|
let id: String
|
|
|
let title: String
|
|
|
@@ -352,7 +410,6 @@ private final class PremiumPlansViewController: NSViewController {
|
|
|
let topRightTag = pillLabel(text: plan.billedPill, tint: Theme.bottomStrip, textColor: Theme.iconTint)
|
|
|
topRightTag.isHidden = plan.billedPill.isEmpty
|
|
|
topRightTag.font = .systemFont(ofSize: 10, weight: .bold)
|
|
|
- topRightTag.heightAnchor.constraint(equalToConstant: 20).isActive = true
|
|
|
|
|
|
let priceLabel = NSTextField(labelWithString: plan.price)
|
|
|
priceLabel.font = .systemFont(ofSize: 18, weight: .semibold)
|
|
|
@@ -549,7 +606,7 @@ private final class PremiumPlansViewController: NSViewController {
|
|
|
let container = NSView()
|
|
|
container.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
|
|
- let button = NSButton(title: title, target: self, action: action)
|
|
|
+ let button = FooterLinkButton(title: title, target: self, action: action)
|
|
|
button.isBordered = false
|
|
|
button.bezelStyle = .rounded
|
|
|
button.font = .systemFont(ofSize: 12, weight: .medium)
|