---
version: alpha
name: "duolingo.com"
description: "Design system extracted from https://www.duolingo.com/ on 2026-10-28"
colors:
  background: "#ffffff"
  foreground: "#777777"
  primary: "#58cc02"
  on-primary: "#111111"
  secondary: "#1cb0f6"
  border: "#e5e5e5"
typography:
  headline-display:
    fontFamily: "duolingo-sans"
    fontSize: "32px"
    fontWeight: 700
    lineHeight: "1.4"
  headline-lg:
    fontFamily: "feather"
    fontSize: "48px"
    fontWeight: 700
    lineHeight: "1.4"
  headline-md:
    fontFamily: "duolingo-sans"
    fontSize: "24px"
    fontWeight: 400
    lineHeight: "1.4"
  body-md:
    fontFamily: "duolingo-sans"
    fontSize: "17px"
    fontWeight: 400
    lineHeight: "24px"
  label-md:
    fontFamily: "duolingo-sans"
    fontSize: "13px"
    fontWeight: 400
    lineHeight: "1.4"
  button:
    fontFamily: "duolingo-sans"
    fontSize: "15px"
    fontWeight: 700
    lineHeight: "1.4"
    letterSpacing: "0.8px"
rounded:
  none: "0px"
  lg: "12px"
  full: "9999px"
spacing:
  unit: "8px"
  1: "16px"
  2: "24px"
  3: "40px"
  4: "48px"
  5: "72px"
  6: "96px"
components:
  button-secondary:
    backgroundColor: "#ffffff"
    textColor: "#1cb0f6"
    typography: "{typography.button}"
    rounded: "12px"
    height: "50px"
    padding: "0px 16px"
---

# duolingo.com

## Overview

Duolingo - The world’s most popular way to learn: Free, fun, and effective courses in languages and more. Learn with quick, science-based lessons personalized to you.

Soft, well-rounded controls, flat surfaces separated by hairlines, restrained display type at 32px / 700, a single green accent on neutrals. The site ships in light mode by default. Measured from 6000 rendered elements at 1440px wide on 2026-10-28.

Reference screenshots live beside this file; look at them before writing any layout, they carry the composition, density and image treatment that tokens cannot:

- `screenshots/desktop-1440-fold.png`: Desktop 1440, above the fold
- `screenshots/desktop-1440-full.jpg`: Desktop 1440, full page
- `screenshots/brand-logo.png`: primary logo lockup
- `screenshots/brand-icon-1.png`: representative interface icon
- `screenshots/brand-icon-2.png`: representative interface icon
- `screenshots/brand-icon-3.png`: representative interface icon
- `screenshots/brand-icon-4.png`: representative interface icon
- `screenshots/media-icon-1-source-hd.png`: representative interface icon / high-resolution source capture
- `screenshots/media-icon-2-source-hd.png`: representative interface icon / high-resolution source capture
- `screenshots/media-icon-3-source-hd.png`: representative interface icon / high-resolution source capture
- `screenshots/media-icon-4-source-hd.png`: representative interface icon / high-resolution source capture
- `screenshots/region-r1-context.jpg`: r1 context: page context
- `screenshots/region-r1-detail.png`: r1 detail: native-resolution local detail
- `screenshots/region-r2-context.jpg`: r2 context: page context
- `screenshots/region-r2-detail.png`: r2 detail: native-resolution local detail
- `screenshots/laptop-1024-fold.png`: Laptop 1024, above the fold
- `screenshots/tablet-768-fold.png`: Tablet 768, above the fold
- `screenshots/phone-390-fold.png`: Phone 390, above the fold
- `screenshots/phone-390-full.jpg`: Phone 390, full page
- `screenshots/media-logo-upscaled.png`: primary logo lockup / upscaled.png
- `screenshots/media-logo-transparent.png`: primary logo lockup / transparent.png
- `screenshots/media-logo-optimized.webp`: primary logo lockup / optimized.webp
- `screenshots/media-icon-1-upscaled.png`: representative interface icon / upscaled.png
- `screenshots/media-icon-1-transparent.png`: representative interface icon / transparent.png
- `screenshots/media-icon-1-optimized.webp`: representative interface icon / optimized.webp
- `screenshots/media-icon-2-upscaled.png`: representative interface icon / upscaled.png
- `screenshots/media-icon-2-transparent.png`: representative interface icon / transparent.png
- `screenshots/media-icon-2-optimized.webp`: representative interface icon / optimized.webp
- `screenshots/media-icon-3-upscaled.png`: representative interface icon / upscaled.png
- `screenshots/media-icon-3-transparent.png`: representative interface icon / transparent.png
- `screenshots/media-icon-3-optimized.webp`: representative interface icon / optimized.webp
- `screenshots/media-icon-4-upscaled.png`: representative interface icon / upscaled.png
- `screenshots/media-icon-4-transparent.png`: representative interface icon / transparent.png
- `screenshots/media-icon-4-optimized.webp`: representative interface icon / optimized.webp
- `screenshots/c-button-1--rest.png`: Button 1 ("Site language: English"), rest
- `screenshots/c-link-1--rest.png`: Text link 1 ("research shows that it w"), rest
- `screenshots/c-link-1--focus.png`: Text link 1 ("research shows that it w"), focus
- `screenshots/c-image-1--rest.png`: Image / figure 1, rest
- `screenshots/c-icon-1--rest.png`: Icon 1, rest
- `screenshots/c-button-2--rest.png`: Button 2 ("I ALREADY HAVE AN ACCOUN"), rest
- `screenshots/c-button-2--active.png`: Button 2 ("I ALREADY HAVE AN ACCOUN"), active
- `screenshots/c-nav-link-2--rest.png`: Navigation link 2 ("Get started"), rest
- `screenshots/c-nav-link-2--focus.png`: Navigation link 2 ("Get started"), focus

## Logo and icon references

Read `BRAND.md` for measured logo proportions, SVG treatments, representative icon crops and favicon declarations. Begin with `START_HERE.md` for a compact handoff; raw evidence is optional.

## Colors

| Token | Value | Use |
| --- | --- | --- |
| background | `#ffffff` | Page background |
| foreground | `#777777` | Primary text |
| primary | `#58cc02` | Candidate accent (semantic role inferred): Selected from measured button, link, text, painted-area and theme colors. It is not proof of a filled primary button; follow the observed component recipes. |
| on-primary | `#111111` | Text on the accent |
| secondary | `#1cb0f6` | Secondary accent (cyan) |
| border | `#e5e5e5` | Hairlines, dividers, input borders |

Full painted palette by area (largest first): `#ffffff`.

The accent `#58cc02` is used sparingly: primary buttons, links and focus rings. Everything else stays neutral.

## Typography

- **duolingo-sans** for h1, body, button: unknown source; use **Inter** as the stand-in if it does not load.
- **feather** for h2: unknown source; use **Inter** as the stand-in if it does not load.

See FONTS.md and fonts.css for source face/weight mappings, loading recipes, actual rendered-font evidence and explicit substitutions. Do not infer a Google Fonts family name from a site-specific alias.

| Role | Family | Size | Weight | Line height | Tracking |
| --- | --- | --- | --- | --- | --- |
| headline-display | duolingo-sans | 32px | 700 | 1.4 | normal |
| headline-lg | feather | 48px | 700 | 1.4 | normal |
| headline-md | duolingo-sans | 24px | 400 | 1.4 | normal |
| body-md | duolingo-sans | 17px | 400 | 24px | normal |
| label-md | duolingo-sans | 13px | 400 | 1.4 | normal |
| button | duolingo-sans | 15px | 700 | 1.4 | 0.8px |
- headline-display: observed (source h1); inferred fields: lineHeight.
- headline-lg: observed (source h2); inferred fields: lineHeight.
- headline-md: fallback (source h3); inferred fields: fontSize, fontFamily, fontWeight, lineHeight.
- label-md: fallback (source label); inferred fields: fontSize, fontFamily, fontWeight, lineHeight.
- button: observed (source button); inferred fields: lineHeight.

Type scale in use: 15px, 17px, 32px, 48px. Base body size 17px.

The hero heading (h1) renders at 32px / 700, center aligned, up to 480px wide. Sample: "The most fun way to learn languages, chess, and more!".

See REGIONS.md, regions.css and the region crops for nested surfaces, gradients, shadows and icon placement. These are local recipes; do not flatten them into site-wide averages.

## Layout

- Spacing unit: 8px. Scale in use: 16, 24, 40, 48, 72, 96 (px).
- Flex and grid gaps: 8, 16, 24, 32, 80, 104 px.
- Content max width: 988px, centred.
- Breakpoints: 530px, 700px, 768px, 1080px, 1160px.
- Header: 900px tall, static, background `rgba(0, 0, 0, 0)`; 12 nav links at 17px / 400 (Get started · Get started · English · Chess · Math · Spanish · French · German).

## Elevation & Depth

No box shadows in use; depth comes from hairline borders and surface tints (flat design).

## Shapes

- Buttons: 12px
- Inputs: 12px
- Cards and panels: 0px
- Images and media: 0px
- Radius scale: none 0px, lg 12px, full 9999px

## Components

### Button, secondary

Background transparent (it sits on `#ffffff`, so place it on that colour), text `#1cb0f6`, border 2px solid transparent, radius 12px, height 50px, padding 0px 16px, 15px / 700, uppercase. Sample label: "I ALREADY HAVE AN ACCOUN".

### Link

Colour `#ffffff`, no underline at rest, weight 700.

### Full inventory

`COMPONENTS.md` carries every component kind found on the page (7 of 87 in the checklist, 9 variants) with each state that was measured live (hover, keyboard focus, pressed, disabled, checked, filled, invalid, open: 3 state changes, 0 overlays opened) and a cropped screenshot of each; `components.css` is the same as a stylesheet. Read it before building any control. Summary:

| Component | Variants | States measured | Sample |
| --- | --- | --- | --- |
| Button | ghost-with-icon sm, outline | active | "Site language: English" |
| Text link | plain | focus | "research shows that it works" |
| Header / navbar | default | rest only | "Site language: EnglishThe most" |
| Navigation link | plain, plain | focus | "English" |
| Image / figure | aspect-4.26 | rest only |  |
| Icon | outline-14px | rest only |  |

Not on this page (do not invent them; if the build needs one, derive it from the nearest kind above): Icon button, Toggle / segmented control, Button group, Floating action button, Close / dismiss button, Text input, Search field, Textarea, Select (native), Combobox / custom select, Checkbox, Radio, Switch / toggle, Range slider, File input / dropzone, Date / time input, Input with attached button or addon, Field label, Help / hint text, Validation error text, Fieldset / form section, Menu / dropdown trigger, Breadcrumb, Tabs, Pagination, Stepper / progress steps, Sidebar navigation, Footer, Footer link, Skip link, Back to top, Social icon links, Theme toggle, Language / region switch, Tooltip, Popover, Dropdown menu, Dialog / modal, Drawer / sheet / off-canvas, Toast / snackbar, Banner / announcement bar, Cookie / consent notice, Lightbox / media viewer, Badge / pill / tag, Chip (removable / selectable tag), Alert / callout, Progress bar, Spinner / loader, Skeleton / shimmer, Counter / notification dot, Empty state, Rating / stars, Card, Pricing card / plan, Feature item (icon + title + text), Testimonial / quote card, Stat / metric, Styled list, List row / menu row, Table, Table row, Accordion / disclosure, Avatar, Avatar stack, Divider, Code block / inline code, Keyboard key, Blockquote, Video / media embed, Carousel / slider, Logo strip, Eyebrow / kicker, FAQ block, Call-to-action band, Newsletter / signup form, Search results / listing row, Hero, Content container, Grid of items, Sticky bar.

## Dark Mode

No dark mode responded to prefers-color-scheme, a theme toggle, or a root class/attribute.

## Responsive Behavior

| Viewport | Content width | Gutter | Body | H1 | Header | Hero | Grids | Buttons |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| desktop 1440px | 988px | 226px | 17px | 32px, 2 lines, center | 900px, 1 links | text only | 2→1 col; 4→1 col; 2→1 col | content-width |
| laptop 1024px | 452px | 283px | 17px | 32px, 2 lines, center | 894px, 1 links | text only | 2→1 col | content-width |
| tablet 768px | 452px | 155px | 17px | 32px, 2 lines, center | 1024px, 1 links | text only | 2→1 col; 2→1 col | content-width |
| phone 390px | 345px | 25px | 17px | 32px, 6 lines, center | 844px, 1 links | text only | 2→1 col | 2 full-width |

- H1 goes 32px → 32px (100%), 2 → 6 lines.
- No hamburger observed at 390px; 1 navigation links remain visible.
- Body text is 17px at the sampled desktop and phone widths.
- Phone side gutter 25px.
- 2 buttons stretch full-width on phones.
- Section top padding 96px → 96px.

## Interaction & Motion

2 elements carry transitions; typical 0.3s with ease, mostly on transform, border-color. No running keyframe animations at rest.

- Hover on button-secondary ("I ALREADY HAVE AN ACCOUNT"): no visible change; cursor pointer.
- Hover on nav-link ("Get started"): no visible change; cursor pointer.
- Tooltip triggers exist (1 × title) but none opened on hover in the first viewport; title attributes fall back to the browser's native tooltip.
- No dropdown menus found in the header.
- No scroll-reveal: content is visible without scrolling into view.

Full detail (every overlay, table, form, scroll and text rule measured) is in `BEHAVIOR.md`; raw evidence in `evidence.json`.

## Do's and Don'ts

- Treat the 8px spacing base as an inference. Preserve measured regional and component padding and gaps, including values outside that scale.
- Use `#58cc02` where supported by measured component or regional evidence; its accent role is inferred.
- Do keep body text at 17px in duolingo-sans.
- Do match corner radii per element class (buttons 12px, cards 0px); do not pick one radius for everything.
- No global shadow was sampled. Inspect regional/component recipes and screenshots before treating a local surface as flat.
- Preserve gradient stops and layer order from regional/component recipes or the global samples above. A missing CSS gradient does not prove an image-backed effect is absent; inspect its pixels.
- Don't rebuild from the tokens alone; open the screenshots for composition, density and image treatment.
- Note: Page background comes from body; large surface colors remain in the palette.
- Note: Body text contrast is 4.5:1 against the page background (below 4.5:1).
