Etsy DESIGN.md

Brands

Etsy's design system embodies a warm, handcrafted aesthetic that celebrates creativity, artisanship, and human connection. The platform connects millions of buyers with independent sellers offering unique, often…

Raw DESIGN.md

At a glance

Group
Brands
Main color
#f56400Orange design systems
Font
Graphik Webfont

Colors in this file

  • #222222

    Etsy Black

  • #ffffff

    --bg-primary

  • #f56400

    Etsy Orange (Primary)

  • #757575

    Unnamed

  • #595959

    --text-secondary

  • #fdebd2

    --bg-cream

  • #333333

    --text-body

  • #bdbdbd

    Unnamed

  • #f1641e

    Etsy Coral

  • #faf9f7

    --bg-warm

Overview

Etsy's design system embodies a warm, handcrafted aesthetic that celebrates creativity, artisanship, and human connection. The platform connects millions of buyers with independent sellers offering unique, often handmade or vintage items. The design language emphasizes authenticity, warmth, and discoverability while maintaining trust through clear seller information and social proof.

Design Philosophy: Warm, inviting, and craft-focused - celebrating the human touch behind every item while enabling seamless discovery and secure transactions in a global creative marketplace.

1. Color Palette

Brand Colors

Color NameHex CodeRGBUsage
Etsy Orange (Primary)#F56400rgb(245, 100, 0)Primary brand, CTAs, accents
Etsy Coral#F1641Ergb(241, 100, 30)Secondary brand, hover states
Etsy Orange Dark#D35400rgb(211, 84, 0)Active/pressed states
Etsy Orange Light#FF7B29rgb(255, 123, 41)Highlights, badges
Etsy Black#222222rgb(34, 34, 34)Logo, primary text

Background Colors

TokenValueUsage
--etsy-bg-primary#FFFFFFPrimary page background
--etsy-bg-cream#FDEBD2Warm accent backgrounds
--etsy-bg-light-cream#FDF6ECSubtle warm backgrounds
--etsy-bg-warm-white#FAF9F7Card backgrounds, sections
--etsy-bg-gray-light#F5F5F5Secondary backgrounds
--etsy-bg-gray-lighter#FAFAFASubtle separation
--etsy-bg-overlayrgba(34, 34, 34, 0.6)Modal overlays
--etsy-bg-hover#F1F1F1Interactive hover states
--etsy-bg-selected#FFF4E6Selected/active items

Semantic Colors

CategoryTokenValueUsage
Success--etsy-success#2E7D32Order confirmed, in stock
Success Light--etsy-success-light#E8F5E9Success backgrounds
Error--etsy-error#D32F2FValidation errors, out of stock
Error Light--etsy-error-light#FFEBEEError backgrounds
Warning--etsy-warning#F57C00Low stock, limited time
Warning Light--etsy-warning-light#FFF3E0Warning backgrounds
Info--etsy-info#1976D2Informational messages
Info Light--etsy-info-light#E3F2FDInfo backgrounds
Favorite Red--etsy-favorite#E53935Heart/favorites icon filled
Star Gold--etsy-star#FBBF24Review stars
Star Empty--etsy-star-empty#D1D5DBEmpty review stars

Text Colors

TokenValueUsage
--etsy-text-primary#222222Primary headings, important text
--etsy-text-body#333333Body text, descriptions
--etsy-text-secondary#595959Secondary text, metadata
--etsy-text-tertiary#757575Helper text, placeholders
--etsy-text-disabled#9E9E9EDisabled states
--etsy-text-inverse#FFFFFFText on dark backgrounds
--etsy-text-link#222222Standard links (underlined)
--etsy-text-link-hover#F56400Link hover state
--etsy-text-price#222222Product prices
--etsy-text-sale#2E7D32Sale prices
--etsy-text-original-price#757575Strikethrough original price

Border Colors

TokenValueUsage
--etsy-border-default#E0E0E0Default borders
--etsy-border-light#EEEEEESubtle borders
--etsy-border-dark#BDBDBDEmphasized borders
--etsy-border-focus#222222Focus ring color
--etsy-border-error#D32F2FError state borders
--etsy-border-input#BDBDBDForm input borders
--etsy-border-input-hover#757575Input hover state
--etsy-border-input-focus#222222Input focus state

Icon Colors

TokenValueUsage
--etsy-icon-primary#222222Primary icons
--etsy-icon-secondary#595959Secondary icons
--etsy-icon-tertiary#757575Tertiary/muted icons
--etsy-icon-disabled#BDBDBDDisabled icons
--etsy-icon-inverse#FFFFFFIcons on dark backgrounds
--etsy-icon-favorite#E53935Filled heart
--etsy-icon-favorite-outline#222222Unfilled heart outline

2. Typography

Font Families

css/* Primary Sans-Serif - Graphik Web */
--etsy-font-primary: 'Graphik Webfont', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;

/* Display/Decorative - Guardian Egyptian */
--etsy-font-display: 'Guardian Egyptian Web', Georgia, 'Times New Roman', serif;

/* System Fallback Stack */
--etsy-font-system: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;

/* Monospace */
--etsy-font-mono: 'SF Mono', SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;

Font Sizes

TokenSizeUsage
--etsy-font-size-xs11pxFine print, legal text
--etsy-font-size-sm12pxCaptions, metadata
--etsy-font-size-base13pxDefault body text
--etsy-font-size-md14pxLarger body text
--etsy-font-size-lg16pxEmphasized text, subheadings
--etsy-font-size-xl18pxSection headings
--etsy-font-size-2xl20pxCard titles
--etsy-font-size-3xl24pxPage section titles
--etsy-font-size-4xl28pxPage headings
--etsy-font-size-5xl32pxHero text
--etsy-font-size-6xl40pxDisplay headings
--etsy-font-size-7xl48pxLarge display

Font Weights

TokenValueUsage
--etsy-font-weight-light300Decorative text
--etsy-font-weight-regular400Body text, default
--etsy-font-weight-medium500Emphasized text, navigation
--etsy-font-weight-semibold600Subheadings, labels
--etsy-font-weight-bold700Headings, buttons, prices

Line Heights

TokenValueUsage
--etsy-line-height-tight1.2Headings, display text
--etsy-line-height-snug1.3Compact text
--etsy-line-height-normal1.4Default body text
--etsy-line-height-relaxed1.5Readable body text
--etsy-line-height-loose1.6Long-form content

Letter Spacing

TokenValueUsage
--etsy-letter-spacing-tight-0.02emDisplay headings
--etsy-letter-spacing-normal0Body text
--etsy-letter-spacing-wide0.02emUppercase labels
--etsy-letter-spacing-wider0.05emSmall caps, badges

Typography Hierarchy

LevelFontSizeWeightLine HeightUsage
DisplayGuardian Egyptian40px7001.2Hero headlines
Heading 1Graphik28px7001.2Page titles
Heading 2Graphik24px7001.3Section titles
Heading 3Graphik20px6001.3Card headings
Heading 4Graphik16px6001.4Subsection titles
Body LargeGraphik14px4001.5Featured descriptions
BodyGraphik13px4001.4Default body
Body SmallGraphik12px4001.4Metadata, captions
CaptionGraphik11px4001.3Fine print
PriceGraphik16-20px7001.2Product prices

3. Spacing System

Base Spacing Scale

TokenValueUsage
--etsy-space-00pxNo spacing
--etsy-space-14pxMinimal spacing
--etsy-space-28pxTight spacing
--etsy-space-312pxDefault internal spacing
--etsy-space-416pxStandard spacing
--etsy-space-520pxComfortable spacing
--etsy-space-624pxSection spacing
--etsy-space-832pxLarge spacing
--etsy-space-1040pxExtra large spacing
--etsy-space-1248pxPage section gaps
--etsy-space-1664pxMajor section spacing
--etsy-space-2080pxHero spacing
--etsy-space-2496pxMaximum spacing

Component-Specific Spacing

TokenValueUsage
--etsy-card-padding16pxProduct card internal padding
--etsy-card-gap12pxGap between card elements
--etsy-grid-gap24pxGrid gap between product cards
--etsy-grid-gap-mobile12pxMobile grid gap
--etsy-section-padding32pxPage section padding
--etsy-nav-height56pxMain navigation height
--etsy-nav-height-mobile48pxMobile navigation height
--etsy-search-height44pxSearch bar height

Layout Guidelines

  • Product card padding: 12-16px on all sides
  • Section spacing: 32-48px between major sections
  • Grid gap (desktop): 24px between cards
  • Grid gap (mobile): 12px between cards
  • Form field spacing: 16px between fields
  • Button groups: 8-12px gap between buttons
  • Icon-to-text spacing: 8px
  • List items: 8-12px vertical spacing

4. Border & Radius

Border Radius

TokenValueUsage
--etsy-radius-none0pxNo rounding
--etsy-radius-sm4pxSmall elements, badges
--etsy-radius-md8pxButtons, inputs
--etsy-radius-lg12pxCards, containers
--etsy-radius-xl16pxLarge cards, modals
--etsy-radius-2xl24pxFeatured sections
--etsy-radius-full9999pxPills, avatars, circles

Border Width

TokenValueUsage
--etsy-border-width-00pxNo border
--etsy-border-width-11pxDefault borders
--etsy-border-width-22pxEmphasized borders, focus
--etsy-border-width-33pxStrong emphasis

Common Border Patterns

css/* Product card border */
.product-card {
  border: var(--etsy-border-width-1) solid var(--etsy-border-light);
  border-radius: var(--etsy-radius-lg);
}

/* Input field border */
.input {
  border: var(--etsy-border-width-1) solid var(--etsy-border-input);
  border-radius: var(--etsy-radius-md);
}

/* Focus ring */
:focus-visible {
  outline: var(--etsy-border-width-2) solid var(--etsy-border-focus);
  outline-offset: 2px;
}

/* Button border (secondary) */
.button-secondary {
  border: var(--etsy-border-width-1) solid var(--etsy-border-dark);
  border-radius: var(--etsy-radius-full);
}

/* Favorite heart container */
.favorite-button {
  border: none;
  border-radius: var(--etsy-radius-full);
}

5. Shadows & Elevation

Shadow Tokens

TokenValueUsage
--etsy-shadow-nonenoneNo shadow
--etsy-shadow-sm0 1px 2px rgba(34, 34, 34, 0.08)Subtle lift
--etsy-shadow-md0 2px 8px rgba(34, 34, 34, 0.1)Cards at rest
--etsy-shadow-lg0 4px 16px rgba(34, 34, 34, 0.12)Hovered cards, dropdowns
--etsy-shadow-xl0 8px 24px rgba(34, 34, 34, 0.15)Modals, popovers
--etsy-shadow-2xl0 16px 48px rgba(34, 34, 34, 0.2)Large dialogs

Card Shadows

TokenValueUsage
--etsy-card-shadow0 2px 4px rgba(34, 34, 34, 0.06)Product card default
--etsy-card-shadow-hover0 4px 12px rgba(34, 34, 34, 0.12)Product card hover

Elevation Hierarchy

LevelShadowUse Case
Level 0--etsy-shadow-noneFlat content, inline elements
Level 1--etsy-shadow-smSubtle depth
Level 2--etsy-shadow-mdCards, buttons at rest
Level 3--etsy-shadow-lgHovered cards, dropdowns
Level 4--etsy-shadow-xlModals, overlays
Level 5--etsy-shadow-2xlMaximum elevation

Z-Index Scale

TokenValueUsage
--etsy-z-base0Default stacking
--etsy-z-raised10Raised elements
--etsy-z-dropdown100Dropdown menus
--etsy-z-sticky200Sticky navigation
--etsy-z-overlay300Overlay backgrounds
--etsy-z-modal400Modal dialogs
--etsy-z-popover500Popovers, tooltips
--etsy-z-toast600Toast notifications
--etsy-z-maximum9999Critical overlays

6. Component Specifications

Buttons

Button Types

TypeBackgroundTextBorderUsage
Primary#222222WhiteNoneMain CTAs (Add to cart, Buy now)
Primary Orange#F56400WhiteNoneBrand CTAs, special actions
SecondaryWhite#2222221px #222222Secondary actions
TertiaryTransparent#222222NoneLow emphasis actions
OutlineTransparent#2222222px #222222Filter toggles
FavoriteTransparentRed/BlackNoneHeart/favorite button

Button Sizes

SizeHeightPaddingFont SizeBorder Radius
Small32px12px 16px13px24px (pill)
Medium40px12px 24px14px24px (pill)
Large48px16px 32px16px28px (pill)
Icon40px8px-50% (circle)

Button States

css/* Primary Button */
.button-primary {
  background: var(--etsy-text-primary);
  color: var(--etsy-text-inverse);
  border: none;
  border-radius: var(--etsy-radius-full);
  padding: 12px 24px;
  font-weight: var(--etsy-font-weight-medium);
  font-size: 14px;
  cursor: pointer;
  transition: all 0.15s ease;
}

.button-primary:hover {
  background: #000000;
  transform: translateY(-1px);
}

.button-primary:active {
  transform: translateY(0);
}

.button-primary:disabled {
  background: var(--etsy-text-disabled);
  cursor: not-allowed;
}

/* Secondary Button */
.button-secondary {
  background: var(--etsy-bg-primary);
  color: var(--etsy-text-primary);
  border: 1px solid var(--etsy-text-primary);
  border-radius: var(--etsy-radius-full);
}

.button-secondary:hover {
  background: var(--etsy-bg-hover);
}

/* Favorite Button */
.button-favorite {
  background: rgba(255, 255, 255, 0.9);
  border: none;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.button-favorite:hover {
  background: rgba(255, 255, 255, 1);
}

.button-favorite.active svg {
  fill: var(--etsy-icon-favorite);
  color: var(--etsy-icon-favorite);
}

Product Cards

css.product-card {
  background: var(--etsy-bg-primary);
  border-radius: var(--etsy-radius-lg);
  overflow: hidden;
  transition: box-shadow 0.2s ease, transform 0.2s ease;
  position: relative;
}

.product-card:hover {
  box-shadow: var(--etsy-card-shadow-hover);
  transform: translateY(-2px);
}

.product-card-image {
  aspect-ratio: 1;
  object-fit: cover;
  width: 100%;
}

.product-card-content {
  padding: var(--etsy-space-3);
}

.product-card-shop {
  font-size: var(--etsy-font-size-sm);
  color: var(--etsy-text-secondary);
  margin-bottom: var(--etsy-space-1);
}

.product-card-title {
  font-size: var(--etsy-font-size-base);
  font-weight: var(--etsy-font-weight-regular);
  color: var(--etsy-text-body);
  line-height: var(--etsy-line-height-snug);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-bottom: var(--etsy-space-2);
}

.product-card-price {
  font-size: var(--etsy-font-size-lg);
  font-weight: var(--etsy-font-weight-bold);
  color: var(--etsy-text-price);
}

.product-card-price-original {
  font-size: var(--etsy-font-size-sm);
  color: var(--etsy-text-original-price);
  text-decoration: line-through;
  margin-left: var(--etsy-space-2);
}

.product-card-favorite {
  position: absolute;
  top: var(--etsy-space-3);
  right: var(--etsy-space-3);
  z-index: var(--etsy-z-raised);
}

Review Stars

css.star-rating {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.star {
  width: 14px;
  height: 14px;
  color: var(--etsy-star);
  fill: var(--etsy-star);
}

.star-empty {
  color: var(--etsy-star-empty);
  fill: var(--etsy-star-empty);
}

.star-half {
  position: relative;
}

.star-half::before {
  content: '';
  position: absolute;
  width: 50%;
  height: 100%;
  overflow: hidden;
  color: var(--etsy-star);
}

.review-count {
  font-size: var(--etsy-font-size-sm);
  color: var(--etsy-text-secondary);
  margin-left: var(--etsy-space-1);
}

Shop Badges

css/* Star Seller Badge */
.badge-star-seller {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--etsy-bg-cream);
  color: var(--etsy-text-primary);
  padding: 4px 8px;
  border-radius: var(--etsy-radius-sm);
  font-size: var(--etsy-font-size-xs);
  font-weight: var(--etsy-font-weight-medium);
}

.badge-star-seller svg {
  color: var(--etsy-star);
  width: 12px;
  height: 12px;
}

/* Free Shipping Badge */
.badge-free-shipping {
  display: inline-flex;
  background: var(--etsy-success-light);
  color: var(--etsy-success);
  padding: 4px 8px;
  border-radius: var(--etsy-radius-sm);
  font-size: var(--etsy-font-size-xs);
  font-weight: var(--etsy-font-weight-medium);
}

/* Sale Badge */
.badge-sale {
  display: inline-flex;
  background: var(--etsy-success);
  color: white;
  padding: 4px 8px;
  border-radius: var(--etsy-radius-sm);
  font-size: var(--etsy-font-size-xs);
  font-weight: var(--etsy-font-weight-bold);
}

/* Bestseller Badge */
.badge-bestseller {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--etsy-bg-warm-white);
  border: 1px solid var(--etsy-border-default);
  color: var(--etsy-text-primary);
  padding: 4px 8px;
  border-radius: var(--etsy-radius-sm);
  font-size: var(--etsy-font-size-xs);
  font-weight: var(--etsy-font-weight-medium);
}

Form Inputs

css/* Text Input */
.input {
  width: 100%;
  height: 44px;
  padding: 12px 16px;
  background: var(--etsy-bg-primary);
  border: 1px solid var(--etsy-border-input);
  border-radius: var(--etsy-radius-md);
  font-size: var(--etsy-font-size-md);
  color: var(--etsy-text-body);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.input:hover {
  border-color: var(--etsy-border-input-hover);
}

.input:focus {
  border-color: var(--etsy-border-input-focus);
  outline: none;
  box-shadow: 0 0 0 1px var(--etsy-border-input-focus);
}

.input::placeholder {
  color: var(--etsy-text-tertiary);
}

.input:disabled {
  background: var(--etsy-bg-gray-light);
  color: var(--etsy-text-disabled);
  cursor: not-allowed;
}

.input-error {
  border-color: var(--etsy-error);
}

.input-error:focus {
  box-shadow: 0 0 0 1px var(--etsy-error);
}

/* Search Input */
.search-input {
  height: var(--etsy-search-height);
  padding-left: 44px;
  padding-right: 16px;
  border-radius: var(--etsy-radius-full);
  background-image: url('search-icon.svg');
  background-repeat: no-repeat;
  background-position: 16px center;
  background-size: 20px;
}

/* Select */
.select {
  appearance: none;
  background-image: url('chevron-down.svg');
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 16px;
  padding-right: 40px;
}

/* Checkbox */
.checkbox {
  width: 18px;
  height: 18px;
  border: 1px solid var(--etsy-border-input);
  border-radius: var(--etsy-radius-sm);
  appearance: none;
  cursor: pointer;
  transition: all 0.15s ease;
}

.checkbox:checked {
  background: var(--etsy-text-primary);
  border-color: var(--etsy-text-primary);
  background-image: url('check.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: 12px;
}

Navigation

css/* Main Navigation Bar */
.nav-main {
  height: var(--etsy-nav-height);
  background: var(--etsy-bg-primary);
  border-bottom: 1px solid var(--etsy-border-light);
  display: flex;
  align-items: center;
  padding: 0 var(--etsy-space-6);
}

/* Logo */
.nav-logo {
  color: var(--etsy-brand-orange);
  font-size: 28px;
  font-weight: var(--etsy-font-weight-bold);
  text-decoration: none;
}

/* Category Navigation */
.nav-categories {
  display: flex;
  gap: var(--etsy-space-4);
  padding: var(--etsy-space-3) var(--etsy-space-6);
  background: var(--etsy-bg-primary);
  border-bottom: 1px solid var(--etsy-border-light);
  overflow-x: auto;
}

.nav-category-item {
  font-size: var(--etsy-font-size-base);
  color: var(--etsy-text-body);
  text-decoration: none;
  white-space: nowrap;
  padding: var(--etsy-space-2) 0;
  border-bottom: 2px solid transparent;
  transition: all 0.15s ease;
}

.nav-category-item:hover {
  color: var(--etsy-text-primary);
}

.nav-category-item.active {
  font-weight: var(--etsy-font-weight-medium);
  border-bottom-color: var(--etsy-text-primary);
}

/* Icon Navigation */
.nav-icon-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: transparent;
  border: none;
  cursor: pointer;
  transition: background 0.15s ease;
}

.nav-icon-button:hover {
  background: var(--etsy-bg-hover);
}

.nav-icon-button svg {
  width: 24px;
  height: 24px;
  color: var(--etsy-icon-primary);
}

Filters

css/* Filter Container */
.filter-container {
  display: flex;
  flex-wrap: wrap;
  gap: var(--etsy-space-2);
  padding: var(--etsy-space-4) 0;
  border-bottom: 1px solid var(--etsy-border-light);
}

/* Filter Button */
.filter-button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  background: var(--etsy-bg-primary);
  border: 1px solid var(--etsy-border-dark);
  border-radius: var(--etsy-radius-full);
  font-size: var(--etsy-font-size-base);
  color: var(--etsy-text-body);
  cursor: pointer;
  transition: all 0.15s ease;
}

.filter-button:hover {
  background: var(--etsy-bg-hover);
}

.filter-button.active {
  background: var(--etsy-text-primary);
  color: var(--etsy-text-inverse);
  border-color: var(--etsy-text-primary);
}

/* Filter Chip */
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: var(--etsy-bg-selected);
  border: 1px solid var(--etsy-border-default);
  border-radius: var(--etsy-radius-full);
  font-size: var(--etsy-font-size-sm);
}

.filter-chip-remove {
  width: 16px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

Seller Information

css/* Shop Info Card */
.shop-info {
  display: flex;
  align-items: center;
  gap: var(--etsy-space-3);
  padding: var(--etsy-space-4);
  background: var(--etsy-bg-warm-white);
  border-radius: var(--etsy-radius-lg);
}

.shop-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  object-fit: cover;
}

.shop-name {
  font-size: var(--etsy-font-size-md);
  font-weight: var(--etsy-font-weight-medium);
  color: var(--etsy-text-primary);
}

.shop-meta {
  font-size: var(--etsy-font-size-sm);
  color: var(--etsy-text-secondary);
  display: flex;
  align-items: center;
  gap: var(--etsy-space-2);
}

/* Shop Stats */
.shop-stats {
  display: flex;
  gap: var(--etsy-space-6);
  margin-top: var(--etsy-space-3);
}

.shop-stat {
  text-align: center;
}

.shop-stat-value {
  font-size: var(--etsy-font-size-xl);
  font-weight: var(--etsy-font-weight-bold);
  color: var(--etsy-text-primary);
}

.shop-stat-label {
  font-size: var(--etsy-font-size-sm);
  color: var(--etsy-text-secondary);
}

7. Motion & Animation

Timing Functions

TokenValueUsage
--etsy-ease-defaultcubic-bezier(0.4, 0, 0.2, 1)Standard transitions
--etsy-ease-incubic-bezier(0.4, 0, 1, 1)Enter animations
--etsy-ease-outcubic-bezier(0, 0, 0.2, 1)Exit animations
--etsy-ease-in-outcubic-bezier(0.4, 0, 0.2, 1)Symmetrical animations
--etsy-ease-bouncecubic-bezier(0.34, 1.56, 0.64, 1)Playful bounce

Duration Tokens

TokenValueUsage
--etsy-duration-instant0msNo animation
--etsy-duration-fast100msMicro-interactions
--etsy-duration-normal150msStandard transitions
--etsy-duration-moderate200msMedium transitions
--etsy-duration-slow300msComplex animations
--etsy-duration-slower400msPage transitions
--etsy-duration-slowest500msLarge element animations

Animation Keyframes

css/* Fade In */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Fade In Up */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Scale In */
@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0.95);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* Heart Pop */
@keyframes heartPop {
  0% { transform: scale(1); }
  25% { transform: scale(1.2); }
  50% { transform: scale(0.95); }
  100% { transform: scale(1); }
}

/* Slide Down */
@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Shimmer (Loading) */
@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

/* Spin */
@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

Common Animation Patterns

css/* Card hover lift */
.product-card {
  transition: transform var(--etsy-duration-normal) var(--etsy-ease-out),
              box-shadow var(--etsy-duration-normal) var(--etsy-ease-out);
}

.product-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--etsy-card-shadow-hover);
}

/* Favorite heart animation */
.favorite-button svg {
  transition: transform var(--etsy-duration-fast) var(--etsy-ease-bounce);
}

.favorite-button:active svg {
  animation: heartPop var(--etsy-duration-slow) var(--etsy-ease-out);
}

/* Button hover */
.button {
  transition: background var(--etsy-duration-fast) var(--etsy-ease-default),
              transform var(--etsy-duration-fast) var(--etsy-ease-default);
}

.button:hover {
  transform: translateY(-1px);
}

.button:active {
  transform: translateY(0);
}

/* Dropdown appearance */
.dropdown {
  animation: slideDown var(--etsy-duration-moderate) var(--etsy-ease-out);
}

/* Modal appearance */
.modal {
  animation: scaleIn var(--etsy-duration-slow) var(--etsy-ease-out);
}

/* Loading skeleton */
.skeleton {
  background: linear-gradient(
    90deg,
    var(--etsy-bg-gray-light) 25%,
    var(--etsy-bg-gray-lighter) 50%,
    var(--etsy-bg-gray-light) 75%
  );
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite linear;
}

/* Spinner */
.spinner {
  animation: spin 1s linear infinite;
}

8. Responsive Breakpoints

Breakpoint Tokens

TokenValueUsage
--etsy-breakpoint-xs0pxMobile (extra small)
--etsy-breakpoint-sm480pxMobile landscape
--etsy-breakpoint-md768pxTablet
--etsy-breakpoint-lg1024pxDesktop
--etsy-breakpoint-xl1280pxLarge desktop
--etsy-breakpoint-2xl1440pxExtra large desktop

Media Query Patterns

scss// Mobile first (recommended)
$breakpoint-sm: 480px;
$breakpoint-md: 768px;
$breakpoint-lg: 1024px;
$breakpoint-xl: 1280px;
$breakpoint-2xl: 1440px;

// Media query mixins
@mixin sm-up { @media (min-width: $breakpoint-sm) { @content; } }
@mixin md-up { @media (min-width: $breakpoint-md) { @content; } }
@mixin lg-up { @media (min-width: $breakpoint-lg) { @content; } }
@mixin xl-up { @media (min-width: $breakpoint-xl) { @content; } }
@mixin 2xl-up { @media (min-width: $breakpoint-2xl) { @content; } }

// Desktop first
@mixin sm-down { @media (max-width: $breakpoint-sm - 1) { @content; } }
@mixin md-down { @media (max-width: $breakpoint-md - 1) { @content; } }
@mixin lg-down { @media (max-width: $breakpoint-lg - 1) { @content; } }
@mixin xl-down { @media (max-width: $breakpoint-xl - 1) { @content; } }

Product Grid Columns

BreakpointGrid ColumnsCard Min WidthGap
xs (0-479px)2140px12px
sm (480-767px)2-3160px16px
md (768-1023px)3-4180px20px
lg (1024-1279px)4-5200px24px
xl (1280-1439px)5-6220px24px
2xl (1440px+)6+240px24px

Responsive Layout Guidelines

css/* Product Grid */
.product-grid {
  display: grid;
  gap: var(--etsy-grid-gap-mobile);
  grid-template-columns: repeat(2, 1fr);
}

@media (min-width: 480px) {
  .product-grid {
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 16px;
  }
}

@media (min-width: 768px) {
  .product-grid {
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 20px;
  }
}

@media (min-width: 1024px) {
  .product-grid {
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--etsy-grid-gap);
  }
}

/* Container */
.container {
  width: 100%;
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 16px;
}

@media (min-width: 768px) {
  .container {
    padding: 0 24px;
  }
}

@media (min-width: 1024px) {
  .container {
    padding: 0 32px;
  }
}

/* Navigation - Mobile */
@media (max-width: 767px) {
  .nav-main {
    height: var(--etsy-nav-height-mobile);
    padding: 0 var(--etsy-space-4);
  }
  
  .nav-categories {
    display: none;
  }
  
  .nav-mobile-menu {
    display: flex;
  }
}

@media (min-width: 768px) {
  .nav-mobile-menu {
    display: none;
  }
}

Content Width Guidelines

Container TypeMax WidthPadding
Full width100%16px (mobile), 24-32px (desktop)
Standard1440px16px (mobile), 32px (desktop)
Narrow1200px16px (mobile), 32px (desktop)
Content900px16px (mobile), 24px (desktop)
Readable680px16px (mobile), 24px (desktop)

9. Accessibility Guidelines

Color Contrast Requirements

ElementMinimum RatioWCAG Level
Body text4.5:1AA
Large text (18px+ bold, 24px+)3:1AA
UI components, icons3:1AA
Focus indicators3:1AA

Etsy Color Contrast Compliance

CombinationRatioCompliant
#222222 on #FFFFFF16.1:1AAA
#333333 on #FFFFFF12.6:1AAA
#595959 on #FFFFFF7.0:1AAA
#757575 on #FFFFFF4.6:1AA
#FFFFFF on #F564003.4:1AA (large text)
#FFFFFF on #22222216.1:1AAA
#222222 on #FDEBD211.8:1AAA

Focus States

css/* Standard focus ring */
:focus-visible {
  outline: 2px solid var(--etsy-border-focus);
  outline-offset: 2px;
}

/* Button focus */
.button:focus-visible {
  outline: 2px solid var(--etsy-border-focus);
  outline-offset: 2px;
}

/* Card focus */
.product-card:focus-visible {
  outline: 2px solid var(--etsy-border-focus);
  outline-offset: 2px;
}

/* Input focus */
.input:focus {
  border-color: var(--etsy-border-input-focus);
  box-shadow: 0 0 0 1px var(--etsy-border-input-focus);
  outline: none;
}

/* Skip link */
.skip-link {
  position: absolute;
  top: -100%;
  left: 16px;
  padding: 8px 16px;
  background: var(--etsy-bg-primary);
  border: 2px solid var(--etsy-border-focus);
  border-radius: var(--etsy-radius-md);
  z-index: var(--etsy-z-maximum);
}

.skip-link:focus {
  top: 16px;
}

Touch Target Sizes

ElementMinimum SizeRecommended
Buttons44px x 44px48px x 48px
Icon buttons44px x 44px48px x 48px
Favorite hearts44px x 44px48px x 48px
Links (inline)N/AAdequate padding
Checkboxes/Radios44px x 44px48px x 48px
Filter chips32px height36px height minimum

Interaction State Signifiers

StateVisual Treatment
HoverBackground color change, subtle shadow lift
FocusBlack outline ring (2px, 2px offset)
Active/PressedSlight scale down, darker background
SelectedBackground highlight, checkmark icon
DisabledReduced opacity (40%), cursor: not-allowed
LoadingSpinner, skeleton shimmer
ErrorRed border, error message below
FavoritedRed filled heart icon

Keyboard Navigation

  • All interactive elements must be keyboard accessible
  • Tab order follows logical reading order (left-to-right, top-to-bottom)
  • Product cards are tabbable with Enter to open
  • Favorite buttons accessible via keyboard
  • Escape key closes modals, dropdowns, and popovers
  • Arrow keys navigate within dropdown menus
  • Space/Enter activates buttons and links
  • Skip link to bypass navigation

Screen Reader Guidelines

html<!-- Product Card -->
<article class="product-card" aria-labelledby="product-title-123">
  <img src="product.jpg" alt="Handmade ceramic mug with blue glaze" />
  <button 
    class="favorite-button" 
    aria-label="Add to favorites"
    aria-pressed="false"
  >
    <svg aria-hidden="true"><!-- heart icon --></svg>
  </button>
  <div class="product-card-content">
    <a href="/shop/name" class="shop-name">ShopName</a>
    <h3 id="product-title-123">
      <a href="/listing/123">Handmade Ceramic Mug</a>
    </h3>
    <div class="star-rating" aria-label="4.8 out of 5 stars">
      <!-- star icons -->
      <span aria-hidden="true">(1,234)</span>
      <span class="visually-hidden">1,234 reviews</span>
    </div>
    <span class="price" aria-label="$24.99">$24.99</span>
  </div>
</article>

<!-- Badge -->
<span class="badge-star-seller" role="img" aria-label="Star Seller">
  <svg aria-hidden="true"><!-- star icon --></svg>
  Star Seller
</span>

<!-- Review Stars -->
<div class="star-rating" role="img" aria-label="4.5 out of 5 stars">
  <svg aria-hidden="true"><!-- 4 filled stars --></svg>
  <svg aria-hidden="true"><!-- 1 half star --></svg>
</div>

<!-- Loading State -->
<div aria-live="polite" aria-busy="true">
  <span class="visually-hidden">Loading products...</span>
</div>

<!-- Visually Hidden Class -->
<style>
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
</style>

Motion Preferences

css@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  
  .product-card:hover {
    transform: none;
  }
  
  .skeleton {
    animation: none;
    background: var(--etsy-bg-gray-light);
  }
}

Image Guidelines

  • All product images must have descriptive alt text
  • Decorative images use alt=""
  • Icons use aria-hidden="true" with adjacent text labels
  • Complex images (infographics) include detailed descriptions
  • Lazy-loaded images maintain aspect ratio to prevent layout shift

Quick Reference

CSS Custom Properties Import

css:root {
  /* Brand */
  --etsy-orange: #F56400;
  --etsy-coral: #F1641E;
  --etsy-black: #222222;
  
  /* Backgrounds */
  --bg-primary: #FFFFFF;
  --bg-cream: #FDEBD2;
  --bg-warm: #FAF9F7;
  
  /* Text */
  --text-primary: #222222;
  --text-body: #333333;
  --text-secondary: #595959;
  
  /* Typography */
  --font-primary: 'Graphik Webfont', -apple-system, sans-serif;
  --font-size-base: 13px;
  --font-weight-regular: 400;
  --font-weight-medium: 500;
  --font-weight-bold: 700;
  
  /* Spacing */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-6: 24px;
  --space-8: 32px;
  
  /* Borders */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-full: 9999px;
  
  /* Shadows */
  --shadow-card: 0 2px 4px rgba(34, 34, 34, 0.06);
  --shadow-card-hover: 0 4px 12px rgba(34, 34, 34, 0.12);
  
  /* Animation */
  --duration-fast: 100ms;
  --duration-normal: 150ms;
  --ease-default: cubic-bezier(0.4, 0, 0.2, 1);
}

Component Size Reference

ComponentHeightMin Width
Button (small)32px64px
Button (medium)40px80px
Button (large)48px100px
Input field44px200px
Search bar44px280px
Nav height (desktop)56px-
Nav height (mobile)48px-
Product cardauto140px
Avatar (small)32px32px
Avatar (medium)48px48px
Avatar (large)72px72px
Badge20pxauto
Icon (standard)24px24px
Star (rating)14px14px

Resources

Use it with your agent

Save the file as DESIGN.md in your project root, then ask your agent to follow it for UI work. Or let the agent fetch it over MCP.

Download

curl -o DESIGN.md https://www.uiskillbook.com/design-md/etsy.md

MCP server

https://www.uiskillbook.com/mcp

MCP tool call

get_design_md({ "slug": "etsy" })