# Apple Design System

> Build web UI in Apple's visual language — the apple.com/HIG design system with exact SF Pro type scales, the achromatic color palette (#1d1d1f /

- Skill: `parthkishan20/apple-design-system` (Agent Skill)
- Install (CLI): `npx skillmds@latest add parthkishan20/apple-design-system`
- Raw SKILL.md: https://api.skillmd.com/api/skills/parthkishan20/apple-design-system/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: parthkishan20 (https://skillmd.com/u/parthkishan20)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/parthkishan20/apple-design-system

---


# Apple Design System

Apple's web design is not "minimalism." It is a specific, reproducible system: a near-monochrome palette with one accent, a large optically-tuned type scale, generous whitespace, hairline borders instead of shadows, and motion that is short and eased. Copying the *feel* without the *values* produces something that looks almost-Apple and reads as cheap. Use the exact numbers below.

Values marked **[verified]** were read from Apple's live CSS. Values marked **[measured]** come from teardowns of rendered apple.com pages. Values marked **[derived]** are consistent extensions of the system where Apple publishes nothing. Prefer verified values; never invent new ones when a verified one exists.

---

## The three rules that matter most

**1. Deference — the UI never competes with the content.** Per Apple's HIG, the interface helps users understand content but never competes with it. In practice: no decorative gradients, no borders around everything, no drop shadows on cards, no colored section backgrounds beyond white / `#f5f5f7` / black. If a visual element is not content and not a control, delete it.

**2. Whitespace is the layout system.** Apple separates sections with space, not dividers. A section gets 80–120px of vertical padding on desktop before it gets a border. When something looks wrong, add space before adding any other element.

**3. One accent color, reserved for interaction.** Blue means "you can act on this." Never use the accent blue for decoration, headings, icons, or emphasis. Everything else is black, near-black, gray, or white.

Two corollaries that catch most mistakes: text is `#1d1d1f`, never `#000` (pure black on white is harsh and un-Apple); and hierarchy comes from **size and weight**, never from color. A de-emphasized heading is smaller, not gray-blue.

---

## Design tokens

Drop this in as the foundation of any project. It is the whole system.

```css
:root {
  /* ---- Color: text ---- */
  --ink:            #1d1d1f;   /* [measured] primary text & headings */
  --ink-secondary:  #6e6e73;   /* [measured] supporting copy */
  --ink-tertiary:   #86868b;   /* [measured] captions, fine print */

  /* ---- Color: surface ---- */
  --surface:        #ffffff;   /* page canvas */
  --surface-alt:    #f5f5f7;   /* [measured] alternating sections, cards */
  --surface-raised: #fafafc;   /* [measured] containers on alt surfaces */
  --surface-dark:   #000000;   /* full-bleed dark sections */
  --hairline:       #d2d2d7;   /* [measured] 1px borders & dividers */

  /* ---- Color: accent (interaction only) ---- */
  --accent-fill:      #0071e3; /* [measured] filled button background */
  --accent-fill-hover:#0077ed; /* [measured] */
  --accent-link:      #0066cc; /* [measured] text links on light */
  --accent-link-dark: #2997ff; /* [measured] text links on dark */

  /* ---- Type ---- hybrid stack: real SF on Apple devices, Inter everywhere else */
  --font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display",
                  "Inter var", Inter, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-text:    -apple-system, BlinkMacSystemFont, "SF Pro Text",
                  "Inter var", Inter, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono:    ui-monospace, "SF Mono", SFMono-Regular, "JetBrains Mono",
                  Menlo, Consolas, monospace;

  /* ---- Radius ---- [verified, apps.apple.com] */
  --radius-xs:   5px;
  --radius-sm:   9px;
  --radius-md:  12px;
  --radius-lg:  17px;
  --radius-xl:  24px;
  --radius-pill: 980px;        /* [verified] Apple's signature CTA radius */

  /* ---- Spacing (4pt base) ---- [derived from measured rhythm] */
  --space-1:  4px;  --space-2:  8px;  --space-3: 12px;
  --space-4: 16px;  --space-5: 22px;  --space-6: 32px;
  --space-7: 40px;  --space-8: 60px;  --space-9: 80px;  --space-10: 120px;

  /* ---- Layout ---- */
  --container:   980px;        /* [verified] classic apple.com content width */
  --container-wide: 1200px;    /* [derived] for data-dense UI */
  --gutter:       22px;        /* [verified] nav/content inset */
  --nav-height:   44px;        /* [verified] also the min tap target */

  /* ---- Motion ---- */
  --ease-default: cubic-bezier(0.25, 0.1, 0.25, 1);   /* [verified] */
  --ease-smooth:  cubic-bezier(0.16, 1, 0.3, 1);      /* [derived] long reveals */
  --dur-fast:   160ms;
  --dur-base:   300ms;
  --dur-slow:   350ms;         /* [verified] nav expand */
}
```

### Dark mode

Do not hand-write a second stylesheet. Redefine the same tokens and let everything follow.

```css
@media (prefers-color-scheme: dark) {
  :root {
    --ink:            #f5f5f7;
    --ink-secondary:  #a1a1a6;
    --ink-tertiary:   #86868b;
    --surface:        #000000;
    --surface-alt:    #1d1d1f;
    --surface-raised: #2c2c2e;
    --hairline:       #424245;
    --accent-link:    var(--accent-link-dark);
  }
}
```

Apple's own approach on apps.apple.com is alpha-based rather than fixed hex — `--systemPrimary: rgba(0,0,0,.85)` in light, `rgba(255,255,255,.85)` in dark **[verified]**, stepping down through `.5`, `.25`, `.1`, `.05` for secondary/tertiary/quaternary/quinary. Use the alpha approach when text sits on photography or colored panels, since it stays legible against any backdrop.

---

## Typography

### Font selection rule

Apple's HIG is explicit: **SF Pro Text for 19px and smaller, SF Pro Display for 20px and larger.** The two are optically different cuts, not the same face at different sizes. Honor the split — it is the single biggest contributor to "this looks Apple."

SF Pro itself is licensed for Apple platforms and cannot be served as a webfont, so use the **hybrid stack** in the tokens above. `-apple-system` resolves to genuine San Francisco on macOS and iOS at zero bytes and zero licensing risk — it references the installed OS font rather than serving it. Since Apple-styled sites skew heavily toward Apple hardware, a large share of visitors get the real thing, and everyone else falls through to Inter, which is the closest open substitute in proportion, x-height, and neo-grotesque character.

Never substitute Roboto, Open Sans, Poppins, or Montserrat. The proportions are wrong and it reads as generic immediately.

### Setting up Inter correctly

Two settings do most of the work:

```css
@font-face {
  font-family: "Inter var";
  src: url("/fonts/Inter-roman-subset.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-display: swap;
  font-style: normal;
}

html {
  font-optical-sizing: auto;   /* Inter 4.x opsz axis = SF's Text/Display split, automatic */
  font-feature-settings: "calt" 1;
}
```

`font-optical-sizing: auto` with Inter 4.x variable is the important one — its optical-size axis reproduces exactly the mechanism behind SF Pro Text vs. Display, so the ≤19px / ≥20px split happens without you managing two families.

Do **not** enable `cv11` (single-storey `a`) — SF Pro uses a double-storey `a`, so that stylistic set moves you away from the target, not toward it.

Self-host a subset woff2 rather than linking Google Fonts: fewer round trips, no third-party request, and `font-display: swap` avoids invisible text on first paint.

### Handling the two-font seam

The hybrid stack's one real cost is that SF and Inter have different metrics — Inter runs slightly wider with a larger x-height — so a headline breaking across two lines on macOS may break across three on Windows. Two mitigations:

- Add roughly **another −0.005em of tracking** to display sizes when Inter is the resolved face, then adjust by eye against a macOS render. Treat that figure as a starting point, not a verified value.
- Use `size-adjust` and `ascent-override` in the `@font-face` block to bring Inter's metrics closer to SF's, which stabilizes line breaks across platforms.

If you need pixel-identical rendering — design QA, marketing screenshots, anything compared side by side across machines — drop `-apple-system` and `BlinkMacSystemFont` from the front of both stacks and run Inter everywhere. You trade a little authenticity for complete determinism. For normal product work, keep the hybrid.

### The display scale [verified]

All display styles are **weight 600**, SF Pro Display. Apple's actual breakpoint steps:

| Style | ≥1069px | ≤1068px | ≤734px |
|---|---|---|---|
| Headline standalone | 96px / 1.0417 / −0.015em | 80px / 1.05 / −0.015em | 48px / 1.0835 / −0.003em |
| Headline super | 80px / 1.05 / −0.015em | 64px / 1.0625 / −0.009em | 48px / 1.0835 / −0.003em |
| Headline elevated | 64px / 1.0625 / −0.009em | 48px / 1.0835 / −0.003em | 40px / 1.1 / 0 |
| Headline | 48px / 1.0835 / −0.003em | 40px / 1.1 / 0 | 32px / 1.125 / 0 *[derived]* |

Read the pattern, because it generalizes: **as type gets larger, line-height tightens toward 1.0 and letter-spacing goes more negative.** Large type set at 1.5 line-height with default tracking is the most common tell of a non-Apple site.

### Body and small text [measured]

Body text does **not** scale fluidly. It steps, then caps.

| Style | Size / line-height | Weight | Tracking |
|---|---|---|---|
| Body (≥744px) | 17px / 1.47 (25px) | 400 | −0.022em |
| Body (<744px) | 16px / 1.5 (24px) | 400 | −0.022em |
| Body compact | 14px / 1.43 (20px) | 400 | −0.016em |
| Caption | 12px / 1.33 (16px) | 400 | −0.01em |
| Legal / footer | 12px / 1.33 | 400 | 0 |
| Eyebrow | 12–14px | 600 | +0.01em, often colored `--ink-secondary` |
| Button label | 17px / 1.18 | 400 | −0.022em |

Note the tracking direction: **negative for body and headlines, positive only for small uppercase eyebrows.** Apple applies subtle negative tracking even at 17px.

### Implementation

Use `clamp()` for display type (fluid, feels intentional at every width) and discrete steps for body (predictable, protects line length). This mirrors Apple's own hybrid approach.

```css
html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
       font-synthesis: none; }

.t-hero {
  font-family: var(--font-display);
  font-size: clamp(3rem, 1.52vw + 2.63rem, 6rem);  /* 48px → 96px */
  font-weight: 600; line-height: 1.05; letter-spacing: -0.015em;
}
.t-h2 {
  font-family: var(--font-display);
  font-size: clamp(2rem, 1.6vw + 1.6rem, 3rem);    /* 32px → 48px */
  font-weight: 600; line-height: 1.0835; letter-spacing: -0.003em;
}
.t-body {
  font-family: var(--font-text);
  font-size: 16px; line-height: 1.5; letter-spacing: -0.022em;
  color: var(--ink);
}
@media (min-width: 744px) { .t-body { font-size: 17px; line-height: 1.47; } }
```

Keep measure between **50 and 75 characters** — Apple centers body copy in a narrow column (`max-width: 60ch`) even inside wide sections. Wide full-bleed paragraphs are never Apple.

---

## Layout

### Breakpoints [verified]

Apple's marketing site steps at three points. Do not invent a four-tier Bootstrap ladder.

```css
/* base: ≤734px   — phone   */
@media (min-width: 735px)  { /* ≤1068px — tablet / small laptop */ }
@media (min-width: 1069px) { /* desktop */ }
```

Secondary thresholds Apple uses for navigation behavior: **1023px** (desktop nav → compact), **767px** (mobile menu), **419px** (extra-small).

### Containers

```css
.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: max(var(--gutter), env(safe-area-inset-left));
}
```

The `env(safe-area-inset-*)` handling is **[verified]** in Apple's nav CSS and matters on notched devices. Include it.

### Section rhythm

Sections alternate `--surface` and `--surface-alt`. That alternation *is* the separation — do not also add a border between them.

| Viewport | Section padding-block |
|---|---|
| ≤734px | 60px |
| 735–1068px | 80px |
| ≥1069px | 100–120px |

---

## Components

### Buttons

Two variants, that's it. A third button style is almost always a mistake.

```css
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px;                      /* HIG minimum tap target */
  padding: 11px 21px;                    /* [measured] */
  border: 1px solid transparent;
  border-radius: var(--radius-pill);     /* 980px */
  font: 400 17px/1.18 var(--font-text);
  letter-spacing: -0.022em;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-default),
              color var(--dur-fast) var(--ease-default);
}
.btn--primary   { background: var(--accent-fill); color: #fff; }
.btn--primary:hover { background: var(--accent-fill-hover); }
.btn--secondary { background: transparent; color: var(--accent-link);
                  border-color: var(--accent-link); }
.btn--secondary:hover { background: var(--accent-link); color: #fff; }
```

Apple's buttons are **narrow**, sized to their label plus 21px of side padding. Full-width buttons appear only in mobile checkout flows. Never stretch a CTA across a desktop section.

### Chevron text link

The most-used interactive element on apple.com, and the cheapest way to make a page read as Apple.

```css
.link-chevron {
  color: var(--accent-link);
  font-size: 17px; letter-spacing: -0.022em;
  text-decoration: none;
}
.link-chevron::after { content: "\203A"; margin-left: 0.25em; }  /* › */
.link-chevron:hover { text-decoration: underline; }
```

Use these instead of secondary buttons wherever the action is navigational ("Learn more", "See all specs", "Compare models").

### Translucent navigation [verified]

```css
.nav {
  position: sticky; top: 0; z-index: 9999;
  height: var(--nav-height);
  background: rgba(255, 255, 255, 0.8);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
          backdrop-filter: saturate(180%) blur(20px);
  font-size: 12px;                      /* Apple's nav type is small */
}
@media (prefers-color-scheme: dark) { .nav { background: rgba(0, 0, 0, 0.8); } }
```

`saturate(180%) blur(20px)` is Apple's literal published value and predates the Liquid Glass era. The saturation boost is what keeps content beneath from going milky — blur alone looks wrong.

### Cards

Hairline border, generous radius, **no shadow**.

```css
.card {
  background: var(--surface-alt);
  border-radius: var(--radius-lg);      /* 17px */
  padding: var(--space-6);
}
```

If a card needs separation on an already-gray section, use `background: var(--surface)` with `border: 1px solid var(--hairline)`. Reach for `box-shadow` only for genuinely floating layers (menus, modals, toasts), and keep it soft: `0 4px 24px rgba(0,0,0,0.08)`.

---

## Motion

Apple's motion is **short, eased, and limited to transform and opacity**. Typical durations are 160ms for hovers and state changes, 300–350ms for entrances and expansions **[verified]**. Anything over 500ms feels sluggish; anything that animates `width`, `height`, `top`, or `left` will jank.

```css
.reveal {
  opacity: 0; transform: translateY(24px);
  transition: opacity var(--dur-base) var(--ease-smooth),
              transform var(--dur-base) var(--ease-smooth);
}
.reveal.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important; scroll-behavior: auto !important;
  }
}
```

Scroll-triggered reveals should use `IntersectionObserver`, fire once, and stagger siblings by 60–80ms. Never bind animation directly to scroll position for content — it hurts readability and accessibility.

---

## Liquid Glass (2025–2026)

Apple introduced Liquid Glass at WWDC 2025 — a translucent material that refracts its surroundings — and revised it at WWDC 2026 after readability complaints, adding a user-facing transparency slider and reducing default translucency. The lesson for web work is the revision, not the launch: **translucency must never cost legibility.**

CSS can approximate the material but not true refraction:

```css
.glass {
  background: rgba(255, 255, 255, 0.45);
  -webkit-backdrop-filter: saturate(180%) blur(24px);
          backdrop-filter: saturate(180%) blur(24px);
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: var(--radius-xl);
}
@supports not (backdrop-filter: blur(1px)) {
  .glass { background: rgba(255, 255, 255, 0.92); }  /* opaque fallback */
}
```

Apply it to floating chrome only — nav bars, toolbars, overlays. Never to body text containers, forms, or data tables. Always verify the text on top still clears 4.5:1 contrast against the *worst-case* backdrop, and always ship the `@supports` fallback.

---

## Accessibility

These are part of the design, not a later pass.

- **Tap targets ≥ 44×44px**, per the HIG. This is why Apple's nav and buttons are 44px tall.
- **Contrast:** body text ≥ 4.5:1, large text (≥24px or ≥19px bold) ≥ 3:1. `#1d1d1f` on `#fff` and `#0071e3` on `#fff` both pass. `--ink-tertiary` (`#86868b`) on white is ~3.5:1 — use it only for 19px+ text.
- **Focus:** style `:focus-visible`, never remove the ring. `outline: 2px solid var(--accent-link); outline-offset: 2px;`
- **Type sizing in `rem`** so browser zoom works (WCAG 1.4.4).
- Honor `prefers-reduced-motion` and `prefers-color-scheme`.

---

## Self-check before shipping

Run through this; each item corresponds to a mistake that makes work read as generic rather than Apple.

- [ ] Font stack leads with `-apple-system` and falls back to Inter, with `font-optical-sizing: auto` set
- [ ] Body text is `#1d1d1f` or its dark-mode token — not `#000`, not `#333`
- [ ] Blue appears only on interactive elements
- [ ] Display headings are weight 600 with negative letter-spacing and line-height near 1.05
- [ ] Buttons are pill-radius (980px), 44px tall, sized to content
- [ ] Section separation comes from whitespace and surface alternation, not borders
- [ ] No drop shadows on static cards
- [ ] Body copy is capped at ~60–75 characters per line
- [ ] Breakpoints are 735px and 1069px, not a generic 768/1024/1280 ladder
- [ ] `prefers-reduced-motion`, `prefers-color-scheme`, and `:focus-visible` are all handled
- [ ] Transitions animate only `transform` and `opacity`, at 160–350ms

## Anti-patterns

Purple-to-blue gradient heroes · rounded-rectangle cards with shadows in a 3-column grid · full-width gradient CTA buttons · icon-plus-heading feature rows in a boxed grid · `letter-spacing: 0` on 72px headings · Poppins or Montserrat · emoji as iconography · more than one accent color · borders around every element.

## Adapting to other stacks

**Tailwind:** map the tokens into `theme.extend` — `colors.ink: '#1d1d1f'`, `colors.accent: '#0071e3'`, `borderRadius.pill: '980px'`, `fontFamily.sans` set to the hybrid stack, and override `screens` to `{ md: '735px', lg: '1069px' }`. Do not use Tailwind's default font stack, gray scale, or breakpoints; all three are the wrong values.

**Component libraries (shadcn, MUI, Chakra):** override the theme tokens rather than restyling components individually. Most of the Apple look comes from the token layer — typography, radius, and the removal of shadows and borders.

**Existing codebases:** apply in this order, since each step is visible on its own — (1) fonts and type scale, (2) color tokens, (3) spacing and section rhythm, (4) button and link shapes, (5) motion. Retrofitting all five at once usually stalls; the type scale alone gets you most of the way.

