Răsfoiți Sursa

Narrow the default window and scale card icons dynamically.

Centralize window dimensions in AppTheme so the app opens at 680px while preserving the existing layout with responsive icon sizing.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 1 lună în urmă
părinte
comite
0a655379e0

+ 2 - 2
smart_printer/AppDelegate.swift

@@ -23,9 +23,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
         window.styleMask.insert(.fullSizeContentView)
         window.styleMask.insert(.fullSizeContentView)
         window.isMovableByWindowBackground = true
         window.isMovableByWindowBackground = true
         window.backgroundColor = AppTheme.background
         window.backgroundColor = AppTheme.background
-        window.setContentSize(NSSize(width: 1120, height: 720))
+        window.setContentSize(NSSize(width: AppTheme.windowWidth, height: AppTheme.windowHeight))
         window.center()
         window.center()
-        window.minSize = NSSize(width: 900, height: 600)
+        window.minSize = NSSize(width: AppTheme.windowMinWidth, height: AppTheme.windowMinHeight)
     }
     }
 
 
     func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
     func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {

+ 23 - 1
smart_printer/AppTheme.swift

@@ -1,7 +1,29 @@
 import Cocoa
 import Cocoa
 
 
 enum AppTheme {
 enum AppTheme {
-    static let sidebarWidth: CGFloat = 220
+    static let windowWidth: CGFloat = 680
+    static let windowHeight: CGFloat = 720
+    static let windowMinWidth: CGFloat = 600
+    static let windowMinHeight: CGFloat = 600
+
+    static let sidebarWidth: CGFloat = 200
+    static let contentPadding: CGFloat = 20
+    static let quickStartSpacing: CGFloat = 12
+    static let featureGridSpacing: CGFloat = 10
+
+    static let quickStartIconMax: CGFloat = 80
+    static let quickStartIconMin: CGFloat = 56
+    static let featureIconMax: CGFloat = 56
+    static let featureIconMin: CGFloat = 36
+
+    static func quickStartIconSize(forCardWidth width: CGFloat) -> CGFloat {
+        min(quickStartIconMax, max(quickStartIconMin, width * 0.58))
+    }
+
+    static func featureIconSize(forCardWidth width: CGFloat) -> CGFloat {
+        min(featureIconMax, max(featureIconMin, width * 0.38))
+    }
+
     static let cornerRadius: CGFloat = 14
     static let cornerRadius: CGFloat = 14
     static let cardCornerRadius: CGFloat = 20
     static let cardCornerRadius: CGFloat = 20
     static let featureCardCornerRadius: CGFloat = 16
     static let featureCardCornerRadius: CGFloat = 16

+ 2 - 2
smart_printer/Base.lproj/Main.storyboard

@@ -686,7 +686,7 @@
                     <window key="window" title="Smart Printer" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="YES" animationBehavior="default" id="IQv-IB-iLA">
                     <window key="window" title="Smart Printer" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="YES" animationBehavior="default" id="IQv-IB-iLA">
                         <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
                         <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
                         <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
                         <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
-                        <rect key="contentRect" x="196" y="240" width="1120" height="720"/>
+                        <rect key="contentRect" x="196" y="240" width="680" height="720"/>
                         <rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
                         <rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
                         <connections>
                         <connections>
                             <outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
                             <outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
@@ -705,7 +705,7 @@
             <objects>
             <objects>
                 <viewController id="XfG-lQ-9wD" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
                 <viewController id="XfG-lQ-9wD" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
                     <view key="view" id="m2S-Jp-Qdl">
                     <view key="view" id="m2S-Jp-Qdl">
-                        <rect key="frame" x="0.0" y="0.0" width="1120" height="720"/>
+                        <rect key="frame" x="0.0" y="0.0" width="680" height="720"/>
                         <autoresizingMask key="autoresizingMask"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </view>
                     </view>
                 </viewController>
                 </viewController>

+ 60 - 28
smart_printer/UIComponents.swift

@@ -184,7 +184,12 @@ struct QuickStartCardData {
 }
 }
 
 
 final class QuickStartCardView: NSView {
 final class QuickStartCardView: NSView {
+    private let iconView: QuickStartIconView
+    private var iconWidthConstraint: NSLayoutConstraint!
+    private var iconHeightConstraint: NSLayoutConstraint!
+
     init(data: QuickStartCardData) {
     init(data: QuickStartCardData) {
+        iconView = QuickStartIconView(kind: data.iconKind)
         super.init(frame: .zero)
         super.init(frame: .zero)
         translatesAutoresizingMaskIntoConstraints = false
         translatesAutoresizingMaskIntoConstraints = false
 
 
@@ -211,8 +216,6 @@ final class QuickStartCardView: NSView {
         let wavePattern = WavePatternView()
         let wavePattern = WavePatternView()
         wavePattern.translatesAutoresizingMaskIntoConstraints = false
         wavePattern.translatesAutoresizingMaskIntoConstraints = false
 
 
-        let iconView = QuickStartIconView(kind: data.iconKind)
-
         addSubview(gradient)
         addSubview(gradient)
         gradient.addSubview(wavePattern)
         gradient.addSubview(wavePattern)
         gradient.addSubview(titleLabel)
         gradient.addSubview(titleLabel)
@@ -225,32 +228,44 @@ final class QuickStartCardView: NSView {
             gradient.trailingAnchor.constraint(equalTo: trailingAnchor),
             gradient.trailingAnchor.constraint(equalTo: trailingAnchor),
             gradient.topAnchor.constraint(equalTo: topAnchor),
             gradient.topAnchor.constraint(equalTo: topAnchor),
             gradient.bottomAnchor.constraint(equalTo: bottomAnchor),
             gradient.bottomAnchor.constraint(equalTo: bottomAnchor),
-            heightAnchor.constraint(equalToConstant: 160),
+            heightAnchor.constraint(equalToConstant: 148),
 
 
-            titleLabel.leadingAnchor.constraint(equalTo: gradient.leadingAnchor, constant: 24),
-            titleLabel.topAnchor.constraint(equalTo: gradient.topAnchor, constant: 28),
+            titleLabel.leadingAnchor.constraint(equalTo: gradient.leadingAnchor, constant: 18),
+            titleLabel.topAnchor.constraint(equalTo: gradient.topAnchor, constant: 24),
 
 
             subtitleLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
             subtitleLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
-            subtitleLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 6),
-            subtitleLabel.trailingAnchor.constraint(lessThanOrEqualTo: iconView.leadingAnchor, constant: -12),
+            subtitleLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 4),
+            subtitleLabel.trailingAnchor.constraint(lessThanOrEqualTo: iconView.leadingAnchor, constant: -8),
 
 
             button.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
             button.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
-            button.bottomAnchor.constraint(equalTo: gradient.bottomAnchor, constant: -24),
+            button.bottomAnchor.constraint(equalTo: gradient.bottomAnchor, constant: -20),
 
 
             wavePattern.trailingAnchor.constraint(equalTo: gradient.trailingAnchor),
             wavePattern.trailingAnchor.constraint(equalTo: gradient.trailingAnchor),
             wavePattern.bottomAnchor.constraint(equalTo: gradient.bottomAnchor),
             wavePattern.bottomAnchor.constraint(equalTo: gradient.bottomAnchor),
-            wavePattern.widthAnchor.constraint(equalToConstant: 120),
-            wavePattern.heightAnchor.constraint(equalToConstant: 80),
+            wavePattern.widthAnchor.constraint(equalToConstant: 100),
+            wavePattern.heightAnchor.constraint(equalToConstant: 70),
 
 
-            iconView.trailingAnchor.constraint(equalTo: gradient.trailingAnchor, constant: -12),
+            iconView.trailingAnchor.constraint(equalTo: gradient.trailingAnchor, constant: -8),
             iconView.centerYAnchor.constraint(equalTo: gradient.centerYAnchor),
             iconView.centerYAnchor.constraint(equalTo: gradient.centerYAnchor),
-            iconView.widthAnchor.constraint(equalToConstant: 110),
-            iconView.heightAnchor.constraint(equalToConstant: 110),
         ])
         ])
+
+        iconWidthConstraint = iconView.widthAnchor.constraint(equalToConstant: AppTheme.quickStartIconMax)
+        iconHeightConstraint = iconView.heightAnchor.constraint(equalToConstant: AppTheme.quickStartIconMax)
+        iconWidthConstraint.isActive = true
+        iconHeightConstraint.isActive = true
     }
     }
 
 
     @available(*, unavailable)
     @available(*, unavailable)
     required init?(coder: NSCoder) { nil }
     required init?(coder: NSCoder) { nil }
+
+    override func layout() {
+        super.layout()
+        let size = AppTheme.quickStartIconSize(forCardWidth: bounds.width)
+        if iconWidthConstraint.constant != size {
+            iconWidthConstraint.constant = size
+            iconHeightConstraint.constant = size
+        }
+    }
 }
 }
 
 
 // MARK: - Feature Card
 // MARK: - Feature Card
@@ -262,16 +277,21 @@ struct FeatureCardData {
 }
 }
 
 
 final class FeatureCardView: NSView {
 final class FeatureCardView: NSView {
+    private let iconView: FeatureIconView
+    private var iconWidthConstraint: NSLayoutConstraint!
+    private var iconHeightConstraint: NSLayoutConstraint!
+
     init(data: FeatureCardData) {
     init(data: FeatureCardData) {
+        iconView = FeatureIconView(kind: data.iconKind)
         super.init(frame: .zero)
         super.init(frame: .zero)
         translatesAutoresizingMaskIntoConstraints = false
         translatesAutoresizingMaskIntoConstraints = false
+        setContentHuggingPriority(.defaultLow, for: .horizontal)
+        setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
         wantsLayer = true
         wantsLayer = true
         layer?.backgroundColor = AppTheme.cardBackground.cgColor
         layer?.backgroundColor = AppTheme.cardBackground.cgColor
         layer?.cornerRadius = AppTheme.featureCardCornerRadius
         layer?.cornerRadius = AppTheme.featureCardCornerRadius
         applyCardShadow()
         applyCardShadow()
 
 
-        let iconView = FeatureIconView(kind: data.iconKind)
-
         let titleLabel = NSTextField(labelWithString: data.title)
         let titleLabel = NSTextField(labelWithString: data.title)
         titleLabel.font = AppTheme.semiboldFont(size: 15)
         titleLabel.font = AppTheme.semiboldFont(size: 15)
         titleLabel.textColor = AppTheme.textPrimary
         titleLabel.textColor = AppTheme.textPrimary
@@ -286,7 +306,7 @@ final class FeatureCardView: NSView {
         arrowButton.isBordered = false
         arrowButton.isBordered = false
         arrowButton.wantsLayer = true
         arrowButton.wantsLayer = true
         arrowButton.layer?.backgroundColor = NSColor.white.cgColor
         arrowButton.layer?.backgroundColor = NSColor.white.cgColor
-        arrowButton.layer?.cornerRadius = 15
+        arrowButton.layer?.cornerRadius = 13
         arrowButton.layer?.borderWidth = 1
         arrowButton.layer?.borderWidth = 1
         arrowButton.layer?.borderColor = NSColor(calibratedWhite: 0.88, alpha: 1).cgColor
         arrowButton.layer?.borderColor = NSColor(calibratedWhite: 0.88, alpha: 1).cgColor
         arrowButton.translatesAutoresizingMaskIntoConstraints = false
         arrowButton.translatesAutoresizingMaskIntoConstraints = false
@@ -302,31 +322,43 @@ final class FeatureCardView: NSView {
         addSubview(arrowButton)
         addSubview(arrowButton)
 
 
         NSLayoutConstraint.activate([
         NSLayoutConstraint.activate([
-            heightAnchor.constraint(equalToConstant: 118),
+            heightAnchor.constraint(equalToConstant: 104),
 
 
-            iconView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 14),
+            iconView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10),
             iconView.centerYAnchor.constraint(equalTo: centerYAnchor),
             iconView.centerYAnchor.constraint(equalTo: centerYAnchor),
-            iconView.widthAnchor.constraint(equalToConstant: 72),
-            iconView.heightAnchor.constraint(equalToConstant: 72),
 
 
-            titleLabel.leadingAnchor.constraint(equalTo: iconView.trailingAnchor, constant: 10),
-            titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: 28),
-            titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -40),
+            titleLabel.leadingAnchor.constraint(equalTo: iconView.trailingAnchor, constant: 8),
+            titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: 22),
+            titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -32),
 
 
             subtitleLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
             subtitleLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
-            subtitleLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 4),
+            subtitleLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 3),
             subtitleLabel.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
             subtitleLabel.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
 
 
-            arrowButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -14),
-            arrowButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -14),
-            arrowButton.widthAnchor.constraint(equalToConstant: 30),
-            arrowButton.heightAnchor.constraint(equalToConstant: 30),
+            arrowButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10),
+            arrowButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10),
+            arrowButton.widthAnchor.constraint(equalToConstant: 26),
+            arrowButton.heightAnchor.constraint(equalToConstant: 26),
         ])
         ])
+
+        iconWidthConstraint = iconView.widthAnchor.constraint(equalToConstant: AppTheme.featureIconMax)
+        iconHeightConstraint = iconView.heightAnchor.constraint(equalToConstant: AppTheme.featureIconMax)
+        iconWidthConstraint.isActive = true
+        iconHeightConstraint.isActive = true
     }
     }
 
 
     @available(*, unavailable)
     @available(*, unavailable)
     required init?(coder: NSCoder) { nil }
     required init?(coder: NSCoder) { nil }
 
 
+    override func layout() {
+        super.layout()
+        let size = AppTheme.featureIconSize(forCardWidth: bounds.width)
+        if iconWidthConstraint.constant != size {
+            iconWidthConstraint.constant = size
+            iconHeightConstraint.constant = size
+        }
+    }
+
     override func resetCursorRects() {
     override func resetCursorRects() {
         addCursorRect(bounds, cursor: .pointingHand)
         addCursorRect(bounds, cursor: .pointingHand)
     }
     }

+ 51 - 37
smart_printer/ViewController.swift

@@ -8,7 +8,7 @@ import Cocoa
 class ViewController: NSViewController {
 class ViewController: NSViewController {
 
 
     override func loadView() {
     override func loadView() {
-        let container = NSView(frame: NSRect(x: 0, y: 0, width: 1120, height: 720))
+        let container = NSView(frame: NSRect(x: 0, y: 0, width: AppTheme.windowWidth, height: AppTheme.windowHeight))
         container.autoresizingMask = [.width, .height]
         container.autoresizingMask = [.width, .height]
         container.wantsLayer = true
         container.wantsLayer = true
         container.layer?.backgroundColor = AppTheme.background.cgColor
         container.layer?.backgroundColor = AppTheme.background.cgColor
@@ -62,8 +62,8 @@ class ViewController: NSViewController {
 
 
             wavePattern.trailingAnchor.constraint(equalTo: mainContent.trailingAnchor),
             wavePattern.trailingAnchor.constraint(equalTo: mainContent.trailingAnchor),
             wavePattern.bottomAnchor.constraint(equalTo: mainContent.bottomAnchor),
             wavePattern.bottomAnchor.constraint(equalTo: mainContent.bottomAnchor),
-            wavePattern.widthAnchor.constraint(equalToConstant: 280),
-            wavePattern.heightAnchor.constraint(equalToConstant: 180),
+            wavePattern.widthAnchor.constraint(equalToConstant: 200),
+            wavePattern.heightAnchor.constraint(equalToConstant: 140),
         ])
         ])
     }
     }
 
 
@@ -129,12 +129,12 @@ class ViewController: NSViewController {
             documentView.trailingAnchor.constraint(equalTo: contentGuide.trailingAnchor),
             documentView.trailingAnchor.constraint(equalTo: contentGuide.trailingAnchor),
             documentView.widthAnchor.constraint(equalTo: contentGuide.widthAnchor),
             documentView.widthAnchor.constraint(equalTo: contentGuide.widthAnchor),
 
 
-            quickStartSection.leadingAnchor.constraint(equalTo: documentView.leadingAnchor, constant: 32),
-            quickStartSection.trailingAnchor.constraint(equalTo: documentView.trailingAnchor, constant: -32),
+            quickStartSection.leadingAnchor.constraint(equalTo: documentView.leadingAnchor, constant: AppTheme.contentPadding),
+            quickStartSection.trailingAnchor.constraint(equalTo: documentView.trailingAnchor, constant: -AppTheme.contentPadding),
             quickStartSection.topAnchor.constraint(equalTo: documentView.topAnchor, constant: 8),
             quickStartSection.topAnchor.constraint(equalTo: documentView.topAnchor, constant: 8),
 
 
-            createPrintSection.leadingAnchor.constraint(equalTo: documentView.leadingAnchor, constant: 32),
-            createPrintSection.trailingAnchor.constraint(equalTo: documentView.trailingAnchor, constant: -32),
+            createPrintSection.leadingAnchor.constraint(equalTo: documentView.leadingAnchor, constant: AppTheme.contentPadding),
+            createPrintSection.trailingAnchor.constraint(equalTo: documentView.trailingAnchor, constant: -AppTheme.contentPadding),
             createPrintSection.topAnchor.constraint(equalTo: quickStartSection.bottomAnchor, constant: 36),
             createPrintSection.topAnchor.constraint(equalTo: quickStartSection.bottomAnchor, constant: 36),
             createPrintSection.bottomAnchor.constraint(equalTo: documentView.bottomAnchor, constant: -40),
             createPrintSection.bottomAnchor.constraint(equalTo: documentView.bottomAnchor, constant: -40),
         ])
         ])
@@ -192,7 +192,7 @@ class ViewController: NSViewController {
 
 
         let cardsStack = NSStackView()
         let cardsStack = NSStackView()
         cardsStack.orientation = .horizontal
         cardsStack.orientation = .horizontal
-        cardsStack.spacing = 20
+        cardsStack.spacing = AppTheme.quickStartSpacing
         cardsStack.distribution = .fillEqually
         cardsStack.distribution = .fillEqually
         cardsStack.translatesAutoresizingMaskIntoConstraints = false
         cardsStack.translatesAutoresizingMaskIntoConstraints = false
 
 
@@ -258,51 +258,65 @@ class ViewController: NSViewController {
             FeatureCardData(title: "OCR File", subtitle: "Scan and print text from images", iconKind: .ocrFile),
             FeatureCardData(title: "OCR File", subtitle: "Scan and print text from images", iconKind: .ocrFile),
         ]
         ]
 
 
-        let row1 = makeFeatureRow(features: Array(features[0..<4]), columns: 4)
-        let row2 = makeFeatureRow(features: Array(features[4..<6]), columns: 4)
-
-        let gridStack = NSStackView(views: [row1, row2])
-        gridStack.orientation = .vertical
-        gridStack.spacing = 16
-        gridStack.distribution = .fill
-        gridStack.translatesAutoresizingMaskIntoConstraints = false
-        section.addSubview(gridStack)
+        let grid = makeFeatureGrid(features: features, columns: 4)
+        section.addSubview(grid)
 
 
         NSLayoutConstraint.activate([
         NSLayoutConstraint.activate([
             title.leadingAnchor.constraint(equalTo: section.leadingAnchor),
             title.leadingAnchor.constraint(equalTo: section.leadingAnchor),
             title.topAnchor.constraint(equalTo: section.topAnchor),
             title.topAnchor.constraint(equalTo: section.topAnchor),
 
 
-            gridStack.leadingAnchor.constraint(equalTo: section.leadingAnchor),
-            gridStack.trailingAnchor.constraint(equalTo: section.trailingAnchor),
-            gridStack.topAnchor.constraint(equalTo: title.bottomAnchor, constant: 16),
-            gridStack.bottomAnchor.constraint(equalTo: section.bottomAnchor),
+            grid.leadingAnchor.constraint(equalTo: section.leadingAnchor),
+            grid.trailingAnchor.constraint(equalTo: section.trailingAnchor),
+            grid.topAnchor.constraint(equalTo: title.bottomAnchor, constant: 16),
+            grid.bottomAnchor.constraint(equalTo: section.bottomAnchor),
         ])
         ])
 
 
         return section
         return section
     }
     }
 
 
-    private func makeFeatureRow(features: [FeatureCardData], columns: Int) -> NSStackView {
-        let row = NSStackView()
-        row.orientation = .horizontal
-        row.spacing = 16
-        row.distribution = .fillEqually
-        row.alignment = .centerY
-        row.translatesAutoresizingMaskIntoConstraints = false
+    private func makeFeatureGrid(features: [FeatureCardData], columns: Int) -> NSView {
+        let grid = NSView()
+        grid.translatesAutoresizingMaskIntoConstraints = false
+
+        let spacing = AppTheme.featureGridSpacing
+        let cards = features.map { FeatureCardView(data: $0) }
+        let rowCount = (cards.count + columns - 1) / columns
 
 
-        for feature in features {
-            row.addArrangedSubview(FeatureCardView(data: feature))
+        for card in cards {
+            grid.addSubview(card)
         }
         }
 
 
-        if features.count < columns {
-            let spacerCount = columns - features.count
-            for _ in 0..<spacerCount {
-                let spacer = NSView()
-                spacer.translatesAutoresizingMaskIntoConstraints = false
-                row.addArrangedSubview(spacer)
+        for (index, card) in cards.enumerated() {
+            let row = index / columns
+            let col = index % columns
+            let columnAnchor = cards[col]
+
+            if col == 0 {
+                card.leadingAnchor.constraint(equalTo: grid.leadingAnchor).isActive = true
+            } else {
+                let leftCard = cards[index - 1]
+                card.leadingAnchor.constraint(equalTo: leftCard.trailingAnchor, constant: spacing).isActive = true
+            }
+
+            card.widthAnchor.constraint(equalTo: columnAnchor.widthAnchor).isActive = true
+
+            if row == 0 {
+                card.topAnchor.constraint(equalTo: grid.topAnchor).isActive = true
+            } else {
+                let aboveCard = cards[index - columns]
+                card.topAnchor.constraint(equalTo: aboveCard.bottomAnchor, constant: spacing).isActive = true
+            }
+
+            if col == columns - 1 {
+                card.trailingAnchor.constraint(equalTo: grid.trailingAnchor).isActive = true
+            }
+
+            if row == rowCount - 1 {
+                card.bottomAnchor.constraint(equalTo: grid.bottomAnchor).isActive = true
             }
             }
         }
         }
 
 
-        return row
+        return grid
     }
     }
 }
 }