|
@@ -52,11 +52,8 @@ final class DashboardView: NSView, NSTextFieldDelegate, NSSharingServicePickerDe
|
|
52
|
static let proAccent = NSColor(srgbRed: 37 / 255, green: 87 / 255, blue: 167 / 255, alpha: 1)
|
52
|
static let proAccent = NSColor(srgbRed: 37 / 255, green: 87 / 255, blue: 167 / 255, alpha: 1)
|
|
53
|
static let proCTABackground = NSColor(srgbRed: 37 / 255, green: 87 / 255, blue: 167 / 255, alpha: 1)
|
53
|
static let proCTABackground = NSColor(srgbRed: 37 / 255, green: 87 / 255, blue: 167 / 255, alpha: 1)
|
|
54
|
static let proCTAText = NSColor(srgbRed: 1, green: 1, blue: 1, alpha: 1)
|
54
|
static let proCTAText = NSColor(srgbRed: 1, green: 1, blue: 1, alpha: 1)
|
|
55
|
- /// Slightly lighter blue for the top of the search-bar “Find jobs” pill (reads less flat than a solid fill).
|
|
|
|
56
|
- static let findJobsCTAHighlight = NSColor(srgbRed: 54 / 255, green: 110 / 255, blue: 198 / 255, alpha: 1)
|
|
|
|
57
|
- /// Hover states: darker brand blue, deeper gradient top, stronger tints, and subtle neutral fills used across CTAs, toggles, and the sidebar.
|
|
|
|
|
|
55
|
+ /// Hover states: darker brand blue, stronger tints, and subtle neutral fills used across CTAs, toggles, and the sidebar.
|
|
58
|
static let brandBlueHover = NSColor(srgbRed: 28 / 255, green: 70 / 255, blue: 140 / 255, alpha: 1)
|
56
|
static let brandBlueHover = NSColor(srgbRed: 28 / 255, green: 70 / 255, blue: 140 / 255, alpha: 1)
|
|
59
|
- static let findJobsCTAHighlightHover = NSColor(srgbRed: 44 / 255, green: 94 / 255, blue: 178 / 255, alpha: 1)
|
|
|
|
60
|
static let selectionFillHover = NSColor(srgbRed: 37 / 255, green: 87 / 255, blue: 167 / 255, alpha: 0.2)
|
57
|
static let selectionFillHover = NSColor(srgbRed: 37 / 255, green: 87 / 255, blue: 167 / 255, alpha: 0.2)
|
|
61
|
static let neutralHoverFill = NSColor(srgbRed: 240 / 255, green: 240 / 255, blue: 240 / 255, alpha: 1)
|
58
|
static let neutralHoverFill = NSColor(srgbRed: 240 / 255, green: 240 / 255, blue: 240 / 255, alpha: 1)
|
|
62
|
static let sidebarRowHoverFill = NSColor(srgbRed: 0, green: 0, blue: 0, alpha: 0.04)
|
59
|
static let sidebarRowHoverFill = NSColor(srgbRed: 0, green: 0, blue: 0, alpha: 0.04)
|
|
@@ -93,9 +90,11 @@ final class DashboardView: NSView, NSTextFieldDelegate, NSSharingServicePickerDe
|
|
93
|
private let jobSearchIcon = NSImageView()
|
90
|
private let jobSearchIcon = NSImageView()
|
|
94
|
private let jobKeywordsField = NSTextField()
|
91
|
private let jobKeywordsField = NSTextField()
|
|
95
|
private let findJobsButton = HoverableButton()
|
92
|
private let findJobsButton = HoverableButton()
|
|
|
|
93
|
+ private let findJobsCTAPill = HoverableView()
|
|
|
|
94
|
+ private let sendIconView = NSImageView()
|
|
|
|
95
|
+ private let sendLabel = NSTextField(labelWithString: "Send")
|
|
|
|
96
|
+ private let sendContentStack = NSStackView()
|
|
96
|
private let findJobsCTAHost = NSView()
|
97
|
private let findJobsCTAHost = NSView()
|
|
97
|
- private let findJobsCTAChrome = HoverableView()
|
|
|
|
98
|
- private var findJobsCTAGradientLayer: CAGradientLayer?
|
|
|
|
99
|
private let welcomeHeroHost = NSView()
|
98
|
private let welcomeHeroHost = NSView()
|
|
100
|
private let welcomeHeroBackgroundView = WelcomeHeroBackgroundView()
|
99
|
private let welcomeHeroBackgroundView = WelcomeHeroBackgroundView()
|
|
101
|
private lazy var welcomeSparkleCluster: WelcomeSparkleClusterView = {
|
100
|
private lazy var welcomeSparkleCluster: WelcomeSparkleClusterView = {
|
|
@@ -201,7 +200,6 @@ final class DashboardView: NSView, NSTextFieldDelegate, NSSharingServicePickerDe
|
|
201
|
override func layout() {
|
200
|
override func layout() {
|
|
202
|
super.layout()
|
201
|
super.layout()
|
|
203
|
updateSearchBarShadowPath()
|
202
|
updateSearchBarShadowPath()
|
|
204
|
- findJobsCTAGradientLayer?.frame = findJobsCTAChrome.bounds
|
|
|
|
205
|
updateFindJobsCTAShadowPath()
|
203
|
updateFindJobsCTAShadowPath()
|
|
206
|
updateJobListingDescriptionWidths()
|
204
|
updateJobListingDescriptionWidths()
|
|
207
|
updateChatBubbleWidths()
|
205
|
updateChatBubbleWidths()
|
|
@@ -1084,67 +1082,69 @@ final class DashboardView: NSView, NSTextFieldDelegate, NSSharingServicePickerDe
|
|
1084
|
findJobsCTAHost.layer?.shadowOffset = CGSize(width: 0, height: 2)
|
1082
|
findJobsCTAHost.layer?.shadowOffset = CGSize(width: 0, height: 2)
|
|
1085
|
findJobsCTAHost.layer?.shadowRadius = 6
|
1083
|
findJobsCTAHost.layer?.shadowRadius = 6
|
|
1086
|
|
1084
|
|
|
1087
|
- findJobsCTAChrome.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
1088
|
- findJobsCTAChrome.wantsLayer = true
|
|
|
|
1089
|
- findJobsCTAChrome.layer?.masksToBounds = true
|
|
|
|
1090
|
- findJobsCTAChrome.layer?.cornerRadius = ctaCorner
|
|
|
|
|
|
1085
|
+ let sendContentPadding: CGFloat = 16
|
|
|
|
1086
|
+
|
|
|
|
1087
|
+ findJobsCTAPill.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
1088
|
+ findJobsCTAPill.wantsLayer = true
|
|
|
|
1089
|
+ findJobsCTAPill.layer?.cornerRadius = ctaCorner
|
|
1091
|
if #available(macOS 11.0, *) {
|
1090
|
if #available(macOS 11.0, *) {
|
|
1092
|
- findJobsCTAChrome.layer?.cornerCurve = .continuous
|
|
|
|
|
|
1091
|
+ findJobsCTAPill.layer?.cornerCurve = .continuous
|
|
1093
|
}
|
1092
|
}
|
|
|
|
1093
|
+ findJobsCTAPill.layer?.masksToBounds = true
|
|
|
|
1094
|
+ findJobsCTAPill.layer?.backgroundColor = Theme.brandBlue.cgColor
|
|
1094
|
|
1095
|
|
|
1095
|
- let gradient = CAGradientLayer()
|
|
|
|
1096
|
- gradient.colors = [Theme.findJobsCTAHighlight.cgColor, Theme.brandBlue.cgColor]
|
|
|
|
1097
|
- gradient.startPoint = CGPoint(x: 0.5, y: 1)
|
|
|
|
1098
|
- gradient.endPoint = CGPoint(x: 0.5, y: 0)
|
|
|
|
1099
|
- findJobsCTAChrome.layer?.addSublayer(gradient)
|
|
|
|
1100
|
- findJobsCTAGradientLayer = gradient
|
|
|
|
|
|
1096
|
+ sendIconView.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
1097
|
+ sendIconView.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 11, weight: .semibold)
|
|
|
|
1098
|
+ sendIconView.image = NSImage(systemSymbolName: "paperplane.fill", accessibilityDescription: nil)
|
|
|
|
1099
|
+ sendIconView.contentTintColor = Theme.proCTAText
|
|
1101
|
|
1100
|
|
|
1102
|
- // Tracks hover over the full pill (the button only covers an inset area), so the gradient darkens whenever the mouse is anywhere over the CTA.
|
|
|
|
1103
|
- findJobsCTAChrome.pointerCursor = true
|
|
|
|
1104
|
- findJobsCTAChrome.hoverHandler = { [weak self] hovering in
|
|
|
|
1105
|
- guard let layer = self?.findJobsCTAGradientLayer else { return }
|
|
|
|
1106
|
- CATransaction.begin()
|
|
|
|
1107
|
- CATransaction.setAnimationDuration(0.15)
|
|
|
|
1108
|
- layer.colors = hovering
|
|
|
|
1109
|
- ? [Theme.findJobsCTAHighlightHover.cgColor, Theme.brandBlueHover.cgColor]
|
|
|
|
1110
|
- : [Theme.findJobsCTAHighlight.cgColor, Theme.brandBlue.cgColor]
|
|
|
|
1111
|
- CATransaction.commit()
|
|
|
|
1112
|
- }
|
|
|
|
|
|
1101
|
+ sendLabel.font = .systemFont(ofSize: 14, weight: .semibold)
|
|
|
|
1102
|
+ sendLabel.textColor = Theme.proCTAText
|
|
|
|
1103
|
+ sendLabel.alignment = .center
|
|
|
|
1104
|
+
|
|
|
|
1105
|
+ sendContentStack.orientation = .horizontal
|
|
|
|
1106
|
+ sendContentStack.spacing = 6
|
|
|
|
1107
|
+ sendContentStack.alignment = .centerY
|
|
|
|
1108
|
+ sendContentStack.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
1109
|
+ sendContentStack.addArrangedSubview(sendIconView)
|
|
|
|
1110
|
+ sendContentStack.addArrangedSubview(sendLabel)
|
|
1113
|
|
1111
|
|
|
1114
|
findJobsButton.translatesAutoresizingMaskIntoConstraints = false
|
1112
|
findJobsButton.translatesAutoresizingMaskIntoConstraints = false
|
|
1115
|
findJobsButton.title = ""
|
1113
|
findJobsButton.title = ""
|
|
1116
|
- findJobsButton.image = NSImage(systemSymbolName: "paperplane.fill", accessibilityDescription: nil)
|
|
|
|
1117
|
- findJobsButton.imagePosition = .imageLeading
|
|
|
|
1118
|
- findJobsButton.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 11, weight: .semibold)
|
|
|
|
1119
|
- findJobsButton.attributedTitle = NSAttributedString(
|
|
|
|
1120
|
- string: " Send",
|
|
|
|
1121
|
- attributes: [
|
|
|
|
1122
|
- .font: NSFont.systemFont(ofSize: 14, weight: .semibold),
|
|
|
|
1123
|
- .foregroundColor: Theme.proCTAText,
|
|
|
|
1124
|
- .kern: 0.35
|
|
|
|
1125
|
- ]
|
|
|
|
1126
|
- )
|
|
|
|
1127
|
- findJobsButton.contentTintColor = Theme.proCTAText
|
|
|
|
1128
|
findJobsButton.isBordered = false
|
1114
|
findJobsButton.isBordered = false
|
|
1129
|
- findJobsButton.bezelStyle = .rounded
|
|
|
|
|
|
1115
|
+ findJobsButton.bezelStyle = .inline
|
|
1130
|
findJobsButton.wantsLayer = true
|
1116
|
findJobsButton.wantsLayer = true
|
|
1131
|
findJobsButton.layer?.backgroundColor = NSColor.clear.cgColor
|
1117
|
findJobsButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
1132
|
findJobsButton.focusRingType = .none
|
1118
|
findJobsButton.focusRingType = .none
|
|
|
|
1119
|
+ findJobsButton.pointerCursor = true
|
|
1133
|
findJobsButton.target = self
|
1120
|
findJobsButton.target = self
|
|
1134
|
findJobsButton.action = #selector(didSubmitSearch)
|
1121
|
findJobsButton.action = #selector(didSubmitSearch)
|
|
1135
|
- findJobsButton.setContentHuggingPriority(.required, for: .horizontal)
|
|
|
|
1136
|
- findJobsButton.setContentCompressionResistancePriority(.required, for: .horizontal)
|
|
|
|
|
|
1122
|
+ findJobsButton.setAccessibilityLabel("Send")
|
|
|
|
1123
|
+ findJobsButton.hoverHandler = { [weak self] hovering in
|
|
|
|
1124
|
+ self?.findJobsCTAPill.layer?.backgroundColor = (hovering ? Theme.brandBlueHover : Theme.brandBlue).cgColor
|
|
|
|
1125
|
+ }
|
|
1137
|
|
1126
|
|
|
1138
|
- findJobsCTAHost.addSubview(findJobsCTAChrome)
|
|
|
|
|
|
1127
|
+ findJobsCTAHost.addSubview(findJobsCTAPill)
|
|
|
|
1128
|
+ findJobsCTAHost.addSubview(sendContentStack)
|
|
1139
|
findJobsCTAHost.addSubview(findJobsButton)
|
1129
|
findJobsCTAHost.addSubview(findJobsButton)
|
|
|
|
1130
|
+ findJobsCTAHost.setContentHuggingPriority(.required, for: .horizontal)
|
|
|
|
1131
|
+ findJobsCTAHost.setContentCompressionResistancePriority(.required, for: .horizontal)
|
|
1140
|
NSLayoutConstraint.activate([
|
1132
|
NSLayoutConstraint.activate([
|
|
1141
|
- findJobsCTAChrome.leadingAnchor.constraint(equalTo: findJobsCTAHost.leadingAnchor),
|
|
|
|
1142
|
- findJobsCTAChrome.trailingAnchor.constraint(equalTo: findJobsCTAHost.trailingAnchor),
|
|
|
|
1143
|
- findJobsCTAChrome.topAnchor.constraint(equalTo: findJobsCTAHost.topAnchor),
|
|
|
|
1144
|
- findJobsCTAChrome.bottomAnchor.constraint(equalTo: findJobsCTAHost.bottomAnchor),
|
|
|
|
|
|
1133
|
+ findJobsCTAPill.leadingAnchor.constraint(equalTo: findJobsCTAHost.leadingAnchor),
|
|
|
|
1134
|
+ findJobsCTAPill.trailingAnchor.constraint(equalTo: findJobsCTAHost.trailingAnchor),
|
|
|
|
1135
|
+ findJobsCTAPill.topAnchor.constraint(equalTo: findJobsCTAHost.topAnchor),
|
|
|
|
1136
|
+ findJobsCTAPill.bottomAnchor.constraint(equalTo: findJobsCTAHost.bottomAnchor),
|
|
|
|
1137
|
+
|
|
|
|
1138
|
+ sendContentStack.centerXAnchor.constraint(equalTo: findJobsCTAPill.centerXAnchor),
|
|
|
|
1139
|
+ sendContentStack.centerYAnchor.constraint(equalTo: findJobsCTAPill.centerYAnchor),
|
|
|
|
1140
|
+ sendContentStack.leadingAnchor.constraint(greaterThanOrEqualTo: findJobsCTAPill.leadingAnchor, constant: sendContentPadding),
|
|
|
|
1141
|
+ sendContentStack.trailingAnchor.constraint(lessThanOrEqualTo: findJobsCTAPill.trailingAnchor, constant: -sendContentPadding),
|
|
|
|
1142
|
+
|
|
|
|
1143
|
+ sendIconView.widthAnchor.constraint(equalToConstant: 14),
|
|
|
|
1144
|
+ sendIconView.heightAnchor.constraint(equalToConstant: 14),
|
|
1145
|
|
1145
|
|
|
1146
|
- findJobsButton.leadingAnchor.constraint(equalTo: findJobsCTAHost.leadingAnchor, constant: 14),
|
|
|
|
1147
|
- findJobsButton.trailingAnchor.constraint(equalTo: findJobsCTAHost.trailingAnchor, constant: -14),
|
|
|
|
|
|
1146
|
+ findJobsButton.leadingAnchor.constraint(equalTo: findJobsCTAHost.leadingAnchor),
|
|
|
|
1147
|
+ findJobsButton.trailingAnchor.constraint(equalTo: findJobsCTAHost.trailingAnchor),
|
|
1148
|
findJobsButton.topAnchor.constraint(equalTo: findJobsCTAHost.topAnchor),
|
1148
|
findJobsButton.topAnchor.constraint(equalTo: findJobsCTAHost.topAnchor),
|
|
1149
|
findJobsButton.bottomAnchor.constraint(equalTo: findJobsCTAHost.bottomAnchor)
|
1149
|
findJobsButton.bottomAnchor.constraint(equalTo: findJobsCTAHost.bottomAnchor)
|
|
1150
|
])
|
1150
|
])
|
|
@@ -1159,7 +1159,7 @@ final class DashboardView: NSView, NSTextFieldDelegate, NSSharingServicePickerDe
|
|
1159
|
|
1159
|
|
|
1160
|
let row = NSStackView(views: [keywordsStack, findJobsCTAHost])
|
1160
|
let row = NSStackView(views: [keywordsStack, findJobsCTAHost])
|
|
1161
|
row.orientation = .horizontal
|
1161
|
row.orientation = .horizontal
|
|
1162
|
- row.spacing = 0
|
|
|
|
|
|
1162
|
+ row.spacing = 10
|
|
1163
|
row.alignment = .centerY
|
1163
|
row.alignment = .centerY
|
|
1164
|
row.distribution = .fill
|
1164
|
row.distribution = .fill
|
|
1165
|
row.translatesAutoresizingMaskIntoConstraints = false
|
1165
|
row.translatesAutoresizingMaskIntoConstraints = false
|
|
@@ -1184,7 +1184,7 @@ final class DashboardView: NSView, NSTextFieldDelegate, NSSharingServicePickerDe
|
|
1184
|
jobSearchIcon.heightAnchor.constraint(equalToConstant: 18),
|
1184
|
jobSearchIcon.heightAnchor.constraint(equalToConstant: 18),
|
|
1185
|
|
1185
|
|
|
1186
|
findJobsCTAHost.heightAnchor.constraint(equalToConstant: ctaHeight),
|
1186
|
findJobsCTAHost.heightAnchor.constraint(equalToConstant: ctaHeight),
|
|
1187
|
- findJobsCTAHost.widthAnchor.constraint(greaterThanOrEqualToConstant: 112)
|
|
|
|
|
|
1187
|
+ findJobsCTAHost.widthAnchor.constraint(greaterThanOrEqualTo: sendContentStack.widthAnchor, constant: sendContentPadding * 2)
|
|
1188
|
])
|
1188
|
])
|
|
1189
|
searchCard.hoverHandler = nil
|
1189
|
searchCard.hoverHandler = nil
|
|
1190
|
}
|
1190
|
}
|
|
@@ -2355,7 +2355,7 @@ final class DashboardView: NSView, NSTextFieldDelegate, NSSharingServicePickerDe
|
|
2355
|
private func setInputEnabled(_ enabled: Bool) {
|
2355
|
private func setInputEnabled(_ enabled: Bool) {
|
|
2356
|
jobKeywordsField.isEnabled = enabled
|
2356
|
jobKeywordsField.isEnabled = enabled
|
|
2357
|
findJobsButton.isEnabled = enabled
|
2357
|
findJobsButton.isEnabled = enabled
|
|
2358
|
- findJobsButton.alphaValue = enabled ? 1 : 0.65
|
|
|
|
|
|
2358
|
+ findJobsCTAHost.alphaValue = enabled ? 1 : 0.65
|
|
2359
|
clearChatButton.isEnabled = enabled
|
2359
|
clearChatButton.isEnabled = enabled
|
|
2360
|
clearChatButton.alphaValue = enabled ? 1 : 0.65
|
2360
|
clearChatButton.alphaValue = enabled ? 1 : 0.65
|
|
2361
|
trailingLoadMoreJobsButton?.isEnabled = enabled
|
2361
|
trailingLoadMoreJobsButton?.isEnabled = enabled
|