--- version: alpha name: Apple-design-analysis category: Media & Consumer Tech website: https://www.apple.com description: A photography-first marketing surface where the product is the page. Edge-to-edge tiles on a signature off-white alternate with near-black bands, separated by a 12px gutter and nothing else — no cards, no borders, no radius on containers. SF Pro splits at 19px into Display and Text, and tracking crosses from negative through zero to positive as the scale descends. Exactly two weights carry the whole hierarchy, and one blue carries every action. colors: primary: "#0071e3" primary-link: "#0066cc" primary-on-dark: "#2997ff" ink: "#1d1d1f" ink-secondary: "#6e6e73" ink-tertiary: "#86868b" ink-quaternary: "#424245" on-primary: "#ffffff" on-dark: "#f5f5f7" canvas: "#ffffff" canvas-secondary: "#fafafc" canvas-tertiary: "#f5f5f7" surface-black: "#000000" surface-dark-secondary: "#161617" surface-dark-tertiary: "#1d1d1f" hairline: "#d2d2d7" hairline-soft: "#e8e8ed" chip-translucent: "rgba(210, 210, 215, 0.64)" accent-orange: "#b64400" accent-green: "#008009" accent-red: "#e30000" productred: "#af1e2d" enviro-green: "#00d959" typography: store-hero: fontFamily: "SF Pro Display, system-ui, -apple-system, sans-serif" fontSize: 80px fontWeight: 600 lineHeight: 1.05 letterSpacing: -0.015em tile-headline: fontFamily: "SF Pro Display, system-ui, -apple-system, sans-serif" fontSize: 56px fontWeight: 600 lineHeight: 1.07143 letterSpacing: -0.005em headline: fontFamily: "SF Pro Display, system-ui, -apple-system, sans-serif" fontSize: 48px fontWeight: 600 lineHeight: 1.08349 letterSpacing: -0.002em promo-headline: fontFamily: "SF Pro Display, system-ui, -apple-system, sans-serif" fontSize: 40px fontWeight: 600 lineHeight: 1.1 letterSpacing: 0em callout: fontFamily: "SF Pro Display, system-ui, -apple-system, sans-serif" fontSize: 32px fontWeight: 600 lineHeight: 1.125 letterSpacing: 0.002em tile-subhead: fontFamily: "SF Pro Display, system-ui, -apple-system, sans-serif" fontSize: 28px fontWeight: 400 lineHeight: 1.14286 letterSpacing: 0.007em promo-subhead: fontFamily: "SF Pro Display, system-ui, -apple-system, sans-serif" fontSize: 21px fontWeight: 400 lineHeight: 1.19048 letterSpacing: 0.011em tile-callout: fontFamily: "SF Pro Display, system-ui, -apple-system, sans-serif" fontSize: 19px fontWeight: 400 lineHeight: 1.21053 letterSpacing: 0.012em body: fontFamily: "SF Pro Text, system-ui, -apple-system, sans-serif" fontSize: 17px fontWeight: 400 lineHeight: 1.47059 letterSpacing: -0.022em body-reduced: fontFamily: "SF Pro Text, system-ui, -apple-system, sans-serif" fontSize: 14px fontWeight: 400 lineHeight: 1.42859 letterSpacing: -0.016em caption: fontFamily: "SF Pro Text, system-ui, -apple-system, sans-serif" fontSize: 12px fontWeight: 400 lineHeight: 1.33337 letterSpacing: -0.01em label-promo: fontFamily: "SF Pro Text, system-ui, -apple-system, sans-serif" fontSize: 12px fontWeight: 600 lineHeight: 1.33337 letterSpacing: -0.01em rounded: none: 0px xs: 5px sm: 8px md: 11px lg: 18px xl: 36px pill: 980px full: 50% spacing: xxs: 4px xs: 8px sm: 12px md: 16px cta: 17px lg: 24px xl: 32px xxl: 48px tile-top: 48px tile-bottom: 56px section: 80px components: button-primary: backgroundColor: "{colors.primary}" textColor: "{colors.on-primary}" typography: "{typography.body-reduced}" rounded: "{rounded.pill}" padding: 9px 16px button-primary-active: backgroundColor: "#006EDB" textColor: "{colors.on-primary}" rounded: "{rounded.pill}" button-elevated: backgroundColor: "{colors.primary}" textColor: "{colors.on-primary}" typography: "{typography.body}" rounded: "{rounded.pill}" padding: 12px 22px button-super: backgroundColor: "{colors.primary}" textColor: "{colors.on-primary}" typography: "{typography.body}" rounded: "{rounded.pill}" padding: 18px 31px button-reduced: backgroundColor: "{colors.primary}" textColor: "{colors.on-primary}" typography: "{typography.caption}" rounded: "{rounded.pill}" padding: 4px 11px button-secondary: backgroundColor: transparent textColor: "{colors.primary-link}" borderColor: "{colors.primary-link}" typography: "{typography.body-reduced}" rounded: "{rounded.pill}" padding: 9px 16px button-neutral: backgroundColor: "{colors.ink}" textColor: "{colors.on-primary}" typography: "{typography.body-reduced}" rounded: "{rounded.pill}" padding: 9px 16px button-block: backgroundColor: "{colors.primary}" textColor: "{colors.on-primary}" typography: "{typography.body-reduced}" rounded: "{rounded.sm}" padding: 9px 16px global-nav: backgroundColor: "rgba(255, 255, 255, 0.8)" textColor: "rgba(0, 0, 0, 0.8)" typography: "{typography.body}" height: 44px tile-light: backgroundColor: "{colors.canvas-tertiary}" textColor: "{colors.ink}" typography: "{typography.tile-headline}" rounded: "{rounded.none}" padding: 48px 0 56px tile-dark: backgroundColor: "{colors.surface-black}" textColor: "{colors.on-dark}" typography: "{typography.tile-headline}" rounded: "{rounded.none}" padding: 48px 0 56px tile-copy: textColor: "{colors.ink}" typography: "{typography.tile-subhead}" gap: 6px tile-ctas: gap: "{spacing.cta}" store-product-card: backgroundColor: "{colors.canvas}" textColor: "{colors.ink}" typography: "{typography.body}" rounded: "{rounded.lg}" padding: 18px 8px 16px paddlenav-arrow: backgroundColor: "{colors.chip-translucent}" textColor: "{colors.ink}" rounded: "{rounded.xl}" size: 45px footer: backgroundColor: "{colors.canvas-tertiary}" textColor: "rgba(0, 0, 0, 0.56)" typography: "{typography.caption}" padding: 37px 22px 11px --- ## Overview Apple's marketing web is a stack of **full-bleed tiles, not a page of components**. Each tile is a viewport-scale band on the signature off-white `{colors.canvas-tertiary}` (#f5f5f7), holding a centered copy stack and a product render, and the tiles are pushed apart by exactly `{spacing.sm}` (12px) of white. That gutter is the entire separation system. There are no cards, no borders, no container radius, and no section dividers — a tile ends because the color changes. The chrome is engineered to disappear. Two type weights carry the whole hierarchy: 600 for headlines, 400 for everything else — 500 is deliberately absent. One blue carries every action. Elevation on the marketing surfaces is a single soft drop-shadow that belongs to the product photograph, never to the UI. The only piece of visible technology is the global nav, a 44px bar of 80%-opacity white running `backdrop-filter: saturate(1.8) blur(20px)` so the page scrolls beneath it. The commerce surfaces bend the language without breaking it. The store keeps the type ladder, the blue and the pill, but introduces what the marketing pages refuse: `{rounded.lg}` (18px) product cards, a second, lighter card shadow, horizontal scroller shelves, and a display step above anything on the homepage — an 80px hero at `{typography.store-hero}`. Read the two surfaces together and the rule is: **editorial pages get no chrome; catalog pages get the minimum chrome a catalog needs.** **Key Characteristics:** - Full-bleed tiles at `min-height: 580px` on `{colors.canvas-tertiary}`, separated by a 12px white gutter and nothing else. - Two fonts, one family: SF Pro Display at ≥19px, SF Pro Text at ≤17px — the switch is load-bearing. - Tracking crosses zero as the scale descends: −0.005em at 56px → +0.012em at 19px → back to −0.022em at 17px once the face changes. - Exactly two weights: 600 for headlines, 400 for all else. No 500 anywhere. - One blue: `{colors.primary}` (#0071e3) fills actions, `{colors.primary-link}` (#0066cc) draws links and secondary outlines. - `{rounded.pill}` is literally `980px`, not `9999px`, and it is reserved for actions. Media and tiles are `{rounded.none}`. - Marketing surfaces carry one shadow, on product photography only; store surfaces add a second, lighter card shadow. - Copy stack is centered and rhythmic: headline → 6px → subhead → 17px → CTA row with 17px between buttons. - Motion is a single symmetric easing, `cubic-bezier(0.4, 0, 0.6, 1)`, at 0.24–0.32s, animating color and opacity rather than transforms. ## Colors > **Source pages analyzed:** homepage (marketing tiles), store (catalog surface), plus the global > nav and global footer chrome shared across both. ### Brand & Accent - **Action Blue** (`{colors.primary}` — #0071e3): The fill of every primary button. Press moves it to `#006EDB`. It does **not** invert on dark surfaces — the same blue sits on white and on black. - **Link Blue** (`{colors.primary-link}` — #0066cc): Text links and the text-plus-border of `{component.button-secondary}`. A step darker than Action Blue because it must hold contrast as 17px text rather than as a filled shape. - **Sky Blue** (`{colors.primary-on-dark}` — #2997ff): Inline links on dark tiles, where Link Blue would sink into the surface. - **Promo Orange** (`{colors.accent-orange}` — #b64400): The only non-blue accent in regular use — small 12px/600 eyebrow labels on store promotions ("Save with Apple Trade In"). Never a fill, only text. - **Product Red** (`{colors.productred}` — #af1e2d) and **Environment Green** (`{colors.enviro-green}` — #00d959): Programme-specific marks, not part of the interface palette. ### Surface - **White** (`{colors.canvas}` — #ffffff): The gutter between tiles, store card fills, and the nav's tint base. Structurally it reads as the *gap*, not the page. - **Off-White** (`{colors.canvas-tertiary}` — #f5f5f7): The signature Apple grey and the true page canvas — every marketing tile and the footer. If one value identifies this design language, it is this one. - **Pearl** (`{colors.canvas-secondary}` — #fafafc): A near-white used for tonal buttons that must still read as objects against white. - **Black** (`{colors.surface-black}` — #000000): Dark tiles. Apple goes to pure black, not a soft near-black, and pairs it with `{colors.on-dark}` (#f5f5f7) text rather than pure white. - **Dark Elevated** (`{colors.surface-dark-secondary}` — #161617 / `{colors.surface-dark-tertiary}` — #1d1d1f): Container steps inside dark contexts — the opened nav panel, dark card fills. - **Translucent Chip** (`{colors.chip-translucent}` — rgba(210, 210, 215, 0.64)): The circular carousel controls floating over imagery on the store. ### Text - **Ink** (`{colors.ink}` — #1d1d1f): Every headline and every body paragraph on light surfaces. Never pure black — pure black is a *surface* here, not a text color. - **Ink Secondary** (`{colors.ink-secondary}` — #6e6e73): Sub-labels, eyebrow text, secondary meta. - **Ink Tertiary** (`{colors.ink-tertiary}` — #86868b): Disabled text and legal fine print. - **Ink Quaternary** (`{colors.ink-quaternary}` — #424245): Body text that needs slightly more weight than secondary without going to full Ink. - **On Dark** (`{colors.on-dark}` — #f5f5f7): All text on black tiles. Note the symmetry — the light canvas and the dark-surface text are the same hex. ### Hairlines & Borders - **Hairline** (`{colors.hairline}` — #d2d2d7): The 1px rule on store cards and chips. On the marketing tiles it does not appear at all. - **Hairline Soft** (`{colors.hairline-soft}` — #e8e8ed): Quaternary fills and the softest separators. Both are also published as alpha pairs (`rgba(0,0,0,.16)` / `rgba(0,0,0,.08)`) for use over photography. ### Brand Gradient **No decorative gradients.** No gradient token exists anywhere in the system. Atmosphere is supplied entirely by product photography. This is unusual for a premium brand site and is a defining constraint: if a surface needs depth, it gets a photograph or a surface-color change, never a ramp. ## Typography ### Font Family - **Display**: `SF Pro Display, system-ui, -apple-system, sans-serif` — all type at **19px and above**. - **Body / UI**: `SF Pro Text, system-ui, -apple-system, sans-serif` — all type at **17px and below**. - The 19px/17px boundary is a real switch, not a preference: the same semantic step renders in Display at 19px on desktop and in Text at 17px once a breakpoint shrinks it. ### Hierarchy | Token | Size | Weight | Line Height | Letter Spacing | Use | |---|---|---|---|---|---| | `{typography.store-hero}` | 80px | 600 | 1.05 | -0.015em | Store landing hero — the largest step in the system | | `{typography.tile-headline}` | 56px | 600 | 1.07143 | -0.005em | Marketing tile headline | | `{typography.headline}` | 48px | 600 | 1.08349 | -0.002em | Section headline; tile headline at ≤1068px | | `{typography.promo-headline}` | 40px | 600 | 1.1 | 0em | Half-width promo tile headline | | `{typography.callout}` | 32px | 600 | 1.125 | 0.002em | Sub-section callout | | `{typography.tile-subhead}` | 28px | 400 | 1.14286 | 0.007em | Tile subhead, one line under the headline | | `{typography.promo-subhead}` | 21px | 400 | 1.19048 | 0.011em | Promo tile subhead | | `{typography.tile-callout}` | 19px | 400 | 1.21053 | 0.012em | Smallest Display step — the last one before the face switches | | `{typography.body}` | 17px | 400 | 1.47059 | -0.022em | Default paragraph, nav links, large button labels | | `{typography.body-reduced}` | 14px | 400 | 1.42859 | -0.016em | Default button label, secondary copy | | `{typography.caption}` | 12px | 400 | 1.33337 | -0.01em | Footer, fine print | | `{typography.label-promo}` | 12px | 600 | 1.33337 | -0.01em | Store promo eyebrow, set in `{colors.accent-orange}` | ### Principles - **Tracking crosses zero, twice.** In the Display range it starts negative and opens up as size falls: −0.005em (56px) → −0.002em (48px) → 0 (40px) → +0.002em (32px) → +0.007em (28px) → +0.012em (19px). At 17px the face changes to Text and tracking snaps back to −0.022em, tightening again through 14px (−0.016em) and 12px (−0.01em). A single global `letter-spacing` destroys this. - **Two weights only.** 600 for headlines and the promo label, 400 for everything else. There is no 500 in the system; when a step needs more presence it changes size, not weight. - **Line-height is inverse to size.** 1.05–1.14 across the Display range, 1.47 for body. Headlines are set tight enough to read as a block; paragraphs are set loose enough to read as prose. - **Body is 17px, not 16px.** The extra pixel is deliberate and sets the reading pace of the site. - **The 19px threshold is a hard rule.** Display at 19px and up, Text at 17px and down. A 17px headline in Display looks subtly wrong, and Apple never ships one. ### Note on Font Substitutes SF Pro is not licensed for third-party web use; Apple serves it only from its own domain. - Lead every stack with `-apple-system, BlinkMacSystemFont, system-ui` — on Apple hardware this resolves to genuine SF Pro and costs nothing. - For other platforms, **Inter** (Google Fonts, variable) is the closest free equivalent. Load weights 400 and 600 only. - Inter runs slightly wider than SF Pro at display sizes: subtract a further **−0.01em** from the tracking values above when Inter is the resolved face. - Inter's x-height is taller: reduce body line-height from **1.47 to ~1.44** so paragraphs keep the same density. - Do not substitute a geometric sans (Poppins, Montserrat). The neutral-grotesque skeleton is what makes the tight display tracking legible. ## Layout ### Spacing System - **Base unit:** 8px, with a heavily used 4px half-step. The measured distribution is dominated by 4 / 6 / 8 / 12 / 14 / 15 / 16, with 48 and 39 appearing as structural tile padding. - **Tokens:** `{spacing.xxs}` 4px · `{spacing.xs}` 8px · `{spacing.sm}` 12px · `{spacing.md}` 16px · `{spacing.cta}` 17px · `{spacing.lg}` 24px · `{spacing.xl}` 32px · `{spacing.xxl}` 48px · `{spacing.section}` 80px. - **Tile padding:** `{spacing.tile-top}` 48px top / `{spacing.tile-bottom}` 56px bottom at desktop, stepping to 54/61 at ≤1068px, 39/43 at ≤734px, and 56/63 on tall desktop viewports. - **Tile gutter:** `{spacing.sm}` (12px) — the single most important spacing value in the system, used both as grid `gap` and as the section `margin-bottom`. - **Copy rhythm:** headline → 6px → subhead → `{spacing.cta}` (17px) → CTA row, with 17px between adjacent buttons. ### Grid & Container - **Max content widths:** 1024px for the global nav, 980px for the footer, ~570px for a tile's copy block. Tiles themselves are unbounded and run full-bleed to a 2560px ceiling. - **Column patterns:** marketing sections are a 1-column or 2-column grid of tiles with a 12px gap; store shelves are horizontal scrollers of ~136px cards rather than a wrapping grid. - **Side padding:** 22px on nav and footer content — the one consistent horizontal inset. ### Whitespace Philosophy Whitespace here is vertical and structural, not marginal. A tile reserves 48–56px above and below its content regardless of how little content there is, so a one-line headline and a full product render occupy the same band height. Horizontally the copy is capped near 570px and centered, which means the air grows as the viewport does. The result reads as a gallery: fixed frames, generous mats, content centered in each. ## Elevation & Depth | Level | Treatment | Use | |---|---|---| | Flat | No shadow, no border | Tiles, nav, footer, all marketing surfaces | | Product shadow | `rgba(0, 0, 0, 0.22) 3px 5px 30px 0` | Product renders resting on a tile — marketing only | | Card shadow | `rgba(0, 0, 0, 0.08) 2px 4px 12px 0` | Store product cards and shelf items — catalog only | | Backdrop blur | `saturate(1.8) blur(20px)` over 80% white | The global nav, and only the global nav | | Hairline | 1px `{colors.hairline}` | Store cards and chips | **Shadow philosophy.** Shadow is a property of *objects*, not of interface. On marketing surfaces there is exactly one shadow and it belongs to the photographed product, giving it weight against the tile. On the store, a second and much lighter shadow appears on product cards — a catalog needs its items to read as pickable objects. Neither shadow is ever applied to a button, a text block, or a tile. Separation between sections comes from the surface change and the 12px gutter. ### Decorative Depth - **Surface alternation** (off-white ↔ black) is the primary rhythm device and replaces dividers. - **Backdrop blur** appears once, on the nav, and is functional: it keeps the bar legible over whatever scrolls beneath it. - **No gradients, no glows, no strokes as decoration.** ## Shapes ### Border Radius Scale | Token | Value | Use | |---|---|---| | `{rounded.none}` | 0px | Tiles, all imagery, all marketing containers | | `{rounded.xs}` | 5px | Small inline chips and inputs | | `{rounded.sm}` | 8px | `{component.button-block}`, inline card imagery, flyout panels | | `{rounded.md}` | 11px | Media controls | | `{rounded.lg}` | 18px | Store product cards — the dominant radius on the catalog surface | | `{rounded.xl}` | 36px | `{component.paddlenav-arrow}` (45px circle at a 36px radius) | | `{rounded.pill}` | 980px | **Every button.** Literally 980px, not 9999px | | `{rounded.full}` | 50% | Dot navigation | The census is unambiguous: on the homepage `{rounded.pill}` accounts for 32 of the rounded elements and everything else is a handful; on the store `{rounded.lg}` takes over with 75 uses. Radius tells you which surface you are on. ### Media Geometry - Product imagery is **square-cornered and full-bleed** within its tile — `border-radius: 0`, `object-fit: cover`. - Marketing tiles are `min-height: 580px` with the copy stack in the top 48px and the render below. - Store card imagery is a 1:1 crop inside an `{rounded.lg}` card. - Responsive `srcset` throughout; below-fold imagery lazy-loads, the hero loads eagerly. ## Components ### Top Navigation **`global-nav`** — 44px fixed bar, `rgba(255, 255, 255, 0.8)` with `backdrop-filter: saturate(1.8) blur(20px)`. Content capped at 1024px with 22px side padding. Links are `{typography.body}` (17px / 400) at `rgba(0, 0, 0, 0.8)`, the wordmark at weight 600. Link transition is `color 0.32s cubic-bezier(0.4, 0, 0.6, 1)`. The dark variant swaps the tint base to `{colors.surface-dark-secondary}` at the same opacity. Collapses to a hamburger at ≤833px. ### Buttons All buttons are `{rounded.pill}` with a 1px transparent border reserved so bordered variants do not shift. Minimum width is computed as `min-width-basis − 2 × horizontal-padding`. **`button-primary`** — The default. Background `{colors.primary}`, text `{colors.on-primary}` in `{typography.body-reduced}` (14px / 400), padding 9px × 16px, min-width basis 60px. - Active state: `{component.button-primary-active}` — background `#006EDB`. - Focus state: 2px outline in `{colors.primary}`, offset 1px. **`button-elevated`** — The tile CTA. Same fill, `{typography.body}` (17px), padding 12px × 22px, min-width basis 70px. This is the size that appears under a tile headline. **`button-super`** — The store hero CTA. `{typography.body}` (17px), padding 18px × 31px, min-width basis 90px. Used once per surface at most. **`button-reduced`** — Compact utility. `{typography.caption}` (12px), padding 4px × 11px, min-width basis 45px. **`button-secondary`** — The second CTA in a pair ("Buy" beside "Learn more"). Transparent fill, text and 1px border both `{colors.primary-link}`. On press it fills to `#006EDB` with white text — the border variant is a resting state, not a permanent style. **`button-neutral`** — Background `{colors.ink}`, white text. Used where blue would compete with imagery. Press moves to `#272729`. **`button-block`** — The single exception to the pill: full width at `{rounded.sm}` (8px). ### Cards & Containers **`tile-light`** — The core unit. Background `{colors.canvas-tertiary}`, `min-height: 580px`, padding `48px 0 56px`, `border-radius: 0`, `overflow: clip`. Contains a centered `{component.tile-copy}` capped near 570px, then a full-bleed product render. **`tile-dark`** — Identical geometry on `{colors.surface-black}` with `{colors.on-dark}` text. Applied per tile, so a black tile can sit directly beside an off-white one in the same grid row. **`tile-copy`** — Headline in `{typography.tile-headline}` → 6px → subhead in `{typography.tile-subhead}` → `{spacing.cta}` → `{component.tile-ctas}`, all centered. **`tile-ctas`** — Flex row, `gap: {spacing.cta}` (17px), centered. Conventionally one `{component.button-elevated}` plus one `{component.button-secondary}`. **`store-product-card`** — The catalog unit, and the only place cards exist. White fill, `{rounded.lg}` (18px), padding `18px 8px 16px`, carrying the lighter card shadow. Arranged in horizontal scroller shelves rather than a wrapping grid. **`paddlenav-arrow`** — 45px circular control over the scrollers, `{colors.chip-translucent}` fill, `{rounded.xl}`. ### Inputs & Forms Only the store's search field surfaced in the analyzed pages: 40px tall, transparent fill, no border, asymmetric padding (`0 38px 0 42px`) to clear a leading glyph and a trailing clear button. Field styling is otherwise carried by the container, not the input. Validation, error and disabled form states were not surfaced — see `## Known Gaps`. ### Footer **`footer`** — Background `{colors.canvas-tertiary}`, content capped at 980px with 22px side padding, vertical padding `37px … 11px`. Body copy in `{typography.caption}` (12px / 400) at `rgba(0, 0, 0, 0.56)`; links at `rgba(0, 0, 0, 0.72)`; column headings 12px / 400 at `rgba(0, 0, 0, 0.88)`. The footer is the one deliberately dense region of the site. ## Do's and Don'ts ### Do - Build the page as a stack of full-bleed tiles separated by `{spacing.sm}` (12px) of white; let the surface change be the divider. - Give every tile `min-height: 580px` and `48px / 56px` vertical padding, even when the content is short. - Switch faces at the 19px boundary — `{typography.tile-callout}` and above in Display, `{typography.body}` and below in Text. - Apply the tracking value from the table for each step; it changes sign across the ladder. - Keep the hierarchy in 600 and 400 only. - Reserve `{rounded.pill}` for actions and `{rounded.none}` for tiles and media; use `{rounded.lg}` only on catalog cards. - Pair `{component.button-elevated}` with `{component.button-secondary}` for the standard two-CTA row. - Animate with `cubic-bezier(0.4, 0, 0.6, 1)` at 0.24–0.32s, on color and opacity. - Put `.theme-dark` on the tile, not the page, so light and dark tiles can be adjacent. ### Don't - Don't wrap tiles in a centered max-width container — only the copy inside is width-capped. - Don't round tiles or imagery; radius belongs to actions and catalog cards. - Don't add shadows to buttons, tiles, or text — shadow is for photographed objects. - Don't introduce a weight 500, or a second accent colour beyond the promo orange label. - Don't apply a single global `letter-spacing`; the sign flips across the scale. - Don't invert `{colors.primary}` on dark surfaces — the blue is identical on white and black. - Don't reach for a gradient. No gradient token exists in this system. - Don't use `{colors.primary-on-dark}` on light surfaces, or `{colors.primary-link}` on dark ones. ## Responsive Behavior ### Breakpoints | Name | Width | Key Changes | |---|---|---| | Small phone | ≤ 480px | Single column; tightest tile padding | | Phone | ≤ 640px | Tile headline at 32px; subhead at 19px | | Large phone | ≤ 734px | Tile padding 39px / 43px; Display steps take their smallest values | | Tablet | 735–833px | Two-up tiles collapse to one column; nav collapses to hamburger at 833px | | Tablet landscape | 834–1023px | Nav returns; tile padding 54px / 61px | | Small desktop | 1024–1068px | Nav content locks at 1024px; headline at 48px | | Desktop | 1069–1440px | Full ladder: tile headline 56px; tile padding 48px / 56px, or 56px / 63px when the viewport is ≥776px tall | | Wide | ≥ 1441px | Tiles keep running full-bleed to a 2560px ceiling; content caps hold | Tile padding is additionally keyed to viewport **height**, not just width — a tall desktop viewport gets 56px / 63px where a short one gets 48px / 56px. ### Touch Targets - The global nav is 44px tall, and `{component.paddlenav-arrow}` is a 45px circle — both at or above the 44px minimum. - `{component.button-elevated}` lands near 44px tall at 12px vertical padding on 17px text. - `{component.button-primary}` at 9px padding on 14px text is below 44px; it is a desktop-density control and should be upgraded to `{component.button-elevated}` on touch surfaces. ### Collapsing Strategy - **Global nav:** full link row → hamburger at ≤833px. - **Tiles:** two-up grid → single column at ≤734px; the 12px gutter is preserved in both. - **Type:** the ladder steps down at 1068px and again at 734px; `{typography.tile-callout}` crosses the face boundary into SF Pro Text on the way. - **Store shelves:** horizontal scrollers keep scrolling rather than reflowing. ### Image Behavior - Responsive `srcset` with breakpoint-matched crops throughout. - Product renders keep their aspect ratio and scale within the tile; the tile height is the constant. - Below-fold media lazy-loads; the first tile's media loads eagerly. ## Iteration Guide 1. Work on one component at a time and address it by its YAML key (`{component.tile-dark}`, `{component.store-product-card}`). 2. Variants live as their own `components:` entries with a suffix (`-active`, `-secondary`, `-reduced`). 3. Use `{token.refs}` everywhere in prose and CSS; never inline a hex once a token exists for it. 4. Document default and active/pressed only. Never document hover. 5. The 19px Display/Text boundary and the per-step tracking values are not adjustable — they are the design language. 6. Before adding any chrome to create emphasis, change the surface instead: off-white tile → black tile. 7. Shadows are only ever attached to photographed objects (marketing) or catalog cards (store) — never to buttons, tiles, or text. ## Known Gaps - **Form states are undocumented.** Only the store's search field surfaced; validation, error, disabled and focus-within states for real inputs were not observable on the analyzed pages. - **Product detail and configurator surfaces were not analyzed.** The option chips, price summaries and sticky purchase bars on a buy page are outside this pass; expect additional components there. - **Dark-mode catalog variants were not surfaced.** The store was observed in its light default; `{colors.surface-dark-secondary}` and `{colors.surface-dark-tertiary}` are published tokens but their catalog application is unverified. - **The `{spacing}` scale is derived, not declared.** Apple publishes no spacing tokens; the values here are the dominant measured values plus the explicit tile and gutter constants. Treat the mid-scale (16 / 24 / 32) as inference and the tile values (12 / 48 / 56) as measured. - **Motion beyond easing and duration is unverified.** The signature curve and its 0.24–0.32s durations are measured; scroll-triggered reveal choreography on long marketing pages was not instrumented. - **SF Pro cannot be used off Apple platforms.** Every rendering outside Apple hardware is a substitution; the tracking and leading deltas in the substitutes note are required, not optional.