             let topEdge: CGFloat = ((isLandscape ? layoutConstants.topEdgeLandscape : layoutConstants.topEdgePortrait(bounds.width)) + self.topBanner)
             
             // measurement
-            let rowGaps: CGFloat = (isLandscape ? layoutConstants.rowGapsLandscape : layoutConstants.rowGapsPortrait)
+            let rowGap: CGFloat = (isLandscape ? layoutConstants.rowGapLandscape : layoutConstants.rowGapPortrait(bounds.width))
+            let lastRowGap: CGFloat = (isLandscape ? rowGap : layoutConstants.rowGapPortraitLastRow(bounds.width))
+            let rowGapTotal = CGFloat(numRows - 1 - 1) * rowGap + lastRowGap
             
             // measurement
             let keyGaps: CGFloat = {

    "specialKeyWidth": 34,
    "doneKeyWidth": 50,
    //    "spaceWidth": 138,
    "debugWidth": (DEBUG_SHOW_SPACERS ? 2 : 0)
]
func layoutMetric(name: String) -> CGFloat { return CGFloat(globalLayout[name]!) }


            
            // measurement
            let keyHeight: CGFloat = {
                let totalGaps = bottomEdge + topEdge + rowGapTotal
                return (bounds.height - totalGaps) / CGFloat(numRows)
            }()
            
