Apple Design System
Overview
Apple's digital design language is an exercise in radical restraint. The system builds its entire visual identity around a near-monochromatic foundation—cool gray {colors.canvas} backgrounds, absolute black {colors.ink} headlines, and carefully graded opacity layers of black for secondary text. Brand voltage appears in exactly one place: the electric blue {colors.primary} applied to call-to-action buttons and interactive links. This creates a visual field where product photography and typography do nearly all the communicative heavy lifting, while the UI chrome recedes to invisibility.
The typographic system is built on two faces from the SF Pro family—SF Pro Display for large editorial moments and SF Pro Text for interface elements—with a deliberate strategy of using size differentials rather than weight changes to establish hierarchy. A headline at 56px sits next to a subhead at 28px, both at font-weight 400 or 600, never heavier. The letter-spacing is surgically tight (often negative), giving the type a premium, compact feel that echoes Apple's hardware design philosophy. The {typography.title-md} role at 12px serves as a distinctive small-label voice, used for metadata like availability dates or category tags.
Shape language is dominated by the pill form factor—buttons, badges, and many containers use the extreme {rounded.pill} (980px+) radius that eliminates visual endpoints entirely. This softness contrasts with the razor-sharp precision of the type and the photographic realism of product imagery. Layout follows a strict alternating band pattern: light canvas sections give way to pure black {colors.surface-dark} bands, creating a staccato rhythm that sections the page into digestible product narratives. Each band contains a single focal point—a device, a headline, a CTA pair—never competing elements.
Sub-systems are minimal by design: the global navigation operates as its own translucent layer ({component.global-nav}) that floats above content; product hero bands alternate between light and dark dialects; and a subtle flyout menu system handles deeper navigation without leaving the page context. There are no cards-within-cards, no dashboard surfaces, no complex data tables—this is a marketing showcase, not an application interface.
Key Characteristics
- Canvas is always
{colors.canvas}(#f5f5f7)—never pure white, always this specific cool gray - Headlines use
{colors.ink}(#000000) at 600 weight, sized from 34–56px depending on prominence - Body copy sits at
{colors.body}(#1d1d1f)—slightly warmer than pure black for readability - All CTAs use
{colors.primary}(#2997ff) with{rounded.pill}geometry and white text - Secondary buttons are transparent with a 1px border in
{colors.primary} - Dark bands use
{colors.surface-dark}(#000000) with{colors.on-dark}white text - Navigation uses
rgba(255, 255, 255, 0.8)backdrop blur at fixed 44px height - Spacing rhythm centers on multiples of 8px and 10px, with 48px section breaks
- Shadows are rare and subtle—only
{extensions.shadows.lg}appears on elevated elements - Transitions follow
cubic-bezier(0.4, 0, 0.6, 1)at ~320ms duration
Colors
Brand & Accent
- Primary (
{colors.primary}— #2997ff): The singular brand color—electric blue used exclusively on primary buttons, key links, and active states. This is the only chromatic element in an otherwise achromatic system. - Primary Hover (
{colors.primary-hover}— #0071e3): Slightly darker blue for hover/interaction states on links and buttons. - Primary Active (
{colors.primary-active}— #0066cc): Pressed/depressed state for touch feedback. - Accent (
{colors.accent}— #2997ff): Alias for primary—Apple uses a single brand color, not an accent palette.
Surface
- Canvas (
{colors.canvas}— #f5f5f7): The foundational background—cool light gray that feels softer than white and reduces glare. Used for all light-themed hero bands and page backgrounds. - Surface Soft (
{colors.surface-soft}— #f5f5f7): Identical to canvas in this implementation; reserved for card-like elevations when needed. - Surface Strong (
{colors.surface-strong}— #e8e8ed): Slightly darker gray for subtle differentiation—used for hovered states, disabled surfaces, or input backgrounds. - Surface Dark (
{colors.surface-dark}— #000000): Pure black background for alternating dark product bands. Creates maximum contrast for white text and product imagery. - Surface Elevated (
{colors.surface-elevated}— #ffffff): Pure white used sparingly—for flyout menus, dropdown panels, and modal-like overlays that must pop above the canvas.
Text & Ink
- Ink (
{colors.ink}— #000000): Absolute black for headlines and high-emphasis text. Used in{typography.display-md}and larger roles. - Body (
{colors.body}— #1d1d1f): Near-black with a hint of warmth—the primary reading color for paragraph text, subheads, and medium-length content. - Muted (
{colors.muted}— rgba(0, 0, 0, 0.8)): 80% opacity black for navigation links and secondary interface text. - Muted Medium (
{colors.muted-medium}— rgba(0, 0, 0, 0.72)): 72% opacity for tertiary text—subheadlines, descriptions below main headings. - Muted Soft (
{colors.muted-soft}— rgba(0, 0, 0, 0.56)): 56% opacity for metadata, timestamps, legal text, and low-importance labels. - Muted Label (
{colors.muted-label}— #6e6e73): Solid mid-gray for small UI labels, form hints, and category tags where opacity would complicate rendering. - On Primary (
{colors.on-primary}— #ffffff): White text on blue primary buttons—passes WCAG AA against{colors.primary}. - On Dark (
{colors.on-dark}— #ffffff): White text on black dark bands—the exclusive text color for{component.hero-band-dark}sections. - On Surface (
{colors.on-surface}— #1d1d1f): Alias for body text color on standard surfaces.
Hairlines & Borders
- Hairline (
{colors.hairline}— #d2d2d7): Light gray borders for dividers, input outlines, and subtle separators. - Hairline Soft (
{colors.hairline-soft}— #e8e8ed): Very faint gray for section dividers and background lines—nearly invisible but structurally present. - Border Strong (
{colors.border-strong}— #86868b): Medium gray for focus rings, active borders, and elements requiring clear definition.
Semantic
- Link (
{colors.link}— #0071e3): Standard inline link color—matches primary-hover, used for text links within body copy. - Link Active (
{colors.link-active}— #2997ff): Active/visited link state—matches primary blue. - Error (
{colors.error}— #ff3b30): Apple's red for validation errors and destructive actions (inferred from system palette). - Success (
{colors.success}— #34c759): Green for confirmations and positive states (inferred). - Warning (
{colors.warning}— #ff9f0a): Amber for caution states (inferred).
Typography
Font Family
The system is built entirely on Apple's SF Pro typeface family, served via their proprietary /wss/fonts CDN endpoint. Two distinct sub-families play different roles:
SF Pro Display is the editorial face, optimized for larger sizes (28px and above). It carries all headline, subhead, and body-copy duties where readability at scale matters. The character shapes are slightly more open and the spacing more generous than the Text variant.
SF Pro Text is the interface face, engineered for screen legibility at small sizes (12–17px). It powers navigation links, buttons, labels, metadata, and any UI element where compact information density is needed. Both faces fall back to "Helvetica Neue", Helvetica, Arial, sans-serif for environments where SF Pro cannot load.
A third font, Apple Legacy Chevron, appears in the fallback stack for navigation elements that require the custom chevron glyph. This is a symbol-only face containing only the arrow characters used in globalnav menus.
Hierarchy
| Token | Size | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
| {typography.display-xl} | 56px | 600 | 1.07 | -0.02em | Major product names on dark bands |
| {typography.display-lg} | 40px | 600 | 1.1 | normal | Large headlines, search input |
| {typography.display-md} | 34px | 600 | 1.47 | -0.374px | Hero product headlines ("iPhone Duo") |
| {typography.title-lg} | 28px | 400 | 1.14 | 0.196px | Subheadlines, taglines ("Hello, hello.") |
| {typography.title-md} | 12px | 400 | 1.33 | -0.12px | Metadata labels, availability dates |
| {typography.body-md} | 28px | 400 | 1.14 | 0.196px | Large body copy (same as title-lg, contextual) |
| {typography.body-sm} | 17px | 400 | 1.47 | -0.022em | Standard body text, descriptions |
| {typography.caption} | 14px | 400 | 1.43 | 0 | Legal text, footnotes |
| {typography.button} | 17px | 400 | 1.29 | -0.022em | Button labels, CTA text |
| {typography.nav-link} | 17px | 400 | 1.47 | -0.022em | Global navigation menu items |
| {typography.label-md} | 14px | 600 | 1.43 | 0 | Emphasized small labels |
Principles
The typography system's defining characteristic is its refusal to use weight as a hierarchy tool beyond the binary choice between 400 (regular) and 600 (semibold). You will never see 700 (bold) or 800 (heavy) in this system—even the largest display headlines stop at 600. Instead, size carries the burden of emphasis: a 56px {typography.display-xl} headline at 600 weight commands more authority than a 17px {typography.body-sm} paragraph ever could, regardless of weight.
Letter-spacing is consistently negative or near-zero, creating a tightly-set, premium feel. The -0.374px tracking on {typography.display-md} is notably precise—not a round number, but a tuned value that optically balances the specific character widths of "iPhone Duo" at 34px. Similarly, {typography.title-lg} uses a positive 0.196px letter-spacing at 28px, a rare departure that gives the tagline text slight breathing room appropriate to its conversational tone.
Color also participates in the hierarchy: {colors.ink} (pure black) is reserved for the most important text, while {colors.body} (#1d1d1f) handles everything else. On dark bands, the system flips to {colors.on-dark} (white) exclusively. There are no colored headlines, no gradient text, no mixed-color spans within a single text block—monochrome discipline is absolute.
Uppercase is essentially absent from the system. Even navigation items and button labels use sentence case. The only exceptions are acronyms (iPhone, iPad, SF Pro) and legal disclaimers in tiny type.
Note on Font Substitutes
SF Pro is a proprietary Apple font not available on Google Fonts or open-source repositories. For implementations outside the Apple ecosystem:
- Headlines/Display: Use Inter (variable font) from Google Fonts as the closest match—it shares SF Pro's geometric humanist skeleton, similar x-height, and excellent screen rendering at all sizes. Set
font-feature-settings: "cv02", "cv03", "cv04", "cv11";to approximate SF Pro's stylistic alternates. - Interface/Text: Use Inter at smaller sizes, or **system-ui` as a native fallback that will resolve to San Francisco on Apple devices.
- CSS Variable Mapping:
--font-display: 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif; --font-text: 'Inter', 'SF Pro Text', -apple-system, BlinkMacSystemFont, sans-serif;
If Google Fonts is unavailable, IBM Plex Sans serves as a secondary substitute with similar proportions, though it lacks Inter's optical size axes.
Layout
Spacing System
- Base unit: 1px (the system uses pixel-perfect values, not a strict 4/8px grid, though most values cluster around 8px and 10px multiples).
- Tokens:
{spacing.xxs}(5px): Tight internal gaps, icon margins{spacing.xs}(8px): Small element spacing, inline gaps{spacing.sm}(10px): Button padding vertical, nav item padding{spacing.md}(15px): CTA group margin-top, form gaps{spacing.lg}(20px): Card padding, section-internal margins{spacing.xl}(21px): Minor section breaks, element stacking{spacing.xxl}(40px): Large internal padding, footer gutters{spacing.section}(48px): Vertical padding for hero bands, major section separators{spacing.hero}(48px): Same as section—hero top/bottom padding
- Section padding (vertical):
{spacing.section}(48px) — used on{component.hero-band-light},{component.hero-band-dark}, and{component.footer-band}. - Card internal padding: Components like
{component.card-product}use{spacing.lg}(20px);{component.flyout-menu}also uses{spacing.lg}. - Gutters: The main content container is centered at 1440px max-width with auto horizontal margins. Internal column gutters appear to be ~20-24px based on nav item distribution.
Grid & Container
- Max content width: 1440px (observed on
<main>,<section>, and<nav>containers). - Editorial vs. marketplace density: This is purely editorial—single-column narrative layout with full-width imagery. No multi-column grids, no sidebars, no card masonry.
- Specific grid behaviors at desktop: The page is effectively a single vertical stack of full-width bands. Within each band, content is center-constrained to ~980px readable width for text, while images can bleed edge-to-edge. The global nav spans full-width with inner content constrained to the same 1440px.
- Hero column splits: The visible "iPhone Duo" hero shows a centered text column (headline + subhead + meta + CTAs stacked vertically) with a large product image positioned below or overlapping the lower portion of the text block. No explicit two-column grid—more of a centered stack with negative-margin imagery.
Whitespace Philosophy
Whitespace is the dominant design element. The system uses it aggressively—large 48px vertical padding on every band, generous line heights (1.14–1.47x), and ample space between the CTA pair and the product image. This is editorial-airy rather than marketplace-dense: each product gets an entire viewport-height (or close to it) to tell its story without competition from adjacent content. The alternating light/dark band structure reinforces this—each section feels like its own page.
Header Architecture
+--------------------------------------------------------------------------------------------------+
| [] Store Mac iPad iPhone Watch Vision AirPods Home Entertain. Access. Support [🔍] [🛒] |
| |
| <---- 1440px max-width, centered, 44px tall, rgba(255,255,255,0.8) background, sticky ----> |
+--------------------------------------------------------------------------------------------------+
^ ^ ^
| | |
Logo Nav links (center-distributed) Utility icons (flush-right)
Hero Section (Light Band - iPhone Duo)
+--------------------------------------------------------------------------------------------------+
| |
| |
| iPhone Duo ({typography.display-md}) |
| |
| Hello, hello. ({typography.title-lg}) |
| |
| Available starting 10.23 ({typography.title-md}) |
| |
| [ Learn more ] [ Pre-order ] ({component.cta-group}) |
| |
| |
| [ iPhone Duo Product Image ] |
| (full-bleed or centered, rounded corners) |
| |
| |
+--------------------------------------------------------------------------------------------------+
<- 48px pad -> <- centered content ~980px -> <- 48px pad ->
Hero Section (Dark Band - iPhone 18 Pro)
+==========================================================================================+
| |
| |
| iPhone 18 Pro ({typography.display-xl}) |
| ({colors.on-dark}) |
| |
| Pro further. ({typography.title-lg}) |
| ({colors.on-dark}) |
| |
| |
| |
+==========================================================================================+
Pure #000000 background, white text, continues below fold with product imagery
Elevation & Depth
| Level | Treatment | Use |
|---|---|---|
| 0 – Flat | No shadow, {colors.canvas} background | Base page surface, hero bands |
| 1 – Hairline outline | 1px {colors.hairline} border | Secondary button ({component.button-secondary}), input fields |
| 2 – Soft drop | {extensions.shadows.sm} or {extensions.shadows.nav} | Global nav bar (subtle lift from content) |
| 3 – Modal/Dropdown elevation | {extensions.shadows.md} | Flyout menus, search overlay |
| 4 – Prominent elevation | {extensions.shadows.lg} (3px 5px 30px) | Product image floating effect, featured cards |
| 5 – Focus ring | 2px solid {colors.border-strong} offset | Keyboard focus indicator on interactive elements |
The system is predominantly flat—shadows appear only on elements that must visually detach from the surface. The global nav uses a translucent white background (rgba(255, 255, 255, 0.8)) rather than a shadow to separate itself from scrolling content. Product images may use the large diffuse shadow ({extensions.shadows.lg}) to create a "floating device" effect against the canvas.
Depth is achieved more through color-block alternation (light band → dark band → light band) than through z-axis layering. The pure black {colors.surface-dark} bands read as "receding" into infinity, creating depth through value contrast rather than physical elevation.
Shapes
Border Radius Scale
| Token | Value | Use |
|---|---|---|
| {rounded.sm} | 8px | Product image corners, card corners |
| {rounded.DEFAULT} | 980px | Default button radius (effectively pill) |
| {rounded.md} | 12px | Reserved for future component variants |
| {rounded.lg} | 16px | Card surfaces, panel containers |
| {rounded.xl} | 20px | Larger containers, modals |
| {rounded.pill} | 9999px | Buttons, badges, tags (fully rounded ends) |
| {rounded.full} | 9999px | Alternative pill token |
| {rounded.circle} | 50% | Avatar placeholders, circular indicators |
Photography Geometry
Product photography dominates the visual hierarchy. Images are treated as first-class design elements:
- Aspect ratio: Device photography typically uses a 3:4 or 9:16 portrait orientation for phones, matching the actual device proportions.
- Corner rounding: Product images use
{rounded.sm}(8px) radius—noticeably rounded but not pill-shaped, maintaining the rectangular integrity of the device. - Treatment: Images are photographed against clean backgrounds (white or seamless gray) with studio lighting that creates subtle gradients. No filters, no duotones, no overlay text on images.
- Positioning: In light-band heroes, the image sits below the text stack, centered horizontally, often extending near the bottom edge of the band before the transition to the next section.
- Dark band treatment: On black backgrounds, product images glow slightly—the black absorbs ambient light in the photo, making the device appear to emit its own luminosity.
Components
No hover states documented. Hover behavior is unreliable to extract from a single screenshot. State variants live as separate entries in the
components:frontmatter (e.g.{component.button-primary-hover},{component.search-input-focus}); add hover styling at implementation time per your stack's conventions.
Buttons
{component.button-primary} — The principal call-to-action: a filled pill-shaped button in {colors.primary} blue with white {colors.on-primary} text. Uses {typography.button} (17px, weight 400) and {rounded.pill} (9999px) geometry. Padding is 10px 21px vertically/horizontally. Appears in pairs or singly in hero sections ("Learn more"). Has hover ({component.button-primary-hover}) and active ({component.button-primary-active}) variants that darken the blue incrementally. Transition uses the system color 0.32s cubic-bezier(0.4, 0, 0.6, 1) timing.
{component.button-secondary} — The outlined alternative: transparent background with a 1px {colors.primary} border and blue text. Same dimensions, type, and radius as primary. Used alongside primary CTAs to offer a lower-commitment action ("Pre-order"). Hover state ({component.button-secondary-hover}) adds a very faint blue tint to the background (approximately 8% opacity blue). Active state ({component.button-secondary-active}) doubles that tint to ~16%. Never appears alone—always paired with a primary button or as a standalone "less important" action.
{component.button-primary-hover} — Hover state for primary buttons. Background shifts to {colors.primary-hover} (#0071e3), a noticeably deeper blue. All other properties (text color, radius, padding, typography) remain identical. Implement with transition: background-color 0.32s cubic-bezier(0.4, 0, 0.6, 1).
{component.button-primary-active} — Pressed/touch state. Background deepens further to {colors.primary-active} (#0066cc). This is the darkest blue in the interaction sequence, providing clear tactile feedback.
{component.button-secondary-hover} — Hover state for secondary buttons. Gains a rgba(41, 151, 255, 0.08) background wash—just enough to signal interactivity without approaching the solidity of the primary button.
{component.button-secondary-active} — Pressed state for secondary buttons. Background wash intensifies to rgba(41, 151, 255, 0.16).
Cards & Containers
{component.card-product} — A light-surface card for showcasing products or features in a grid (though the current page doesn't show a card grid, this is inferred from the design system's patterns). Background {colors.surface-soft}, text {colors.ink}, rounded {rounded.lg} (16px), padding {spacing.lg} (20px). Would contain a product image, title, and brief description.
{component.card-product-dark} — Dark-surface variant for placement within {colors.surface-dark} bands. Background pure black, text white ({colors.on-dark}), same rounding and padding as the light variant.
{component.flyout-menu} — The navigation submenu panel that appears when hovering/clicking global nav items. Background {colors.surface-elevated} (white), text {colors.body}, rounded {rounded.sm} (8px) for subtle softening, padding {spacing.lg} (20px). Uses {extensions.shadows.md} elevation to float above the page content. Contains categorized link lists in {typography.body-sm}.
{component.scrim-overlay} — A semi-transparent overlay (rgba(0, 0, 0, 0.2)) that covers the page content when flyout menus or search is active. Dismisses the overlay on click/tap outside the active element.
Inputs & Forms
{component.search-input} — The global search field that appears in the nav bar when the search icon is activated. Transparent background (no visible fill), text color rgb(51, 51, 54) (dark gray), uses {typography.display-lg} (40px—surprisingly large for an input, emphasizing search-as-command-palette behavior). Padding is 1px 34px 0px—asymmetric to accommodate the search icon. No visible border until focused.
{component.search-input-focus} — Focused state of the search input. Background remains transparent, text color shifts to {colors.ink} (pure black) for maximum contrast. A focus ring in {colors.border-strong} likely appears (standard Apple focus treatment).
Navigation
{component.global-nav} — The persistent top navigation bar. Background rgba(255, 255, 255, 0.8)—translucent white with implicit backdrop-filter blur (Apple applies this via browser-specific properties). Height fixed at 44px. Text uses {typography.nav-link} (17px, SF Pro Text with Myriad/Chevron fallbacks). Color is {colors.muted} (80% black) for inactive links, {colors.ink} for active. Contains: Apple logo (left), nav items (center-distributed), utility icons (right: search, bag). Sticks to top on scroll with {extensions.shadows.nav} appearing after scroll begins.
{component.global-nav-link} — Individual navigation menu items (Store, Mac, iPad, etc.). Transparent background, {colors.muted} text, {typography.nav-link}, padding 0 {spacing.sm} (0 10px). On hover, text color shifts toward {colors.ink}. Some items trigger {component.flyout-menu} panels on hover/press.
{component.global-nav-link-active} — Active state for nav links. Text becomes {colors.ink} (pure black), indicating the current section or page.
{component.global-nav-icon-button} — Icon-only buttons in the nav bar (search magnifier, shopping bag). 44×44px square hit target (meets WCAG AAA), transparent background, {colors.body} text/icon color. These toggle the search overlay and bag panel respectively.
Signature Components
{component.hero-band-light} — The primary product showcase container for light-themed sections. Background {colors.canvas} (cool gray), text {colors.ink}, uses {typography.display-md} for the main headline. Padding {spacing.section} (48px) top and bottom. Contains stacked children: headline → subhead → meta label → CTA group → product image. Centers content horizontally within a ~980px readable column.
{component.hero-band-dark} — The dark-alternating product showcase. Background {colors.surface-dark} (pure black), text {colors.on-dark} (white), uses {typography.display-xl} for maximum impact (56px headlines feel monumental against black). Same padding and centering logic as the light variant. Creates the staccato rhythm of Apple's page structure.
{component.product-headline} — The h1-level product name within a hero band. Transparent background, {colors.ink} (or {colors.on-dark} in dark bands), {typography.display-md} (34px, weight 600, tight tracking). Example: "iPhone Duo".
{component.product-subhead} — The tagline beneath the headline. Transparent background, {colors.muted-medium} text (72% black or equivalent white transparency), {typography.title-lg} (28px, weight 400). Example: "Hello, hello."—conversational, lighter weight than the headline.
{component.product-meta} — Availability/shipping information. Transparent background, {colors.muted-soft} text (56% black), {typography.title-md} (12px, quite small, serving as fine print). Example: "Available starting 10.23".
{component.cta-group} — The container wrapping the button pair. Transparent background, padding {spacing.md} (15px) top only—to push the buttons down from the meta text. Contains {component.button-primary} and {component.button-secondary} side-by-side with ~8-10px gap between them.
{component.product-hero-image} — The large product photograph. Transparent background (images have their own bounds), {rounded.sm} (8px) corner radius. Positioned below the CTA group, centered horizontally. May extend beyond the text column width for visual drama. Uses {extensions.shadows.lg} if a floating effect is desired.
{component.section-divider} — A 1px horizontal rule separating major sections. Background {colors.hairline-soft} (#e8e8ed), full-width, 1px height. Nearly invisible but provides structural demarcation between bands.
{component.footer-band} — The page footer area. Background {colors.surface-dark} (black), text {colors.muted-soft} (low-opacity white or gray), {typography.caption} (14px). Padding {spacing.xl} (40px) vertical. Contains legal links, copyright, and regional selectors in small type.
{component.link-inline} — Standard inline text link within body copy or footers. Transparent background, {colors.link} color (#0071e3), {typography.body-sm}. Underlined on hover per standard browser behavior (or explicitly if implemented).
{component.label-text} — Small categorical or metadata label. Transparent background, {colors.muted-label} (#6e6e73) text, {typography.title-md} (12px). Used for section categories, feature tags, or filter labels.
{component.progress-dot} — Pagination dot indicator for carousels or multi-panel sections. Background {colors.hairline} (#d2d2d7), 8×8px circle ({rounded.circle}). Inactive state.
{component.progress-dot-active} — Active pagination dot. Background {colors.ink} (black) or {colors.on-dark} (white) depending on band context. Same 8×8px size.
{component.icon-nav} — Navigation chevron or utility icon. Transparent background, {colors.body} color, 17px size (matching nav link type size). Aligned baseline with adjacent {typography.nav-link} text.
Do's and Don'ts
Do
- Do use
{colors.canvas}(#f5f5f7) as the page background—never pure white#fffffffor the main canvas (reserve white for{colors.surface-elevated}overlays only). - Do limit
{colors.primary}(#2997ff) to interactive elements—buttons, links, and active states. Never use it for headlines, backgrounds, or decorative elements. - Do maintain the 44px height for
{component.global-nav}and ensure it has a translucent white background with backdrop blur. - Do pair
{component.button-primary}with{component.button-secondary}in CTA groups—the secondary button provides an essential "lower commitment" path. - Do use
{rounded.pill}(9999px) for all buttons—this extreme roundness is a signature element that distinguishes Apple's UI. - Do alternate between
{component.hero-band-light}and{component.hero-band-dark}sections to create visual rhythm—never place two light or two dark bands adjacently. - Do keep headline font-weight at 600 maximum—never use 700 (bold) or higher, even for
{typography.display-xl}. - Do apply
{typography.title-md}(12px) to metadata like availability dates—this small size creates intentional hierarchy without needing color changes. - Do use
{colors.muted-soft}(56% opacity black) for tertiary text—this is significantly lighter than{colors.body}and signals "read only if interested." - Do center all hero content horizontally within a ~980px readable column, even though the band itself is full-width.
- Do add
{rounded.sm}(8px) corners to product photography—sharp rectangles feel dated in this system.
Don't
- Don't introduce new brand colors—
{colors.primary}is the only chromatic element. If you need emphasis, use size or value contrast instead. - Don't use font weights above 600—the system stops at semibold. If text needs more presence, increase size or switch to
{typography.display-xl}. - Don't apply shadows to the global navigation—it uses translucency (
rgba(255, 255, 255, 0.8)) for separation, not elevation. - Don't place text directly on product imagery—always keep text on solid
{colors.canvas}or{colors.surface-dark}backgrounds. - Don't use
{colors.ink}(#000000) for body paragraphs—that's reserved for headlines. Use{colors.body}(#1d1d1f) instead for reading comfort. - Don't create card grids within hero bands—each product gets its own full-width band with a single focal point.
- Don't add gradient overlays to hero images or backgrounds—Apple's aesthetic is flat color blocks, not atmospheric effects.
- Don't make buttons smaller than 44px in height (including padding)—this violates the touch-target minimum established by
{component.global-nav-icon-button}. - Don't use uppercase for button labels or navigation items—sentence case is mandatory throughout.
- Don't mix
SF Pro DisplayandSF Pro Textat the same size—Display is for ≥28px, Text is for ≤17px. Respect the optical size boundary. - Don't add border-radius to the global nav bar—it's a sharp rectangle (0px radius) that spans full-width, contrasting with the pill-shaped buttons below.
Motion & Animation
Transition Tokens
/* Color transitions - standard for all interactive elements */
--transition-color: color 0.32s cubic-bezier(0.4, 0, 0.6, 1), background-color 0.32s cubic-bezier(0.4, 0, 0.6, 1);
/* Opacity transitions - for overlays and fade effects */
--transition-opacity: opacity 0.24s cubic-bezier(0.4, 0, 0.6, 1) 0.08s, visibility 0.24s steps(1, start) 0.08s;
/* Width transitions - for search expand/collapse and accordions */
--transition-width: width 0.25s linear;
--transition-width-complex: width 1s ease-in-out, height 1s ease-in-out, padding-block 1s ease-in-out, padding-inline 1s ease-in-out, padding 1s ease-in-out;
/* Background color quick transition */
--transition-bg-quick: background-color 0.1s linear;
/* Simple fade */
--transition-fade: opacity 0.4s;
Keyframe Animations
globalnav-chevron-slide-in-hover— Chevron icon slides right on nav item hover, indicating a submenu is available.globalnav-chevron-hover-off— Chevron returns to original position when hover leaves the nav item.globalnav-flyout-slide-forward-next/previous— Flyout menu panels slide horizontally during multi-level navigation (forward/backward).globalnav-flyout-slide-back-previous/next— Reverse animation for returning to parent menu level.globalnav-scrim-height-change— The dark overlay behind open menus animates its height smoothly.globalnav-fade-in— Fade-in effect for the nav bar or its contents on page load.globalnav-search-fade— Search input field fades in/out when toggled.globalnav-search-fade-and-slide— Combined fade + vertical slide for search appearance.globalnav-search-input-intro/outro— Search text field placeholder or value animates in/out.segment-out— Segmented control indicator slides to new position.progress-indicator-animating— Loading spinner or progress bar animation.dotnav-shift-start-1/end-1— Pagination dots animate position during carousel slide transitions.
Interaction Patterns
- Nav item hover: Chevron icon slides right 4-6px via
globalnav-chevron-slide-in-hover, signaling click/tap will reveal a submenu. Duration matches--transition-color. - Flyout menu reveal: Panel fades in and slides down 8-12px over 240-320ms with
cubic-bezier(0.4, 0, 0.6, 1)easing. Scrim overlay fades in simultaneously with slight delay (0.08s). - Search expand: Clicking the search icon expands a full-width input field from 0 width to ~600px over 250ms linear easing (
--transition-width). Input text fades in separately. - Button interactions: Background color transitions over 320ms with the standard Apple easing. No scale transform—buttons don't grow on hover, they only shift color value.
- Carousel/page transitions: Content cross-fades or slides horizontally while pagination dots (
progress-dot) animate to new active position. Dot shift uses dedicated keyframes (dotnav-shift-start-1). - Scroll-triggered reveals: While not explicitly in the CSS keyframes, Apple commonly uses intersection-observer-based fade-up animations for content entering the viewport—elements start at
opacity: 0; transform: translateY(20px)and animate to full opacity/position over ~600ms withcubic-bezier(0.4, 0, 0.2, 1)easing. - Focus rings: Interactive elements gain a 2px offset outline in
{colors.border-strong}on keyboard focus, transitioning over 150ms.
Imagery Style
- Photography style: Studio product photography with pristine lighting, shot against seamless white or light-gray backgrounds. Devices are shown at 3/4 angle or front-facing, always with the screen on displaying realistic UI.
- Subject matter: Exclusively Apple hardware (iPhones, Macs, iPads) and occasionally lifestyle hands holding devices (as seen in the iPhone Duo image—a hand cradling the folded phone).
- Color treatment: No color grading, filters, or duotones. Images are color-accurate to the actual product. On dark bands, the product appears to glow due to the black background absorbing ambient light in the photograph.
- Role in layout: Imagery is dominant—product photos are large (often 500-800px tall), centered, and given more visual weight than the accompanying text. The text supports the image; the image doesn't illustrate the text.
- No illustration: Unlike tech brands that use abstract 3D illustrations or flat vector art, Apple uses only photography. Zero illustrated elements appear on this page.
- Image quality: Extremely high resolution, retina-optimized (2x or 3x asset variants served via responsive srcset). Images are crisp at all sizes with no visible compression artifacts.
- Framing: Products are tightly cropped with minimal negative space within the image frame—the surrounding whitespace comes from the layout padding, not the photo composition.
- Human elements: When hands appear (as in the Duo phone image), they are photographed with natural skin tones, casually positioned, suggesting effortless use. No stock-photo stiffness.
- Screen content: Device screens show actual iOS/macOS UI—app icons, widgets, wallpapers—not abstract gradient placeholders.
Icon System
- Library: Custom SVG icons (Apple's own icon set, not a public library). Font-based icons via "SF Pro Icons" and legacy "Apple Legacy Chevron" fonts for navigation chevrons.
- Specific icons observed:
- Apple logo (wordmark/symbol) — 17px height in nav
- Search/magnifying glass — 17px, stroke-based
- Shopping bag — 17px, stroke-based
- Navigation chevron (right-pointing) — animated on hover, part of "Apple Legacy Chevron" font
- Treatment: Stroke-based icons (not filled), using
currentColorso they inherit the text color of their parent. Line weight appears to be 1.5px or 2px consistent across all icons. - Size alignment: Icons match
{typography.nav-link}size (17px) when inline with navigation text, ensuring baseline alignment. Standalone icon buttons maintain 44×44px hit targets with the icon centered. - No icon library dependency: These are proprietary assets. Implementations must source Apple's icon fonts or recreate these few icons as inline SVGs.
Recommended Frontend Stack
- Framework: Next.js (React) / Astro (for static-marketing optimization)
- Styling: Vanilla CSS with CSS custom properties (tokens) + CSS Modules for component scoping
(Apple does NOT use Tailwind—their class names are semantic: globalnav, ac-gn, etc.)
- Fonts: Self-hosted SF Pro via Apple's CDN (/wss/fonts) or system font stack fallback
CSS variables: --font-display (SF Pro Display), --font-text (SF Pro Text)
- Animation: CSS transitions + @keyframes (no JS animation library needed for documented motion)
For scroll-triggered effects: Intersection Observer API with vanilla JS
- Icons: Custom SVG + SF Pro Icons font (chevrons) + Apple Legacy Chevron font
- Component lib: None (fully custom components—Apple builds everything in-house)
- Build tool: Vite or Next.js built-in bundler
Note on framework detection: The extracted CSS shows no Tailwind utility classes, no styled-components attributes, and no CSS Modules naming conventions (like filename_className_hash). Class names are semantic (globalnav, globalmessage-segment, visuallyhidden), suggesting either hand-authored CSS or a custom build pipeline. The presence of @font-face declarations for "Apple Legacy Chevron" indicates a font-icon approach for certain symbols.
Responsive Behavior
Breakpoints
| Name | Width | Key Changes | |---|---|---| | Mobile | < 738px | Single column, hamburger menu, stacked CTAs, reduced type sizes (~80%), full-width images | | Tablet | 738–1068px | Two-column potential for some sections, condensed nav (text links may hide), maintained type scale | | Desktop | 1068–1440px | Full nav visible, optimal hero layout, 1440px content container | | Wide | > 1440px | Content remains 1440px centered, canvas fills remaining width |
Note: Apple's actual breakpoints are proprietary and numerous—these are inferred from typical responsive behavior patterns visible in the layout structure.
Touch Targets
{component.button-primary}: ~41px height (10px padding × 2 + ~21px text) × variable width. With 21px horizontal padding, minimum width is ~80px. Meets WCAG AAA (44×44px) comfortably.{component.button-secondary}: Identical dimensions to primary button.{component.global-nav-icon-button}: Explicitly 44×44px (from CSSsize: 44px). Perfectly meets WCAG AAA.{component.global-nav-link}: Text-only links rely on line-height (~25px at 17px font) plus vertical padding. May be slightly under 44px tall—Apple often accepts this for text links where the full line-height strip is clickable.{component.search-input}: 40px font size ensures the input area is well over 44px tall when accounting for padding.
Collapsing Strategy
- Navigation: At mobile widths (< 738px), the horizontal nav links (Store, Mac, iPad, etc.) collapse into a hamburger menu icon. Tapping it opens a full-screen overlay with stacked vertical links. The 44px nav bar height is maintained.
- Hero columns: The centered text + image stack reflows to single column on mobile. Text sits at the top, CTAs below it, then the product image takes full width beneath. No side-by-side layout at small viewports.
- CTA grouping: On desktop,
{component.button-primary}and{component.button-secondary}sit side-by-side with ~10px gap. On mobile, they stack vertically (primary on top, secondary below) with ~8-10px vertical gap. - Typography scaling: Font sizes reduce by approximately 15-20% on mobile.
{typography.display-md}(34px) likely becomes ~28-29px.{typography.title-lg}(28px) becomes ~23-24px. Letter-spacing proportions remain similar. - Spacing compression: Vertical padding on hero bands reduces from 48px to ~24-32px on mobile. Internal element gaps compress proportionally.
- Global nav behavior: The translucent white background persists at all breakpoints. On mobile, the bag and search icons remain visible; the hamburger replaces the text links.
Image Behavior
- Hero product images: Scale down proportionally on mobile, maintaining aspect ratio (typically 3:4 or 9:16 for phones). Max-width: 100% of container. The
{rounded.sm}(8px) corner radius is preserved at all sizes. - Image positioning: On desktop, images may be offset or overlap text columns slightly. On mobile, they become block-level elements with no negative margins—simple stacked layout.
- Resolution switching: Apple serves 1x, 2x, and 3x image variants via
srcsetand<picture>elements, though this isn't visible in the static CSS extract. Implementation should include responsive image handling. - Dark band images: On mobile, the black background still extends full-width. White text and product image remain high-contrast. No special treatment needed beyond fluid width.
Iteration Guide
-
Start with the token foundation. Define all CSS custom properties from the YAML frontmatter (
{colors.*},{typography.*},{rounded.*},{spacing.*}) in a:rootblock or design-tokens.css file. Every value in your components must reference these tokens—never hardcode#2997ffor34pxinline. -
Build the global navigation first. Implement
{component.global-nav}as a fixed-position bar (44px tall,rgba(255, 255, 255, 0.8)background,backdrop-filter: blur(20px)). Add the Apple logo left, nav links center (using{typography.nav-link}), utilities right. Make it responsive: hide text links < 738px, show hamburger. Test the translucent effect by scrolling content underneath. -
Implement the alternating band pattern. Create reusable
{component.hero-band-light}and{component.hero-band-dark}section components. Each should accept children content, apply the correct background color, center content horizontally (max-width ~980px), and add 48px vertical padding. Alternate them: light → dark → light. -
Build the typography hierarchy precisely. Use the exact values from the frontmatter—including the non-round numbers like
letter-spacing: -0.374pxon{typography.display-md}and0.196pxon{typography.title-lg}. These precise values are part of Apple's optical tuning. Don't round them. -
Create the button system with state variants. Build
{component.button-primary}and{component.button-secondary}with their hover/active CSS classes (not nested pseudo-classes—keep them as separate.button-primary-hoverclasses for clarity). Ensure the{rounded.pill}radius (9999px) renders as fully rounded ends. Test the color transitions at 320ms withcubic-bezier(0.4, 0, 0.6, 1). -
Implement a complete hero section. Replicate the "iPhone Duo" band:
{component.product-headline}→{component.product-subhead}→{component.product-meta}→{component.cta-group}(containing the two buttons) →{component.product-hero-image}. Center everything. Apply{colors.canvas}background. Verify the type scale: 34px headline → 28px subhead → 12px meta. -
Add motion with the documented transitions. Apply
transition: color 0.32s cubic-bezier(0.4, 0, 0.6, 1)to all interactive elements. For the nav hover chevron animation, implement@keyframes globalnav-chevron-slide-in-hoverwith atransform: translateX(4-6px)keyframe. Keep all motion subtle—this brand rejects bouncy or playful animation. -
Handle fonts strategically. If you can access Apple's
/wss/fontsendpoint, use it. Otherwise, declare the CSS variable--font-display: 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;and--font-text: 'Inter', 'SF Pro Text', -apple-system, BlinkMacSystemFont, sans-serif;. Import Inter from Google Fonts. Accept that it won't be pixel-identical to SF Pro but will capture 90% of the feel. -
Test the dark band contrast. Build
{component.hero-band-dark}with{colors.surface-dark}background and{colors.on-dark}white text. Place{typography.display-xl}(56px) white headline on it. Verify WCAG AAA contrast (56px white on #000000 passes easily). Add a product image and verify it "pops" against the black. -
Run the linter and validate. After implementation, run
npx @google/design.md lint DESIGN.mdto catch broken token references, orphaned components (defined in frontmatter but missing from prose body), and contrast ratio warnings. Fix any{token.path}references that don't resolve to your CSS custom property names.
Font Setup for Non-Apple Environments:
Since SF Pro requires licensing/Apple-device access, use this substitution strategy in your CSS:
:root {
/* Primary typefaces */
--font-display: 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--font-text: 'Inter', 'SF Pro Text', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--font-nav: 'Inter', 'SF Pro Text', 'Myriad Set Pro', -apple-system, BlinkMacSystemFont, sans-serif;
/* Import Inter from Google Fonts in your HTML <head>: */
/* <link rel="preconnect" href="https://fonts.googleapis.com"> */
/* <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> */
/* <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet"> */
}
Set font-feature-settings: "cv02", "cv03", "cv04", "cv11"; on elements using Inter to enable the stylistic sets that approximate SF Pro's character variants (particularly the circular dots on 'i' and 'j', and the open apostrophe).
Known Gaps
- Hover state styling: Per the no-hover policy, hover styles for
{component.button-primary},{component.button-secondary},{component.global-nav-link}, and{component.link-inline}are documented as separate frontmatter entries but the exact color/transform values for:hoverpseudo-classes are inferred from the active states and common patterns, not extracted from live interaction. - Loading/skeleton states: No loading spinners, skeleton screens, or pending-state UI were visible in the static screenshot. The
progress-indicator-animatingkeyframe exists in the CSS but its visual output couldn't be captured. - Form validation states: Beyond
{component.search-input-focus}, there are no error, warning, or success states for form fields. The semantic colors{colors.error},{colors.success},{colors.warning}are included in the palette based on Apple's system-wide conventions but aren't grounded in visible UI on this page. - Dropdown/flyout content: The
{component.flyout-menu}component structure is defined, but its internal layout (columns, headings, link groups) couldn't determined from the screenshot since no menu was open. The keyframes for flyout animation exist in the CSS, confirming the component's existence. - Mobile navigation overlay: The hamburger menu's full-screen overlay (triggered < 738px) isn't visible in the desktop screenshot. Its structure, animation, and close behavior are inferred.
- Footer content:
{component.footer-band}is defined structurally, but the actual footer content (legal links, copyright text, region selector) falls below the visible viewport and couldn't be inspected. - Carousel/pagination system: The
dotnav-shiftandprogress-indicatorkeyframes suggest a carousel or multi-panel section exists somewhere on the page, but it wasn't in the above-fold screenshot. The{component.progress-dot}and{component.progress-dot-active}components are prepared for this. - Exact shadow values on product images: While
{extensions.shadows.lg}is documented from the extracted CSS (rgba(0, 0, 0, 0.22) 3px 5px 30px 0px), it's unclear whether this shadow appears on the iPhone Duo image specifically or only on elevated card components in other page sections. - Backdrop-filter specifics: The global nav uses
rgba(255, 255, 255, 0.8)background, and Apple famously appliesbackdrop-filter: blur(20px)to it, but this property wasn't explicitly in the extracted CSS rules (it may be applied via a browser-prefix or JavaScript polyfill not captured in the static dump). - Responsive breakpoint values: The exact pixel widths where navigation collapses, type scales down, and layout reflows are estimated from industry-standard patterns—Apple's actual media query breakpoints are not visible in the DOM snapshot.