---
version: alpha
name: Shot on iPhone
description: Editorial monochrome photography portfolio — a pure achromatic system where black-and-white imagery IS the design. Near-white canvas, near-black ink, generous gallery whitespace, and a clean geometric sans set in restrained weights. No color, no chrome, no distraction from the photograph.

colors:
  # Canvas + ink
  background: "#ffffff"
  surface: "#ffffff"
  surface-soft: "#fafafa"
  ink: "#0a0a0a"
  ink-pure: "#000000"

  # Neutral scale (achromatic only)
  gray-900: "#1a1a1a"
  gray-700: "#404040"
  gray-600: "#525252"
  gray-500: "#737373"
  gray-400: "#a3a3a3"
  gray-300: "#d4d4d4"
  gray-200: "#e5e5e5"
  gray-100: "#ebebeb"
  gray-50: "#f5f5f5"

  # Interactive
  primary: "#0a0a0a"          # buttons / active view-mode pill = ink
  link: "#0a0a0a"
  border: "#e5e5e5"
  focus-ring: "#737373"

  # On-color
  on-primary: "#ffffff"
  on-ink: "#ffffff"

typography:
  display-hero:
    fontFamily: "Inter, -apple-system, Helvetica Neue, Arial, sans-serif"
    fontSize: 44px
    fontWeight: 600
    lineHeight: 1.10
    letterSpacing: -1.2px
  section-heading:
    fontFamily: "Inter, -apple-system, Helvetica Neue, Arial, sans-serif"
    fontSize: 32px
    fontWeight: 600
    lineHeight: 1.20
    letterSpacing: -0.8px
  sub-heading:
    fontFamily: "Inter, -apple-system, Helvetica Neue, Arial, sans-serif"
    fontSize: 22px
    fontWeight: 500
    lineHeight: 1.30
    letterSpacing: -0.4px
  card-title:
    fontFamily: "Inter, -apple-system, Helvetica Neue, Arial, sans-serif"
    fontSize: 18px
    fontWeight: 600
    lineHeight: 1.40
    letterSpacing: -0.2px
  body-large:
    fontFamily: "Inter, -apple-system, Helvetica Neue, Arial, sans-serif"
    fontSize: 19px
    fontWeight: 400
    lineHeight: 1.70
    letterSpacing: 0px
  body:
    fontFamily: "Inter, -apple-system, Helvetica Neue, Arial, sans-serif"
    fontSize: 16px
    fontWeight: 400
    lineHeight: 1.60
    letterSpacing: 0px
  body-medium:
    fontFamily: "Inter, -apple-system, Helvetica Neue, Arial, sans-serif"
    fontSize: 16px
    fontWeight: 500
    lineHeight: 1.50
    letterSpacing: 0px
  button-ui:
    fontFamily: "Inter, -apple-system, Helvetica Neue, Arial, sans-serif"
    fontSize: 14px
    fontWeight: 500
    lineHeight: 1.40
    letterSpacing: 0px
  caption:
    fontFamily: "Inter, -apple-system, Helvetica Neue, Arial, sans-serif"
    fontSize: 13px
    fontWeight: 400
    lineHeight: 1.40
    letterSpacing: 0.2px

spacing:
  xs: 4px
  sm: 8px
  md: 12px
  lg: 16px
  xl: 24px
  2xl: 40px
  3xl: 64px
  4xl: 96px

rounded:
  none: 0px
  xs: 4px
  sm: 6px
  md: 8px
  lg: 12px
  full: 9999px

components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.button-ui}"
    rounded: "{rounded.full}"
    padding: 8px 16px

  button-ghost:
    backgroundColor: "{colors.background}"
    textColor: "{colors.ink}"
    typography: "{typography.button-ui}"
    rounded: "{rounded.full}"
    padding: 8px 16px
    borderColor: "{colors.border}"

  view-mode-pill:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.button-ui}"
    rounded: "{rounded.full}"
    padding: 6px 14px

  view-mode-pill-inactive:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.gray-600}"
    typography: "{typography.button-ui}"
    rounded: "{rounded.full}"
    padding: 6px 14px

  avatar:
    backgroundColor: "{colors.gray-100}"
    rounded: "{rounded.full}"
    width: 256px
    height: 256px

  photo-tile:
    backgroundColor: "{colors.gray-50}"
    rounded: "{rounded.none}"
    borderColor: "{colors.border}"

  card:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    rounded: "{rounded.md}"
    padding: 24px
    borderColor: "{colors.border}"

  nav-bar:
    backgroundColor: "{colors.background}"
    textColor: "{colors.ink}"
    typography: "{typography.button-ui}"
    padding: 16px 24px
    borderColor: "{colors.border}"

  link-inline:
    textColor: "{colors.link}"
    typography: "{typography.body}"
---

# Shot on iPhone Design System

## Overview

Shot on iPhone is a personal monochrome photography portfolio where the design system gets out of the way almost entirely. The site is overwhelmingly white (`{colors.background}`) with near-black ink (`{colors.ink}`), and that achromatic restraint is deliberate — when every photograph on the page is black and white, any introduced hue would fight the work. The interface is a frame, not a subject. It exists to hold the image and then disappear.

The result is editorial in the truest sense: generous whitespace, a single clean geometric sans-serif, and a strict grayscale neutral scale running from near-black ink down through `{colors.gray-500}` muted captions to the `{colors.gray-50}` tile backgrounds that hold loading photographs. There is no accent color, no gradient, no decorative shadow. Depth and separation come from spacing and thin `{colors.border}` hairlines alone.

Interaction is minimal and unobtrusive. The site offers a few viewing modes — Flow, Grid, Map — surfaced as small pill toggles where the active mode fills with ink (`{colors.primary}`) and inactive modes sit quiet in `{colors.gray-600}`. Buttons are fully rounded pills in the same ink-on-white / white-on-ink logic. A large circular avatar anchors the about section. Everything else is photograph and breathing room.

Typography is set in a modern geometric sans (Inter, falling back to the system stack) in three weights: 400 for reading, 500 for UI and emphasis, 600 for headings. Display sizes pull in slightly with negative tracking for a tighter editorial headline, while body copy relaxes to comfortable 1.6–1.7 line-height for long-form narrative passages.

**Key Characteristics:**
- Pure achromatic palette — grayscale only, from `{colors.ink}` to `{colors.background}`, no hue anywhere
- Black-and-white photography IS the design; chrome is intentionally invisible
- Inter / system geometric sans in three strict weights (400 / 500 / 600)
- Generous gallery whitespace; separation by spacing and thin hairlines, not shadows
- Fully-rounded pill buttons and view-mode toggles (ink-fill when active)
- Large circular avatar for the about/identity section
- Negative letter-spacing on headlines for a compressed editorial feel
- Square, edge-to-edge photo tiles with subtle `{colors.gray-50}` loading backgrounds

## Colors

### Primary
- **Ink** (`{colors.ink}`): Primary text, headings, active pills, buttons. Near-black, not pure black.
- **Pure White** (`{colors.background}`): Page background, card surfaces, text on ink.
- **True Black** (`{colors.ink-pure}`): Reserved for deepest contrast moments and photo mattes.

### Neutral Scale (achromatic)
- **Gray 900** (`{colors.gray-900}`): Strong secondary headings.
- **Gray 700** (`{colors.gray-700}`): Secondary body text.
- **Gray 600** (`{colors.gray-600}`): Inactive view-mode labels, muted UI text.
- **Gray 500** (`{colors.gray-500}`): Captions, metadata, tertiary text.
- **Gray 400** (`{colors.gray-400}`): Placeholder, disabled.
- **Gray 300 / 200** (`{colors.gray-300}` / `{colors.gray-200}`): Dividers, hairlines.
- **Gray 100 / 50** (`{colors.gray-100}` / `{colors.gray-50}`): Photo-tile loading backgrounds, subtle surface tint.

### Interactive
- **Primary** (`{colors.primary}`): Ink-fill for active buttons and pills.
- **Link** (`{colors.link}`): Inline links in ink (underlined on hover).
- **Border** (`{colors.border}`): Hairline borders on tiles, cards, nav.
- **Focus Ring** (`{colors.focus-ring}`): Keyboard focus indication.

## Typography

### Font Family
- **Primary**: `Inter`, with fallbacks `-apple-system, Helvetica Neue, Arial, sans-serif`
- A single geometric sans carries the entire system — no serif, no mono.

### Hierarchy

The complete type scale lives in the `typography:` token block above. Reference tokens directly (`{typography.display-hero}`, `{typography.body}`, etc.).

| Token | Use |
|---|---|
| `display-hero` | Page / name hero |
| `section-heading` | Section titles |
| `sub-heading` | Sub-sections |
| `card-title` | Card / about headings |
| `body-large` | Lead narrative passages |
| `body` | Standard reading text |
| `body-medium` | Emphasized UI text |
| `button-ui` | Buttons, pills, nav links |
| `caption` | Photo captions, metadata |

### Principles
- **One typeface, three weights**: 400 reads, 500 interacts, 600 announces. No bold beyond 600.
- **Tighten the headline**: Display and section headings use negative tracking (-0.8px to -1.2px) for a compressed editorial feel; body relaxes to neutral tracking.
- **Long-form comfort**: Narrative passages use 1.6–1.7 line-height for relaxed reading.
- **Quiet UI**: All interface text is small (13–14px) and stays out of the photograph's way.

## Layout

### Spacing System
The complete scale lives in the `spacing:` token block above. Base rhythm is 8px. Notable: large jumps to `{spacing.3xl}` (64px) and `{spacing.4xl}` (96px) for the gallery's generous vertical breathing room.

### Grid & Container
- Centered single-column for narrative; full-width or near-full-width for the photo gallery.
- Multiple gallery modes: **Flow** (vertical stream), **Grid** (uniform tiles), **Map** (geolocated).
- Photo tiles are edge-to-edge with minimal gutter.

### Whitespace Philosophy
- **Gallery emptiness**: Massive vertical padding around image groups (`{spacing.3xl}`–`{spacing.4xl}`).
- **Separation without lines**: Spacing does most of the dividing work; thin `{colors.border}` hairlines only where structurally needed.
- **No background variation**: Depth comes from whitespace and the photographs themselves, never from colored panels.

## Elevation & Depth

| Level | Treatment | Use |
|---|---|---|
| Flat (Level 0) | No shadow | Page background, text, photo tiles |
| Hairline (Level 1) | `1px solid {colors.border}` | Card, nav, tile separation |
| Focus | `2px solid {colors.focus-ring}` outline | Keyboard focus |

**Shadow Philosophy**: There is effectively no shadow system. The aesthetic is flat and editorial — the photographs supply all the visual weight, and the UI stays paper-flat behind them. Any elevation is communicated by a single hairline, never a drop shadow.

## Shapes

| Token | Value | Use |
|---|---|---|
| `none` | 0px | Photo tiles (square, sharp) |
| `xs` | 4px | Small inline elements |
| `sm` | 6px | Inputs |
| `md` | 8px | Cards |
| `lg` | 12px | Larger containers |
| `full` | 9999px | Pills, buttons, avatar |

## Components

The full component spec lives in the `components:` token block above. Reference tokens directly (`{components.button-primary}`, `{components.view-mode-pill}`).

### Buttons & Pills
- **`button-primary`** — Ink fill, white text, full pill.
- **`button-ghost`** — White with `{colors.border}` hairline, ink text, full pill.
- **`view-mode-pill`** / **`view-mode-pill-inactive`** — Flow / Grid / Map toggle. Active fills ink; inactive is quiet gray text on white.

### Media
- **`avatar`** — 256px circular profile image, `{rounded.full}`.
- **`photo-tile`** — Square, sharp-cornered (`{rounded.none}`), `{colors.gray-50}` loading background, optional hairline.

### Cards & Nav
- **`card`** — White surface, hairline border, 8px radius, generous padding.
- **`nav-bar`** — White, hairline bottom border, small 14px UI text.

### Links
- **`link-inline`** — Ink text, underline on hover. No accent-colored links anywhere.

## Do's and Don'ts

### Do
- Keep the palette strictly achromatic — grayscale from `{colors.ink}` to `{colors.background}`.
- Let the photographs carry all visual weight; keep chrome invisible.
- Use full-pill radius for buttons and view-mode toggles.
- Fill the active view-mode pill with ink; keep inactive ones quiet gray.
- Use generous whitespace for separation instead of borders or panels.
- Set everything in one geometric sans across three weights.

### Don't
- Don't introduce any hue — color fights black-and-white photography.
- Don't add drop shadows; the system is paper-flat.
- Don't use weight 700+ on text — 600 is the heading ceiling.
- Don't round the photo tiles — they stay square and sharp.
- Don't crowd the gallery; whitespace IS the design.
- Don't make UI text large or attention-grabbing — it should recede behind the image.

---

## Responsive Behavior

### Breakpoints
| Name | Width | Key Changes |
|------|-------|-------------|
| Mobile | <600px | Single-column gallery, stacked narrative, tighter padding |
| Tablet | 600–1024px | 2-column grid mode, expanded padding |
| Desktop | 1024–1400px | Full multi-column grid, generous margins |
| Large | >1400px | Centered content, maximum gallery breathing room |

### Touch Targets
- Pills and buttons use comfortable 6–8px vertical padding.
- View-mode toggles sized for easy tapping on mobile.

### Collapsing Strategy
- Gallery: multi-column grid → 2-column → single column.
- Narrative: comfortable measure maintained; padding tightens on mobile.
- View-mode pills: stay inline, may wrap on narrow screens.
- Avatar: scales down proportionally on mobile.

### Image Behavior
- Next.js responsive images (`w=3840&q=75`) serve appropriate resolution per viewport.
- Photo tiles maintain aspect ratio; gallery reflows column count by width.
- Loading state shows `{colors.gray-50}` placeholder background.

---

## Agent Prompt Guide

### Quick Color Reference
- Primary CTA: Ink `{colors.ink}`
- Background: Pure White `{colors.background}`
- Heading text: Ink `{colors.ink}`
- Body text: Gray 700 `{colors.gray-700}`
- Caption text: Gray 500 `{colors.gray-500}`
- Border: `1px solid {colors.border}`
- Active pill: Ink fill `{colors.primary}`, white text

### Example Component Prompts
- "Create a hero on white background. Name at 44px Inter weight 600, letter-spacing -1.2px, color `{colors.ink}`. Tagline at 19px weight 400, color `{colors.gray-700}`, line-height 1.7."
- "Build a view-mode toggle: three full-pill segments (Flow / Grid / Map). Active = ink fill `{colors.primary}` + white 14px Inter weight 500. Inactive = white + `{colors.gray-600}` text. 6px 14px padding."
- "Design a monochrome photo grid: square tiles, no radius, 8px gutter, `{colors.gray-50}` loading background, optional 1px `{colors.border}` hairline. Reflow 4 → 2 → 1 columns."
- "Create an about block: 256px circular avatar `{rounded.full}`, name at 32px Inter weight 600 letter-spacing -0.8px, long-form bio at 16px weight 400 line-height 1.6 in `{colors.gray-700}`."

### Iteration Guide
1. Stay achromatic — never add a hue; the photographs are black and white.
2. Use whitespace, not shadows or panels, to separate sections.
3. Three weights only: 400 read, 500 interact, 600 announce.
4. Full-pill radius for buttons/toggles; square sharp corners for photos.
5. Keep all UI text small and quiet so the image stays the subject.

---

## Attribution

Independent design analysis from [Design Swatches](https://designmd.santiagoalonso.com) by [Santiago Alonso](https://santiagoalonso.com). Based on publicly observable interface patterns. Not affiliated with or endorsed by Shot on iPhone. Brand names and trademarks belong to their respective owners.
