---
version: alpha
name: Logan Liffick
description: Quiet engineered minimalism — a near-black canvas with Inter at medium weight, a strict neutral grayscale (Tailwind base scale) softened by two pastel accents (warm orange, mint green), hairline borders, and gentle 2px–12px radii. The personal site of a Vercel design engineer, restrained to the point of being almost monochrome.
colors:
  # Canvas + ink (dark default)
  background: "#0a0a0a"
  surface: "#171717"
  surface-soft: "#262626"
  ink: "#fafafa"
  ink-strong: "#ffffff"
  ink-secondary: "#a1a1a1"
  ink-muted: "#525252"

  # Borders / hairlines (flattened over the #0a0a0a canvas)
  border: "#262626"
  border-soft: "#1f1f1f"        # white/8% over near-black

  # Neutral scale (Tailwind base / neutral)
  neutral-50: "#fafafa"
  neutral-100: "#f5f5f5"
  neutral-200: "#e5e5e5"
  neutral-300: "#d4d4d4"
  neutral-400: "#a1a1a1"
  neutral-500: "#737373"
  neutral-600: "#525252"
  neutral-700: "#404040"
  neutral-800: "#262626"
  neutral-900: "#171717"
  neutral-950: "#0a0a0a"

  # Pastel accents — sparingly, for tags / highlights
  accent-orange: "#ffd7a8"
  accent-green: "#b9f8cf"

  # Interactive
  primary: "#fafafa"            # inverted CTA: light fill on dark canvas
  on-primary: "#0a0a0a"
  hover-surface: "#262626"      # white/25% intent, flattened
  selection: "#404040"

  # On-color
  on-ink: "#0a0a0a"

typography:
  display-hero:
    fontFamily: "Inter, Inter Fallback, ui-sans-serif, system-ui, sans-serif"
    fontSize: 40px
    fontWeight: 500
    lineHeight: 1.10
    letterSpacing: -1.2px
  page-title:
    fontFamily: "Inter, Inter Fallback, sans-serif"
    fontSize: 28px
    fontWeight: 500
    lineHeight: 1.20
    letterSpacing: -0.7px
  section-heading:
    fontFamily: "Inter, Inter Fallback, sans-serif"
    fontSize: 20px
    fontWeight: 500
    lineHeight: 1.30
    letterSpacing: -0.4px
  card-title:
    fontFamily: "Inter, Inter Fallback, sans-serif"
    fontSize: 16px
    fontWeight: 500
    lineHeight: 1.40
    letterSpacing: -0.2px
  body-large:
    fontFamily: "Inter, Inter Fallback, sans-serif"
    fontSize: 18px
    fontWeight: 400
    lineHeight: 1.65
    letterSpacing: 0px
  body:
    fontFamily: "Inter, Inter Fallback, sans-serif"
    fontSize: 16px
    fontWeight: 400
    lineHeight: 1.60
    letterSpacing: 0px
  body-small:
    fontFamily: "Inter, Inter Fallback, sans-serif"
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.50
    letterSpacing: 0px
  ui-label:
    fontFamily: "Inter, Inter Fallback, sans-serif"
    fontSize: 14px
    fontWeight: 500
    lineHeight: 1.43
    letterSpacing: 0px
  caption:
    fontFamily: "Inter, Inter Fallback, sans-serif"
    fontSize: 13px
    fontWeight: 400
    lineHeight: 1.40
    letterSpacing: 0px
  mono-label:
    fontFamily: "var(--font-mono), ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"
    fontSize: 13px
    fontWeight: 400
    lineHeight: 1.40
    letterSpacing: 0px

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

rounded:
  none: 0px
  xs: 2px
  sm: 4px
  md: 6px
  lg: 8px
  xl: 12px
  pill: 9999px

components:
  # Primary inverted CTA — light fill on dark canvas
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.ui-label}"
    rounded: "{rounded.lg}"
    padding: 8px 16px
  button-primary-hover:
    backgroundColor: "{colors.neutral-200}"
    textColor: "{colors.on-primary}"
    typography: "{typography.ui-label}"
    rounded: "{rounded.lg}"
    padding: 8px 16px

  # Ghost button — transparent with hairline border
  button-ghost:
    backgroundColor: "{colors.background}"
    textColor: "{colors.ink}"
    typography: "{typography.ui-label}"
    rounded: "{rounded.lg}"
    padding: 8px 16px
    borderColor: "{colors.border}"
  button-ghost-hover:
    backgroundColor: "{colors.hover-surface}"
    textColor: "{colors.ink}"
    typography: "{typography.ui-label}"
    rounded: "{rounded.lg}"
    padding: 8px 16px
    borderColor: "{colors.border}"

  # Icon button — social / nav
  button-icon:
    backgroundColor: "{colors.background}"
    textColor: "{colors.ink-secondary}"
    rounded: "{rounded.md}"
    padding: 8px
    width: 36px
    height: 36px

  # Text link — quiet, underline on hover
  link:
    textColor: "{colors.ink}"
    typography: "{typography.body}"
  link-muted:
    textColor: "{colors.ink-secondary}"
    typography: "{typography.body-small}"

  # Card — surface lift, hairline border
  card:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    rounded: "{rounded.xl}"
    padding: 20px
    borderColor: "{colors.border}"

  # List row — entries (writing, projects)
  list-row:
    backgroundColor: "{colors.background}"
    textColor: "{colors.ink}"
    typography: "{typography.body}"
    rounded: "{rounded.lg}"
    padding: 12px 8px
    borderColor: "{colors.border-soft}"

  # Tag / pill — accent-tinted label
  tag-orange:
    backgroundColor: "{colors.surface-soft}"
    textColor: "{colors.accent-orange}"
    typography: "{typography.caption}"
    rounded: "{rounded.sm}"
    padding: 2px 8px
  tag-green:
    backgroundColor: "{colors.surface-soft}"
    textColor: "{colors.accent-green}"
    typography: "{typography.caption}"
    rounded: "{rounded.sm}"
    padding: 2px 8px

  # Inline code
  code-inline:
    backgroundColor: "{colors.surface-soft}"
    textColor: "{colors.ink}"
    typography: "{typography.mono-label}"
    rounded: "{rounded.xs}"
    padding: 1px 4px

  # Top nav
  nav-bar:
    backgroundColor: "{colors.background}"
    textColor: "{colors.ink-secondary}"
    typography: "{typography.ui-label}"
    padding: 16px 24px
    borderColor: "{colors.border-soft}"

  # Input
  input:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    typography: "{typography.body-small}"
    rounded: "{rounded.lg}"
    padding: 8px 12px
    borderColor: "{colors.border}"
  input-focus:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    rounded: "{rounded.lg}"
    padding: 8px 12px
    borderColor: "{colors.neutral-500}"
---

# Logan Liffick Design System

## Overview

Logan Liffick's personal site is the portfolio of a design engineer at Vercel, and it reads exactly like that lineage suggests: restraint pushed almost to monochrome. The canvas is a near-black `{colors.background}` (#0a0a0a, the darkest step of the Tailwind neutral scale rather than pure black) with high-contrast off-white `{colors.ink}` text. The whole page is built from a single grayscale ramp — there is no chrome color, no branded hue carrying the layout — so the eye is left with structure, spacing, and type doing all the work.

Typography is Inter, used at a tight band of weights: regular 400 for reading text and medium 500 (`var(--font-weight-medium)`) for headings, labels, and anything that needs to assert itself. There is no bold display weight and no decorative serif. Headings lean on slight negative tracking to feel engineered and compact, while body text sits at normal tracking with generous line-height for comfortable reading. A monospace stack (`var(--font-mono)`) appears only for inline code and the occasional technical label, the small nod to the developer context.

What keeps the site from feeling cold is two carefully rationed pastel accents lifted straight from Tailwind's palette: a warm orange `{colors.accent-orange}` (#ffd7a8) and a mint green `{colors.accent-green}` (#b9f8cf). They never fill surfaces or buttons — they show up as text on tags, status dots, or subtle highlights, soft enough to read as quiet personality rather than brand color. Everything else is neutral. The primary call to action inverts the canvas: a light `{colors.primary}` fill with dark text, the standard "high-contrast button on a dark site" move.

Structure is delineated with hairlines, not shadows. Borders are a single low-contrast step above the canvas (`{colors.border}`), and cards lift by surface tint (`{colors.surface}`) rather than elevation. Radii are gentle and small — the live tokens define `--radius-xs: .125rem` (2px), `--radius-lg: .5rem` (8px), and `--radius-xl: .75rem` (12px) — so nothing feels rounded or playful; corners are softened just enough to avoid hard edges.

**Key Characteristics:**
- Near-black `{colors.background}` (#0a0a0a) canvas with off-white `{colors.ink}` text — a dark-first, almost-monochrome system
- Inter throughout, restricted to two weights: 400 (read) and 500 (emphasis/UI) — no bold, no serif
- Slight negative letter-spacing on headings; normal tracking with loose line-height on body
- Strict Tailwind neutral grayscale ramp from #0a0a0a to #fafafa carries the entire layout
- Two rationed pastel accents — warm orange `{colors.accent-orange}` and mint green `{colors.accent-green}` — used only as text/tag tints, never as fills
- Inverted primary CTA: light fill, dark text
- Hairline borders (`{colors.border}`) and surface tints instead of shadows for separation
- Gentle small radii (2px / 8px / 12px) — softened, never round

## Colors

### Canvas & Ink
- **Canvas** (`{colors.background}`): Near-black page background, the darkest neutral step.
- **Surface** (`{colors.surface}`): Card and panel fill, one step above the canvas.
- **Surface Soft** (`{colors.surface-soft}`): Tag, code, and hover surface tint.
- **Ink** (`{colors.ink}`): Primary off-white text on the dark canvas.
- **Ink Strong** (`{colors.ink-strong}`): Pure-white emphasis for the rare maximum-contrast moment.
- **Ink Secondary** (`{colors.ink-secondary}`): Muted text, nav links, captions.
- **Ink Muted** (`{colors.ink-muted}`): Disabled / lowest-priority text.

### Accents (used sparingly)
- **Accent Orange** (`{colors.accent-orange}`): Warm pastel highlight, tag text, status.
- **Accent Green** (`{colors.accent-green}`): Mint pastel highlight, tag text, status.

### Interactive
- **Primary** (`{colors.primary}`): Inverted light CTA fill on the dark canvas.
- **On Primary** (`{colors.on-primary}`): Dark text on the light CTA.
- **Hover Surface** (`{colors.hover-surface}`): Hover state for ghost buttons / rows.
- **Selection** (`{colors.selection}`): Text selection highlight.

### Borders
- **Border** (`{colors.border}`): Standard hairline on cards and inputs.
- **Border Soft** (`{colors.border-soft}`): Lowest-contrast divider between list rows / nav.

### Neutral Scale
The full Tailwind neutral ramp (`{colors.neutral-50}` → `{colors.neutral-950}`) is the backbone of the system. Text, surfaces, borders, and hover states are all sampled from these steps; the two pastel accents are the only deviation from pure grayscale.

## Typography

### Font Family
- **Primary**: `Inter` (`--font-inter: "Inter", "Inter Fallback"`), with fallbacks `ui-sans-serif, system-ui, sans-serif`.
- **Monospace**: `var(--font-mono)` with fallbacks `ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace` — for inline code and technical labels only.
- **Weights**: a variable Inter (`font-weight: 100 900` declared) used in practice at just two stops — 400 and the `--font-weight-medium` (500) token.

### 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` | Landing name / hero line — 40px Inter 500, tight tracking |
| `page-title` | Section / page titles |
| `section-heading` | Sub-section headings |
| `card-title` | Entry and card titles |
| `body-large` | Lead paragraph / intro |
| `body` | Standard reading text |
| `body-small` | Secondary reading text, metadata |
| `ui-label` | Buttons, nav, interactive labels (500) |
| `caption` | Tags, timestamps, footnotes |
| `mono-label` | Inline code, technical labels |

### Principles
- **Two weights, strict roles**: 400 for reading, 500 for anything interactive or announced. No 600/700 bold anywhere.
- **Negative tracking scales with size**: headings tighten (−0.4px to −1.2px); body stays at normal tracking.
- **Loose body leading**: reading text runs 1.6–1.65 line-height for an airy, comfortable rhythm against the dark canvas.
- **Mono as a whisper**: monospace appears only for code/technical labels — the single signal of the developer context.

## Layout

### Spacing System
The complete scale lives in the `spacing:` token block above. It is a compact, narrow-column rhythm: tight steps (`{spacing.xs}`–`{spacing.lg}`) for component internals, and large jumps (`{spacing.3xl}`–`{spacing.4xl}`) for vertical breathing room between sections.

### Grid & Container
- Single narrow centered column — a reading-width measure (~640–720px), not a full-bleed marketing grid.
- Content stacks vertically: hero / about, then a "Latest" list, then connect links.
- Generous top and inter-section padding; the column never feels crowded.

### Whitespace Philosophy
- **Dark gallery emptiness**: the near-black canvas plus wide vertical spacing makes each block feel isolated and considered.
- **Hairlines over boxes**: separation comes from `{colors.border-soft}` dividers and spacing, not heavy containers.
- **Accent restraint**: color is so rationed that a single orange or green tag becomes a focal point.

## Elevation & Depth

| Level | Treatment | Use |
|---|---|---|
| Flat (Level 0) | No border, no shadow | Page background, text blocks |
| Hairline (Level 1) | 1px solid `{colors.border}` | Cards, inputs |
| Soft divider (Level 1b) | 1px solid `{colors.border-soft}` | List rows, nav bottom |
| Surface lift (Level 2) | `{colors.surface}` fill on `{colors.background}` | Cards, panels |
| Focus (Accessibility) | Ring in `{colors.neutral-500}` / `base-1000` at ~75% | Keyboard focus on interactive elements |

**Shadow Philosophy**: there is effectively no shadow system. Depth is expressed entirely through surface tint and hairline borders — a flat, paper-on-paper feel appropriate to the dark minimal aesthetic.

## Shapes

| Token | Value | Use |
|---|---|---|
| `none` | 0px | Full-bleed sections, dividers |
| `xs` | 2px | Inline code (`--radius-xs`) |
| `sm` | 4px | Tags, small chips |
| `md` | 6px | Icon buttons |
| `lg` | 8px | Buttons, inputs, rows (`--radius-lg`) |
| `xl` | 12px | Cards (`--radius-xl`) |
| `pill` | 9999px | Status dots, avatars |

## Components

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

### Buttons
- **`button-primary`** — Inverted light fill (`{colors.primary}`), dark text, 8px radius. The single high-contrast CTA.
- **`button-ghost`** — Transparent on canvas with a `{colors.border}` hairline; hover tints to `{colors.hover-surface}`.
- **`button-icon`** — Compact square for social/nav icons, muted ink that brightens on hover.

### Links
- **`link`** — Quiet off-white text; underline appears on hover (`decoration-current/70`).
- **`link-muted`** — Secondary gray link for metadata and footers.

### Cards & Rows
- **`card`** — `{colors.surface}` fill, 12px radius, `{colors.border}` hairline. Lifts by tint, never shadow.
- **`list-row`** — Entry row for the "Latest" list; separated by `{colors.border-soft}` dividers.

### Tags
- **`tag-orange` / `tag-green`** — Tiny 4px-radius pills on `{colors.surface-soft}` with pastel accent text. The only place the accents appear.

### Inputs & Code
- **`input`** — `{colors.surface}` fill, hairline border; focus brightens the border to `{colors.neutral-500}`.
- **`code-inline`** — Mono on `{colors.surface-soft}`, 2px radius.

### Navigation
- **`nav-bar`** — Minimal top bar, muted ink links, soft hairline underneath.

## Do's and Don'ts

### Do
- Keep the canvas near-black `{colors.background}` and let off-white `{colors.ink}` text carry contrast
- Use Inter at only two weights — 400 to read, 500 to emphasize
- Apply slight negative tracking to headings; keep body tracking neutral with loose leading
- Ration the pastel accents to text/tag tints only
- Separate with hairline borders and surface tints, not shadows
- Invert the primary CTA: light fill, dark text
- Keep radii small (2–12px)

### Don't
- Don't introduce a third accent or use orange/green as a surface fill
- Don't use bold (600/700) weights — 500 is the ceiling
- Don't add drop shadows or elevation — this is a flat system
- Don't widen the column past a comfortable reading measure
- Don't tighten body line-height — the air is the point
- Don't use pure black; `{colors.background}` (#0a0a0a) is the canvas
- Don't use large playful radii

---

## Responsive Behavior

### Breakpoints
| Name | Width | Key Changes |
|------|-------|-------------|
| Mobile | <640px | Single column, edge padding ~16px |
| Tablet | 640–1024px | Same single column, wider gutters |
| Desktop | >1024px | Centered reading column, max ~720px |

### Touch Targets
- Buttons use 8px–16px padding for comfortable taps
- Icon buttons sit at ~36px square
- List rows have generous vertical padding for tappable hit areas

### Collapsing Strategy
- The layout is already single-column, so little reflow is needed — spacing simply tightens on mobile
- Nav links may collapse to a compact row or menu
- Section vertical spacing compresses from `{spacing.4xl}` toward `{spacing.2xl}` on small screens

### Image / Media Behavior
- Any media sits inside the reading column at full column width with the standard `{rounded.xl}` radius and `{colors.border}` hairline
- The dark canvas is maintained edge-to-edge at all sizes

---

## Agent Prompt Guide

### Quick Color Reference
- Background: near-black `{colors.background}`
- Heading + body text: off-white `{colors.ink}`
- Secondary text: `{colors.ink-secondary}`
- Primary CTA: light fill `{colors.primary}` with `{colors.on-primary}` text
- Border: hairline `{colors.border}`
- Accents (sparingly): `{colors.accent-orange}`, `{colors.accent-green}`

### Example Component Prompts
- "Create a hero on near-black `{colors.background}`. Name at 40px Inter weight 500, line-height 1.10, letter-spacing −1.2px, color `{colors.ink}`. One-line bio at 18px Inter weight 400, line-height 1.65, color `{colors.ink-secondary}`. A light pill-less CTA button (`{colors.primary}` fill, `{colors.on-primary}` text, 8px radius, 8px 16px padding) and a ghost button (transparent, `{colors.border}` hairline)."
- "Design a card: `{colors.surface}` fill, no shadow, 1px solid `{colors.border}`, 12px radius, 20px padding. Title 16px Inter weight 500, body 16px weight 400 in `{colors.ink-secondary}`."
- "Build a tag: `{colors.surface-soft}` background, `{colors.accent-orange}` text, 4px radius, 2px 8px padding, 13px Inter."
- "Create a 'Latest' list: rows separated by 1px `{colors.border-soft}` dividers, title 16px Inter 500 in `{colors.ink}`, date 13px in `{colors.ink-secondary}`, underline-on-hover."

### Iteration Guide
1. Start dark — `{colors.background}` canvas, `{colors.ink}` text — before adding anything
2. Inter only, weights 400 and 500; never reach for bold
3. Color is grayscale by default; the two pastels are a whisper, never a fill
4. Separate with hairlines and surface tints, not shadows
5. Keep the column narrow and the vertical spacing wide
6. Radii stay small (2/8/12px) — softened, not round

---

## 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 Logan Liffick. Brand names and trademarks belong to their respective owners.
