Twitch

Twitch's iOS app is a live-first surface built on a near-black canvas (#0E0E10) that keeps the focus on streamer video and the constant motion of ch

Back to all styles

A live page in this style is not built yet — the CSS variables and the prompt below are enough to reproduce it.

At a glance

18tokens
10type steps
3radius steps
4pxspacing base

Twitch, in one page

Twitch's iOS app is a live-first surface built on a near-black canvas (#0E0E10) that keeps the focus on streamer video and the constant motion of chat. The background is a true near-black with the faintest cool tint, and elevated surfaces (#18181B, #1F1F23) step up in cool grays so cards, the chat column, and sheets separate without borders. The interface is dense and kinetic: thumbnails are live previews, viewer counts tick, the LIVE pill pulses, and chat scrolls continuously. The chrome is deliberately quiet so the energy comes from content and community.

The accent system is a duo with strict roles. Twitch Purple (#9146FF) is the brand and primary-action color — Follow, Subscribe, the active tab, links, and focus. Live Red (#EB0400) is reserved exclusively for liveness — the "● LIVE" pill and the now-live indicator. The two never blur: purple is "act," red is "this is happening right now." Everything else is white, cool gray, or near-black. This split is the core of Twitch's visual language — community action vs. live status.

Typography is Roobert (Twitch's brand typeface), rendered here with an Inter fallback that keeps its rounded-grotesque warmth. The hierarchy is compact and functional: 11-28pt at weights 400 / 600 / 700. There are no oversized editorial headlines — the live video and the streamer's thumbnail are the spectacle. Type labels and identifies: stream titles at 15-16pt weight 600, channel names at 14-15pt weight 700, metadata (game, viewers) at 12-13pt weight 400 in gray, section headers at 20-22pt weight 700. The most expressive type moment is the channel page, where the streamer's display name sits at 22pt weight 700 beside a live avatar ring.

Key Characteristics:

Do's and don'ts

Do

  • Use #0E0E10 near-black canvas — faint cool tint, quiet chrome so content/chat carry energy
  • Keep the color split strict: Twitch Purple (#9146FF) = brand/action; Live Red (#EB0400) = liveness only
  • Use off-white #EFEFF1 for primary text — softer than pure white for long chat reading
  • Put the red "● LIVE" pill top-left and the black viewer-count pill bottom-left on live thumbnails
  • Encode presence in the avatar ring — purple normally, red when currently LIVE
  • Keep chat dense (4pt lines) and let live cards breathe (16pt gaps)
  • In theater/landscape, float chat as a blurred 72%-opaque overlay on the right
  • Make the active tab purple (icon + label) — purple is the indicator
  • Treat emotes as first-class type tokens, baseline-aligned

Don't

  • Don't use pure black #000000 for the app canvas — that's the theater/player surface only
  • Don't use Live Red for anything except liveness — it must always mean "happening now"
  • Don't use Twitch Purple for the LIVE state — purple is action/brand, never status
  • Don't use pure white #FFFFFF for body text — #EFEFF1 is the intentional softer choice
  • Don't use thin or medium weights — Roobert here is 400 / 600 / 700 only
  • Don't space chat loosely — community throughput depends on tight 4pt lines
  • Don't introduce visible card borders — elevation is cool-gray surface-step + translucency
  • Don't over-animate — card scale is subtle (1.03); the continuous motion is the LIVE pulse and chat scroll only

Copy this into your AI builder

Paste it as-is. Every value below was measured from the original site, not guessed.

Assembled from the measured tokens — the source document has no prompt block.

Build a page in the Twitch design language. Follow the measured tokens below — do not substitute your own palette.

Colors:
- Twitch Purple: #9146ff
- Purple Pressed: #772ce8
- Live Red: #eb0400
- Live Red Pressed: #c20300
- Canvas: #0e0e10
- Deep Black: #000000
- Surface 1: #18181b
- Surface 2: #1f1f23
- Surface 3: #2a2a2d
- Divider: #2a2a2d

Type:
- families: Roobert, Fallback Stack, Numerals
- scale: 10, 11, 12, 13, 14, 15, 16, 20, 22
- weights: 400, 600, 700

Shape:
- radius: 4, 6, 8
- elevation: Shadow: `rgba(145,70,255,0.35) 0 6px 18px` on the channel-page primary CTA

Spacing: 4, 8, 16

Rules:
- Use `#0E0E10` near-black canvas — faint cool tint, quiet chrome so content/chat carry energy
- Keep the color split strict: Twitch Purple (`#9146FF`) = brand/action; Live Red (`#EB0400`) = liveness only
- Use off-white `#EFEFF1` for primary text — softer than pure white for long chat reading
- Put the red "● LIVE" pill top-left and the black viewer-count pill bottom-left on live thumbnails
- Encode presence in the avatar ring — purple normally, red when currently LIVE
- Keep chat dense (4pt lines) and let live cards breathe (16pt gaps)

Avoid:
- Don't use pure black `#000000` for the app canvas — that's the theater/player surface only
- Don't use Live Red for anything except liveness — it must always mean "happening now"
- Don't use Twitch Purple for the LIVE state — purple is action/brand, never status
- Don't use pure white `#FFFFFF` for body text — `#EFEFF1` is the intentional softer choice
- Don't use thin or medium weights — Roobert here is 400 / 600 / 700 only
- Don't space chat loosely — community throughput depends on tight 4pt lines

Keep every value literal. If a token is given, use that exact value.

The specification

Colour paletteRead the full spec

Primary

  • Twitch Purple (#9146FF): Brand color, primary CTA (Follow / Subscribe), active tab icon + label, links, focus ring, live avatar ring.
  • Purple Pressed (#772CE8): Pressed/active state for purple CTAs and toggles.
  • Purple Glow (rgba(145,70,255,0.35)): Soft glow under the primary CTA and around a focused live card.

Liveness (Reserved)

  • Live Red (#EB0400): The "● LIVE" pill and now-live indicator — used for nothing else.
  • Live Red Pressed (#C20300): Pressed state if the LIVE pill is interactive (jump-to-live).

Canvas & Surfaces

  • Canvas (#0E0E10): Primary near-black app background — faint cool tint.
  • Deep Black (#000000): Full-screen / theater video background.
  • Surface 1 (#18181B): Card backgrounds, sheets, the chat column, elevated rows.
  • Surface 2 (#1F1F23): Higher elevation — modals, active rows, chat input, chip default.
  • Surface 3 (#2A2A2D): Pressed state on dark surfaces, hairline divider tone.
  • Divider (#2A2A2D): 1pt separators between settings rows and list blocks.

Text

  • Text Primary (#EFEFF1): Stream titles, channel names, screen headers (intentionally off-white, not pure #FFFFFF).
  • Text Secondary (#ADADB8): Metadata (game · viewers), descriptions, section subtitles.
  • Text Tertiary (#6F6F7B): Disabled labels, very low-emphasis captions, placeholder text.

Semantic

  • Online Green (#00C16E): "Online" presence dot on the Following list (channel currently up but not the LIVE pill).
  • Mention Purple Tint (rgba(145,70,255,0.20)): Highlighted chat message background when you're @mentioned.
  • Sub Badge Gradient (#9146FF → #772CE8): Subscriber-badge accent in chat.
  • Error Red (#EB0400): Playback errors, stream-offline, connection-lost (shares the live red hue).

Light Mode (Limited Use)

Twitch's iOS app is effectively dark-only — the live-streaming atmosphere depends on the near-black canvas. A light variant is not part of the core product.

  • Light Canvas (#FFFFFF)
  • Light Text (#0E0E10)
Type scaleRead the full spec

Font Family

  • Primary: Roobert (Twitch brand typeface) — rounded grotesque with friendly terminals
  • Fallback Stack: 'Inter', -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif
  • Numerals: Tabular figures for viewer counts, timestamps, and follower totals

Hierarchy

RoleFontSizeWeightLine HeightLetter SpacingNotes
Screen Title (Large)Roobert28pt7001.15-0.4pt"Browse", "Following" large nav title
Channel Name (Hero)Roobert22pt7001.2-0.3ptStreamer display name on channel page
Section HeaderRoobert20pt7001.2-0.3pt"Live channels", "Recommended"
Stream TitleRoobert16pt6001.25-0.1ptStream/VOD title on a card or channel
Channel LabelRoobert15pt7001.25-0.1ptChannel name under a card
BodyRoobert15pt4001.450ptStream "About", panel text
Chat MessageRoobert14pt4001.350ptChat line body (username bolded inline)
Chat UsernameRoobert14pt7001.350ptColored display name in a chat line
MetadataRoobert13pt4001.30pt"Just Chatting · 12.4K viewers"
Card SubtitleRoobert12pt4001.30ptGame/category line under a thumbnail
Label (UPPER)Roobert11pt7001.20.6pt"LIVE CHANNELS" eyebrow labels
Button (Primary)Roobert15pt7001.00.2ptPurple "Follow" / "Subscribe"
Button (Secondary)Roobert14pt6001.00pt"Following", outline buttons
Tab LabelRoobert10pt6001.00.2ptBottom tab bar labels
BadgeRoobert11pt7001.00.4pt"LIVE", viewer-count pill, sub badge

Principles

  • Weights concentrated at 400 / 600 / 700: Regular for body/metadata/chat, semibold for titles, bold for names, headers, CTAs — no thin, no medium, no black
  • Off-white primary text: #EFEFF1, not pure #FFFFFF — softer on the near-black canvas for long chat-reading sessions
  • Density for community: No hero display type; live video + scrolling chat are the energy
  • All-caps only for eyebrows and the LIVE badge: never for titles or chat
  • Color split is structural: purple = action/brand, red = liveness — never decorative, never swapped
Components and layoutRead the full spec

Buttons

Primary CTA (Follow / Subscribe — The Purple Button)

  • Shape: Rounded rectangle, height 40pt (auto-width) or full-width on sheets
  • Background: #9146FF
  • Text: #FFFFFF
  • Icon: optional SF Symbol heart.fill (Follow) / star.fill (Subscribe) 14pt leading, #FFFFFF
  • Corner radius: 6pt
  • Font: Roobert 15pt weight 700, letter-spacing 0.2pt
  • Shadow: rgba(145,70,255,0.35) 0 6px 18px on the channel-page primary CTA
  • Pressed: background #772CE8, scale 0.97, with .impactOccurred(.light) haptic

Following / Subscribed (active state)

  • Background: #1F1F23
  • Text: #EFEFF1 with a small leading checkmark or heart.fill in #9146FF
  • Height: 40pt, corner radius 6pt
  • Font: Roobert 14pt weight 600
  • Pressed: background #2A2A2D

Icon Actions (Share, Notifications bell, More)

  • Size: 22pt glyph, 44pt hit area
  • Default: #ADADB8
  • Active: #9146FF (notifications on, in a clip)
  • Layout: trailing the channel header, 20pt gap

Live / Jump-to-Live Pill (interactive variant)

  • Background: #EB0400
  • Content: white ● dot + "LIVE", Roobert 11pt weight 700 uppercase
  • Height: 22pt, corner radius 4pt, horizontal padding 8pt
  • Pressed: #C20300

Text Button ("See all")

  • Font: Roobert 13pt weight 600
  • Color: #ADADB8
  • No underline, 44pt hit area, trailing each section header

Cards & Containers

Live Thumbnail Card (Horizontal rail / grid)

  • Width: 280pt (rail) or full-width minus margins (grid 1-col)
  • Aspect: 16:9 live preview
  • Corner radius: 6pt on the thumbnail
  • Overlays on the thumbnail: red "● LIVE" pill top-left, viewer-count pill (rgba(0,0,0,0.6) + white ● 12.4K) bottom-left
  • Below: avatar (32pt circle) + stream title (16pt w600, 2-line clamp) + channel name (13pt w400 #ADADB8) + game/category tag (12pt w400 #ADADB8)
  • Press: scale 1.03 with focus lift rgba(0,0,0,0.5) 0 12px 28px and a subtle purple ring; thumbnail begins live preview after ~600ms

Channel Card (compact, Following list)

  • Layout: 44pt circular avatar with a 2pt purple ring (red ring if currently LIVE) → display name (15pt w700) + "playing Game · 8.1K" (13pt w400 #ADADB8) → trailing red LIVE pill or gray "offline" time
  • Background: transparent (#0E0E10), pressed #18181B
  • Height: 64pt

Stream View (video + docked chat)

  • Top: 16:9 video player (full-bleed width), tap to reveal controls over a rgba(0,0,0,0.5) scrim
  • Under video: channel bar — avatar + name + Follow/Subscribe purple CTA + viewer count + LIVE pill
  • Below: docked chat column filling the rest of the screen — continuously scrolling messages on #18181B, chat input pinned at the bottom
  • Landscape/theater: video goes full-screen and chat becomes a semi-transparent overlay on the right (rgba(14,14,16,0.72) with blur)

Chat Message Row

  • Layout: inline badges (sub/mod/verified) → colored username (14pt w700, user's chosen chat color) → ": " → message body (14pt w400 #EFEFF1) → inline emote chips
  • Padding: 4pt vertical, 12pt horizontal; no row background by default
  • @mention to you: row background rgba(145,70,255,0.20) with a 2pt leading purple bar
  • Emote: 24-28pt inline image token, baseline-aligned

Chat Input

  • Background: #1F1F23, height 44pt, corner radius 8pt
  • Leading emote-picker icon (face.smiling) 20pt #ADADB8, trailing send/paperplane.fill (purple when text present)
  • Placeholder: "Send a message", 15pt w400 #ADADB8

Navigation

Bottom Tab Bar

  • Height: 52pt + safe area
  • Background: rgba(14,14,16,0.94) with .regularMaterial blur
  • Tabs: Following, Browse, Search, Notifications, Profile
  • Icon size: 24pt
  • Active color: #9146FF (icon + label both turn purple — purple is the indicator)
  • Inactive: #ADADB8
  • Labels: Roobert 10pt w600, always shown
  • Active tab icon: filled SF Symbol; inactive: outlined
  • Notifications tab: red dot badge when unread

Channel Header

  • 48pt + safe area, transparent over the video; back chevron left, Share + More right
  • On scroll into the channel page: solid rgba(14,14,16,0.94) with display name centered

Player Controls Overlay

  • Tap video → controls fade in over rgba(0,0,0,0.5)
  • Center: 56pt circular rgba(255,255,255,0.16) play/pause; for live, a "● LIVE / jump to live" pill replaces the scrubber's end
  • Bottom: live progress is a thin red line at the live edge; for VODs, a purple scrubber (2pt track rgba(255,255,255,0.3), #9146FF fill, 14pt thumb)
  • Top: title + close; bottom-right: quality, captions, chat-toggle, AirPlay

Input Fields

Search Bar

  • Background: #1F1F23
  • Height: 44pt, corner radius 8pt
  • Leading SF Symbol magnifyingglass 18pt #ADADB8
  • Placeholder: "Search", 16pt w400 #ADADB8
  • Text color: #EFEFF1
  • Focus: 1.5pt #9146FF ring

Category / Filter Chip

  • Background: #1F1F23 default / #9146FF selected
  • Text: #EFEFF1 default / #FFFFFF selected
  • Height: 36pt, corner radius 500pt (full pill), horizontal padding 16pt
  • Font: Roobert 14pt weight 600

Distinctive Components

Live Chat Overlay

Responsive behaviourRead the full spec

Device Sizes

DeviceWidthKey Changes
iPhone SE (3rd gen)375pt240pt rail cards; 1-col browse grid
iPhone 13/14/15390ptStandard 280pt rail cards
iPhone 15/16 Pro393ptDynamic Island accommodated in transparent channel header
iPhone 15/16 Pro Max430pt320pt rail cards; chat column taller in stream view
iPad768pt+2-3 col browse grid; stream view = video + persistent side chat column

Dynamic Type

  • Stream titles, channel names, chat messages, "About": full scale
  • Card subtitle / metadata / viewer pills: scales but clamps at +2 steps (layout-sensitive)
  • LIVE pill, tab labels, scrubber times: fixed (never scale)
  • Chat: respects Dynamic Type but caps growth to keep throughput readable

Orientation

  • Following / Browse / Search / Channel: portrait-locked
  • Stream view: rotates to landscape → theater mode — video full-screen, chat becomes the overlay
  • Clips player: rotates to landscape

Touch Targets

  • Follow / Subscribe CTA: 40pt height — generous tap
  • Live cards: full-card tappable, ≥ 110pt tall hit
  • Channel rows: 64pt height, full-row tappable
  • Chat send / emote picker: 44pt hit area
  • Tab bar icons: 24pt icon, 44pt effective hit

Safe Area Handling

  • Top: transparent channel header respects safe area / Dynamic Island over the video
  • Bottom: tab bar floats above home indicator; chat input docks above it; theater overlay insets from edges
  • Sides: 16pt content margins; rails bleed to the right edge intentionally

Drop-in CSS variables

The same values as a theme block. Add the class to <body> and the site repaints.

body.theme-twitch {--page-bg: #0e0e10;
  --page-bg-gradient: none;
  --text-color: #efeff1;
  --heading-color: #efeff1;
  --link-color: #9d5aff;
  --link-hover-color: #7f27ff;
  --border-color: #373739;
  --card-bg: #0e0e10;
  --card-shadow: 0 1px 2px rgba(239,239,241,0.06);
  --card-hover-shadow: 0 6px 18px rgba(239,239,241,0.12);
  --header-bg: #212123;
  --header-text-color: #ffffff;
  --header-shadow: none;
  --footer-bg: #0e0e10;
  --footer-text-color: #a0a0a2;
  --button-bg: #9146ff;
  --button-text-color: #ffffff;
  --button-hover-bg: #7313ff;
  --button-border: none;
  --button-border-radius: 6px;
  --button-secondary-bg: #1c1c1e;
  --button-secondary-text-color: #efeff1;
  --button-secondary-hover-bg: #29292b;
  --button-secondary-border: 1px solid #373739;
  --prompt-bg: #19191b;
  --prompt-text-color: #efeff1;
  --base-font: var(--font-sans);
  --heading-font: var(--font-sans);
  --card-border-radius: 6px;
}

Download theme.css

Visually close to

Measured with a deterministic colour + geometry comparison across 958 styles. Not a hand-picked list.

Where this came from

Source document
ios/design-md/video/twitch/DESIGN.md · 22.3 KB
Repository
Meliwat/awesome-ios-design-md
Licence
MIT

Source text is reproduced under its original licence. Tokens, similarity scores and page structure are ours.