Layout
Shadows, spacing scale, radius tokens, and the concentric corner radius formula
Shadows (non-glass fallback)
Small
Cards, list items, inline controls. Subtle lift.
Medium
Popovers, dropdown menus, floating action buttons.
Large
Sheets, modals, full-screen overlays. Maximum elevation.
When to use
- Shadows/Fallback for iOS 16–25 and Reduce Transparency. Prefer glass when available.
- Always pair/Shadow + 1px border (separator or cardBorder) for crisp edges on light backgrounds
Platform notes
- iOS Shadows are fallback for iOS 16–25 and Reduce Transparency. On iOS 26+ prefer glass effects. Use CALayer.shadowPath for performance.
- Android Use elevation (dp) for shadow:
shadowSmall= 2dp,shadowMedium= 6dp,shadowLarge= 12dp. In Compose useModifier.shadow(elevation = X.dp). In XML useandroid:elevation. - Web Use
var(--shadowSmall)etc. viabox-shadow. Pair withborder: 1px solid var(--border)for crisp edges — shadows alone look soft on light backgrounds.
Spacing & Radius
248121624324864
6
10
14
20
24
full
Corner Curve
Always use Apple's continuous corner curve (
CALayer.cornerCurve = .continuous) for all rounded corners. The superellipse produces softer, more organic rounding than circular arcs — a defining characteristic of Apple's visual language since iOS 7.When to use
- 2–4/Icon gaps, inline element margins, tight padding
- 8/Default inner padding, gap between related items
- 12–16/Card padding, section gaps, cell content insets
- 24–32/Section spacing, screen margins, group separation
- 48–64/Major section breaks, hero spacing, scroll content insets
- radius 6/Small controls (badges, tags, checkboxes). 10 — buttons, inputs, text fields. 14 — list cells, inner cards. 20–24 — cards, sheets, modals. full — pills, avatars, circular buttons
- cornerCurve/iOS Always
.continuous— never circular. Nest with.containerRelativeon iOS 26+. Web CSSborder-radiusis always circular — no superellipse equivalent. The visual difference is subtle at small radii; noticeable at 20px+.
Platform notes
- iOS Spacing values map 1:1 to pt. Use layout constants, not hardcoded CGFloat. Corner curve must be
.continuous— never circular. - Android Spacing values map 1:1 from px tokens to dp (
space8= 8dp). For radius, useRoundedCornerShape(X.dp)in Compose orcornerRadiusin XML. Android uses circular arcs — no native superellipse, same as Web. - Web Use
var(--space*)andvar(--radius*)tokens. CSSborder-radiusis always circular — no superellipse equivalent. Visual difference is subtle below 14px.
Concentric Corner Radius
rinner = router − gap
Each nested layer subtracts its inset from the parent radius. All curves share a common center point — the device bezel, the sheet, the card inside it.
Device Screen Radius
iPhone 16 Pro
55pt
iPhone 16
47pt
iPad Pro
18pt
macCatalyst
8pt · 13pt with toolbar
Example — iPhone 16 Pro
Screen
55pt
Sheet (8pt inset)
55 − 8 = 47pt
Card (16pt inset)
47 − 16 = 31pt
Cell (12pt inset)
31 − 12 = 19pt
FenceKit (Bottom Sheet)
Minimum floor
32pt
Full-width
= screen radius
Corner curve
.continuous (always)
Dynamic
read at runtime, never hardcode
API
scene
.effectiveCornerRadius
view
.concentricCornerRadius(minimumValue:)
view
.updateConcentricCornerRadius()
iOS 26+
.containerRelative
When to use
- Formula/Subtract the gap (padding between layers) from the parent radius. Never eyeball inner radii.
- Runtime/Always read device radius via
effectiveCornerRadius. Different devices, different values. - Floor/32pt minimum for sheets. The math can yield smaller values — clamp them.
- .continuous/Concentric math requires superellipse corners. Circular arcs break the shared-center illusion.
- iOS 26/
.containerRelativedoes this automatically. Use it for new code, keep manual utilities for pre-26. - Web Apply the same rinner = router - gap formula manually in CSS. No container-relative equivalent — calculate and set
border-radiusper nesting level. Use CSS custom properties to keep it maintainable.
Platform notes
- iOS Use
effectiveCornerRadiusto read device screen radius at runtime. iOS 26+.containerRelativehandles concentric math automatically. - Android Same formula applies — outer radius minus gap equals inner radius. Use
RoundedCornerShape(X.dp)in Compose orcornerRadiusin XML shapes. Calculate per nesting level; no automatic container-relative API. - Web No container-relative equivalent — calculate
border-radiusper nesting level manually. Use CSS custom properties to keep values maintainable across breakpoints.