Просмотр исходного кода

Restyle home feature shortcut cards to match reference design

Update Role, Company, and Skill tiles with outline SF Symbols, corporate
blue and slate secondary colors, pastel icon wells, light border, softer
shadow, and subtitle row with trailing arrow. Increase padding and card
spacing.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 недель назад: 3
Родитель
Сommit
ac4b4c47c0
1 измененных файлов с 54 добавлено и 35 удалено
  1. 54 35
      App for Indeed/Views/DashboardView.swift

+ 54 - 35
App for Indeed/Views/DashboardView.swift

@@ -312,14 +312,14 @@ final class DashboardView: NSView, NSTextFieldDelegate {
312
 
312
 
313
     private func configureFeatureShortcutCards() {
313
     private func configureFeatureShortcutCards() {
314
         featureCardsRow.orientation = .horizontal
314
         featureCardsRow.orientation = .horizontal
315
-        featureCardsRow.spacing = 12
315
+        featureCardsRow.spacing = 16
316
         featureCardsRow.distribution = .fillEqually
316
         featureCardsRow.distribution = .fillEqually
317
         featureCardsRow.alignment = .top
317
         featureCardsRow.alignment = .top
318
         featureCardsRow.translatesAutoresizingMaskIntoConstraints = false
318
         featureCardsRow.translatesAutoresizingMaskIntoConstraints = false
319
 
319
 
320
         let specs: [(symbol: String, title: String, subtitle: String, action: Selector)] = [
320
         let specs: [(symbol: String, title: String, subtitle: String, action: Selector)] = [
321
-            ("briefcase.fill", "Role", "Explore similar or better job roles", #selector(didTapFeatureRole)),
322
-            ("building.2.fill", "Company", "Find opportunities at other companies", #selector(didTapFeatureCompany)),
321
+            ("briefcase", "Role", "Explore similar or better job roles", #selector(didTapFeatureRole)),
322
+            ("building.2", "Company", "Find opportunities at other companies", #selector(didTapFeatureCompany)),
323
             ("chevron.left.forwardslash.chevron.right", "Skill", "Match jobs that fit your skills", #selector(didTapFeatureSkill))
323
             ("chevron.left.forwardslash.chevron.right", "Skill", "Match jobs that fit your skills", #selector(didTapFeatureSkill))
324
         ]
324
         ]
325
         for spec in specs {
325
         for spec in specs {
@@ -2540,8 +2540,9 @@ private struct OpenAIAPIErrorResponse: Codable {
2540
     }
2540
     }
2541
 }
2541
 }
2542
 
2542
 
2543
-/// Home welcome row: three tappable shortcuts that seed the main search field (matches the reference dashboard tiles).
2543
+/// Home welcome row: three tappable shortcuts that seed the main search field (reference: white cards, pastel icon well, arrow at bottom trailing).
2544
 private final class FeatureShortcutCardView: NSView {
2544
 private final class FeatureShortcutCardView: NSView {
2545
+    private static let cardCornerRadius: CGFloat = 14
2545
     private weak var actionTarget: AnyObject?
2546
     private weak var actionTarget: AnyObject?
2546
     private var actionSelector: Selector
2547
     private var actionSelector: Selector
2547
 
2548
 
@@ -2551,37 +2552,44 @@ private final class FeatureShortcutCardView: NSView {
2551
         super.init(frame: .zero)
2552
         super.init(frame: .zero)
2552
         translatesAutoresizingMaskIntoConstraints = false
2553
         translatesAutoresizingMaskIntoConstraints = false
2553
         wantsLayer = true
2554
         wantsLayer = true
2554
-        layer?.cornerRadius = 14
2555
+        layer?.cornerRadius = Self.cardCornerRadius
2555
         if #available(macOS 11.0, *) {
2556
         if #available(macOS 11.0, *) {
2556
             layer?.cornerCurve = .continuous
2557
             layer?.cornerCurve = .continuous
2557
         }
2558
         }
2558
         layer?.backgroundColor = NSColor.white.cgColor
2559
         layer?.backgroundColor = NSColor.white.cgColor
2559
         layer?.masksToBounds = false
2560
         layer?.masksToBounds = false
2560
-        layer?.shadowColor = NSColor.black.withAlphaComponent(0.12).cgColor
2561
+        layer?.borderWidth = 1
2562
+        // `#EDF2F7` — light card stroke.
2563
+        layer?.borderColor = NSColor(srgbRed: 237 / 255, green: 242 / 255, blue: 247 / 255, alpha: 1).cgColor
2564
+        layer?.shadowColor = NSColor.black.withAlphaComponent(0.06).cgColor
2561
         layer?.shadowOffset = CGSize(width: 0, height: 2)
2565
         layer?.shadowOffset = CGSize(width: 0, height: 2)
2562
-        layer?.shadowRadius = 10
2566
+        layer?.shadowRadius = 12
2563
         layer?.shadowOpacity = 1
2567
         layer?.shadowOpacity = 1
2564
 
2568
 
2565
-        let brandBlue = NSColor(srgbRed: 37 / 255, green: 87 / 255, blue: 167 / 255, alpha: 1)
2566
-        let iconWellColor = NSColor(srgbRed: 220 / 255, green: 235 / 255, blue: 252 / 255, alpha: 1)
2567
-        let secondary = NSColor(srgbRed: 118 / 255, green: 118 / 255, blue: 118 / 255, alpha: 1)
2569
+        // `#0047AB` — primary title / icons / arrow.
2570
+        let primaryBlue = NSColor(srgbRed: 0 / 255, green: 71 / 255, blue: 171 / 255, alpha: 1)
2571
+        // `#EBF2FF` — circular icon well.
2572
+        let iconWellColor = NSColor(srgbRed: 235 / 255, green: 242 / 255, blue: 255 / 255, alpha: 1)
2573
+        // `#5D6D7E` — muted description.
2574
+        let secondary = NSColor(srgbRed: 93 / 255, green: 109 / 255, blue: 126 / 255, alpha: 1)
2568
 
2575
 
2576
+        let iconSize: CGFloat = 48
2569
         let iconHost = NSView()
2577
         let iconHost = NSView()
2570
         iconHost.translatesAutoresizingMaskIntoConstraints = false
2578
         iconHost.translatesAutoresizingMaskIntoConstraints = false
2571
         iconHost.wantsLayer = true
2579
         iconHost.wantsLayer = true
2572
         iconHost.layer?.backgroundColor = iconWellColor.cgColor
2580
         iconHost.layer?.backgroundColor = iconWellColor.cgColor
2573
-        iconHost.layer?.cornerRadius = 22
2581
+        iconHost.layer?.cornerRadius = iconSize / 2
2574
 
2582
 
2575
         let icon = NSImageView()
2583
         let icon = NSImageView()
2576
         icon.translatesAutoresizingMaskIntoConstraints = false
2584
         icon.translatesAutoresizingMaskIntoConstraints = false
2577
-        icon.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 16, weight: .semibold)
2585
+        icon.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 18, weight: .regular)
2578
         icon.image = NSImage(systemSymbolName: symbolName, accessibilityDescription: nil)
2586
         icon.image = NSImage(systemSymbolName: symbolName, accessibilityDescription: nil)
2579
-        icon.contentTintColor = brandBlue
2587
+        icon.contentTintColor = primaryBlue
2580
         iconHost.addSubview(icon)
2588
         iconHost.addSubview(icon)
2581
 
2589
 
2582
         let titleField = NSTextField(wrappingLabelWithString: title)
2590
         let titleField = NSTextField(wrappingLabelWithString: title)
2583
         titleField.font = .systemFont(ofSize: 15, weight: .bold)
2591
         titleField.font = .systemFont(ofSize: 15, weight: .bold)
2584
-        titleField.textColor = brandBlue
2592
+        titleField.textColor = primaryBlue
2585
         titleField.maximumNumberOfLines = 1
2593
         titleField.maximumNumberOfLines = 1
2586
         titleField.isEditable = false
2594
         titleField.isEditable = false
2587
         titleField.isBordered = false
2595
         titleField.isBordered = false
@@ -2589,50 +2597,60 @@ private final class FeatureShortcutCardView: NSView {
2589
         titleField.alignment = .left
2597
         titleField.alignment = .left
2590
 
2598
 
2591
         let subtitleField = NSTextField(wrappingLabelWithString: subtitle)
2599
         let subtitleField = NSTextField(wrappingLabelWithString: subtitle)
2592
-        subtitleField.font = .systemFont(ofSize: 11, weight: .regular)
2600
+        subtitleField.font = .systemFont(ofSize: 12, weight: .regular)
2593
         subtitleField.textColor = secondary
2601
         subtitleField.textColor = secondary
2594
         subtitleField.maximumNumberOfLines = 2
2602
         subtitleField.maximumNumberOfLines = 2
2595
         subtitleField.isEditable = false
2603
         subtitleField.isEditable = false
2596
         subtitleField.isBordered = false
2604
         subtitleField.isBordered = false
2597
         subtitleField.drawsBackground = false
2605
         subtitleField.drawsBackground = false
2598
         subtitleField.alignment = .left
2606
         subtitleField.alignment = .left
2599
-        subtitleField.preferredMaxLayoutWidth = 160
2600
-
2601
-        let textColumn = NSStackView(views: [titleField, subtitleField])
2602
-        textColumn.orientation = .vertical
2603
-        textColumn.spacing = 4
2604
-        textColumn.alignment = .leading
2605
-        textColumn.translatesAutoresizingMaskIntoConstraints = false
2606
-        textColumn.setContentHuggingPriority(.defaultLow, for: .horizontal)
2607
-        textColumn.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
2607
+        subtitleField.lineBreakMode = .byWordWrapping
2608
+        subtitleField.setContentHuggingPriority(.defaultLow, for: .horizontal)
2609
+        subtitleField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
2608
 
2610
 
2609
         let chevron = NSImageView()
2611
         let chevron = NSImageView()
2610
         chevron.translatesAutoresizingMaskIntoConstraints = false
2612
         chevron.translatesAutoresizingMaskIntoConstraints = false
2611
-        chevron.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 13, weight: .semibold)
2613
+        chevron.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 12, weight: .semibold)
2612
         chevron.image = NSImage(systemSymbolName: "arrow.right", accessibilityDescription: nil)
2614
         chevron.image = NSImage(systemSymbolName: "arrow.right", accessibilityDescription: nil)
2613
-        chevron.contentTintColor = brandBlue
2615
+        chevron.contentTintColor = primaryBlue
2614
         chevron.setContentHuggingPriority(.required, for: .horizontal)
2616
         chevron.setContentHuggingPriority(.required, for: .horizontal)
2615
         chevron.setContentCompressionResistancePriority(.required, for: .horizontal)
2617
         chevron.setContentCompressionResistancePriority(.required, for: .horizontal)
2616
 
2618
 
2619
+        let subtitleRow = NSStackView(views: [subtitleField, chevron])
2620
+        subtitleRow.orientation = .horizontal
2621
+        subtitleRow.spacing = 10
2622
+        subtitleRow.alignment = .bottom
2623
+        subtitleRow.distribution = .fill
2624
+        subtitleRow.translatesAutoresizingMaskIntoConstraints = false
2625
+
2626
+        let textColumn = NSStackView(views: [titleField, subtitleRow])
2627
+        textColumn.orientation = .vertical
2628
+        textColumn.spacing = 6
2629
+        textColumn.alignment = .leading
2630
+        textColumn.translatesAutoresizingMaskIntoConstraints = false
2631
+        textColumn.setContentHuggingPriority(.defaultLow, for: .horizontal)
2632
+        textColumn.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
2633
+
2617
         iconHost.setContentHuggingPriority(.required, for: .horizontal)
2634
         iconHost.setContentHuggingPriority(.required, for: .horizontal)
2618
         iconHost.setContentCompressionResistancePriority(.required, for: .horizontal)
2635
         iconHost.setContentCompressionResistancePriority(.required, for: .horizontal)
2619
 
2636
 
2620
-        let row = NSStackView(views: [iconHost, textColumn, chevron])
2637
+        let row = NSStackView(views: [iconHost, textColumn])
2621
         row.orientation = .horizontal
2638
         row.orientation = .horizontal
2622
-        row.spacing = 12
2639
+        row.spacing = 16
2623
         row.alignment = .centerY
2640
         row.alignment = .centerY
2624
         row.distribution = .fill
2641
         row.distribution = .fill
2625
         row.translatesAutoresizingMaskIntoConstraints = false
2642
         row.translatesAutoresizingMaskIntoConstraints = false
2626
         addSubview(row)
2643
         addSubview(row)
2627
 
2644
 
2645
+        let inset: CGFloat = 22
2628
         NSLayoutConstraint.activate([
2646
         NSLayoutConstraint.activate([
2629
-            row.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 14),
2630
-            row.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -14),
2631
-            row.topAnchor.constraint(equalTo: topAnchor, constant: 16),
2632
-            row.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16),
2647
+            row.leadingAnchor.constraint(equalTo: leadingAnchor, constant: inset),
2648
+            row.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -inset),
2649
+            row.topAnchor.constraint(equalTo: topAnchor, constant: inset),
2650
+            row.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -inset),
2633
 
2651
 
2634
-            iconHost.widthAnchor.constraint(equalToConstant: 44),
2635
-            iconHost.heightAnchor.constraint(equalToConstant: 44),
2652
+            iconHost.widthAnchor.constraint(equalToConstant: iconSize),
2653
+            iconHost.heightAnchor.constraint(equalToConstant: iconSize),
2636
             icon.centerXAnchor.constraint(equalTo: iconHost.centerXAnchor),
2654
             icon.centerXAnchor.constraint(equalTo: iconHost.centerXAnchor),
2637
             icon.centerYAnchor.constraint(equalTo: iconHost.centerYAnchor)
2655
             icon.centerYAnchor.constraint(equalTo: iconHost.centerYAnchor)
2638
         ])
2656
         ])
@@ -2651,7 +2669,8 @@ private final class FeatureShortcutCardView: NSView {
2651
         super.layout()
2669
         super.layout()
2652
         guard let layer = layer, bounds.width > 0, bounds.height > 0 else { return }
2670
         guard let layer = layer, bounds.width > 0, bounds.height > 0 else { return }
2653
         let r = bounds
2671
         let r = bounds
2654
-        layer.shadowPath = CGPath(roundedRect: r, cornerWidth: 14, cornerHeight: 14, transform: nil)
2672
+        let cr = Self.cardCornerRadius
2673
+        layer.shadowPath = CGPath(roundedRect: r, cornerWidth: cr, cornerHeight: cr, transform: nil)
2655
     }
2674
     }
2656
 
2675
 
2657
     override func mouseDown(with event: NSEvent) {
2676
     override func mouseDown(with event: NSEvent) {