diff --git a/.claude/skills/icp-brand-design/SKILL.md b/.claude/skills/icp-brand-design/SKILL.md index fd7567e9..1955b387 100644 --- a/.claude/skills/icp-brand-design/SKILL.md +++ b/.claude/skills/icp-brand-design/SKILL.md @@ -1,15 +1,11 @@ --- name: icp-brand-design -description: "ICP / DFINITY visual design system: tokens, color, typography, layout, components, motion, iconography, and accessibility for surfaces under the DFINITY or Internet Computer (ICP) mark. Pairs with icp-brand-voice (positioning, voice, vocabulary). Use when building or reviewing the visual side of products (NNS, ICP.app, Internet Identity, dashboards), the main website, developer docs, marketing material, or internal tools. Enforces the Anthropic-inspired visual system from skills.internetcomputer.org: Newsreader 500 serif headings, parchment palette, terracotta accent, light mode default, dark mode opt-in. Triggers: ICP design, DFINITY design, ICP visual style, brand tokens, is this on brand visually, design review ICP, color palette, typography ICP, component library, NNS redesign. Products with their own brand identity (OISY, Caffeine, and future ecosystem products with their own visual systems) are out of scope." -license: MIT -metadata: - version: '1.0' - source: https://skills.internetcomputer.org - author: Pierre Samaties - pairs_with: icp-brand-voice +description: "ICP / DFINITY visual design system v2: tokens, color, typography, layout, components, accessibility for DFINITY and Internet Computer surfaces. Pairs with icp-brand-voice. Use when building or reviewing visual surfaces (NNS, ICP.app, Internet Identity, dashboards, the main website, developer docs, marketing). Enforces the system that ships on internetcomputer.org: three faces (Newsreader, Inter, JetBrains Mono), single rust accent, light editorial parchment as the default theme with an opt-in dark theme for product surfaces that need it, sentence case, italic for asides only, no em-dashes (U+2014), tamperproof spelled as one word. Triggers: ICP design, DFINITY design, brand tokens, design review ICP, color palette, typography ICP, NNS redesign, light or dark mode ICP. OISY, Caffeine, and ecosystem products with their own brand are out of scope." --- -# ICP / DFINITY Brand Design +# ICP / DFINITY Brand Design v2.2 + +**Current version:** v2.2 (2026-05-08). See the Changelog section at the bottom for history. Every change to this skill bumps the minor version and adds a line to the changelog. ## When to Use This Skill @@ -21,7 +17,7 @@ Load this skill when the user works on any **visual** surface under the DFINITY - **Marketing material**: landing pages, campaign pages, investor pages, press pages, decks - **Reviews**: design reviews, brand checks, compliance audits, PR or mockup reviews -Also load when the user says "make this on brand visually", "ICP style", "DFINITY look", "brand tokens", "Anthropic-style but for ICP". +Also load when the user says "make this on brand visually", "ICP style", "DFINITY look", "brand tokens", "match the website". For **what to say** (positioning, voice, vocabulary), load `icp-brand-voice`. The two skills are designed to be used together. @@ -34,140 +30,380 @@ Do NOT use this skill for: ## North Star -Every DFINITY product should feel like it came from the same studio: quiet, editorial, confident. The reference implementation is [skills.internetcomputer.org](https://skills.internetcomputer.org). +Every DFINITY product should feel like it came from the same studio: editorial, factual, calm. The reference implementation is the **ICP Brand Guidelines v2** site (link in `Resources` below) and the live `internetcomputer.org`. -Two non-negotiables: +Three non-negotiables: -1. **Light mode is the default.** Dark mode is opt-in per product via `data-theme="dark"` on the root. Never use `prefers-color-scheme` to auto-switch. -2. **One accent color per page.** Terracotta / ember only. No green, blue, or secondary brand colors. +1. **Light editorial parchment is the default theme.** This matches the live site, which ships light only today. A dark theme is documented and available as opt-in via `data-theme="dark"` on ``, for product surfaces that genuinely benefit from one (NNS late-night use, dashboards, terminal-style developer tools). Marketing and the main site stay on the light default. Never auto-switch on `prefers-color-scheme`. +2. **One primary accent on a page: rust `#a8482b`.** Section stripes (the small set below) are scoped strictly to category coding, never on body text, CTAs, or emphasis. +3. **Three faces, three roles.** Newsreader for what you read. Inter for what you click. JetBrains Mono for what the system reports. No other typefaces. ## Instructions ### 1. Load the tokens -Use `assets/tokens.css` as the single source of truth for color, type, spacing, and radii. Ship it untouched, or mirror the same values into your framework config. +Use `assets/tokens.css` as the single source of truth for color, type, spacing, radii, and themes. Ship it untouched, or mirror the same values into your framework config. ```html ``` -Never redefine the accent, background, or text colors with hex values in product code. Always reference the CSS custom properties (`var(--icp-bg)`, `var(--icp-fg)`, `var(--icp-accent)`, etc.). +Never redefine the accent, background, or text colors with literal hex values in product code. Always reference the CSS custom properties (`var(--icp-bg)`, `var(--icp-fg)`, `var(--icp-accent)`, etc.). + +The tokens file ships the light theme at `:root` (so it loads by default with no attribute) and the dark theme under `[data-theme="dark"]` (opt-in). ### 2. Color -**Light (default)** - -| Role | Token | Hex | Notes | -| ------------- | ------------------ | --------- | ------------------------------------------ | -| Page bg | `--icp-bg` | `#f8f5ef` | parchment, never pure white | -| Elevated bg | `--icp-bg-elev` | `#fdfaf3` | cards, code headers, inputs | -| Text | `--icp-fg` | `#1a1714` | ink, never pure black | -| Muted text | `--icp-muted` | `#6b6660` | captions, meta | -| Rule | `--icp-rule` | `#e5ddcf` | 1px hairlines, dividers | -| Accent | `--icp-accent` | `#cc5a2b` | terracotta, the one and only brand color | -| Accent dim | `--icp-accent-dim` | `#f2d7c7` | blush, callout backgrounds | -| Code bg | `--icp-code-bg` | `#efe8da` | sand | - -**Dark (opt-in)** - -| Role | Hex | Notes | -| ------------- | --------- | -------------------------------------- | -| Page bg | `#14110d` | deep bark, never pure black | -| Elevated bg | `#1b1812` | bark | -| Text | `#f0ebe0` | bone | -| Muted | `#a29a8d` | ash | -| Rule | `#2d2820` | soil | -| Accent | `#ff7a4d` | ember (warmer for dark surfaces) | -| Accent dim | `#3a2218` | hearth | - -**Rules** - -- One accent color per page. Terracotta / ember only. No green, blue, or secondary brand colors. +#### Primary accent (one and only) + +| Token | Light (default) | Dark (opt-in) | Notes | +| ---------------------- | --------------- | ------------- | ------------------------------ | +| `--icp-accent` | `#a8482b` | `#c25a37` | rust, the single brand color | +| `--icp-accent-strong` | `#8e3b22` | `#d96a45` | hover, focus ring | +| `--icp-accent-dim` | rgba 0.10 | rgba 0.16 | accent washes only | + +The accent paints heading emphasis words, key inline terms, primary CTA fills, and focus rings. Body text, nav, and chrome stay in `--icp-fg`. Never use the accent on chart fills, banners, large blocks, or anything where it would compete with itself across the page. + +**Accent scope rule (strict).** The accent is for **single words or short phrases only**: one emphasis word in a heading, an inline term inside a paragraph, a CTA label, an indicator dot, a focus ring. **Never on a full sentence, a full subtitle, a full paragraph, or any block of text.** If more than a short phrase is in the accent, the design is wrong. The test, the accent should always read as a precise pointer, never as a paint job. If a designer asks "can I make the whole subtitle rust to make it stand out", the answer is no, use weight or hierarchy instead, the accent stays scoped. + +The dark accent is warmed to `#c25a37` because the same rust at `#a8482b` does not pass AA on a dark surface for small UI text. Both values resolve to `var(--icp-accent)` once the theme is set. + +#### Light theme (default, editorial parchment) + +Mirrors the live `internetcomputer.org` exactly. + +| Role | Token | Value | Notes | +| ---------------- | ---------------------- | ---------- | -------------------------------------- | +| Page bg | `--icp-bg` | `#faf9f5` | parchment, never pure white | +| Sunk bg | `--icp-bg-sunk` | `#f3f1ea` | alternating sections, sunk panels | +| Elevated bg | `--icp-bg-elev` | `#ffffff` | small lift for cards that read as raised | +| CTA bar bg | `--icp-bg-cta-inverse` | `#1a1a1a` | near-black inversion (deliberate) | +| Card bg | `--icp-bg-card` | `#ffffff` | | +| Foreground | `--icp-fg` | `#1a1a1a` | ink, never pure black | +| Body text | `--icp-fg-body` | `#1a1a1a` | same as fg, the live site uses one ink | +| Secondary | `--icp-fg-secondary` | `#4b4943` | meta strips, secondary copy | +| Muted | `--icp-fg-muted` | `#868078` | captions, attributions | +| Hairline | `--icp-rule` | `#e7e3da` | warm ivory hairline, not gray | +| Strong rule | `--icp-rule-strong` | `#4b4943` | hover underlines, emphasized borders | +| Grid line | `--icp-grid-line` | `rgba(26,26,26,0.04)` | the hero grid paper texture | + +#### Dark theme (opt-in, `[data-theme="dark"]`) + +For product surfaces that need a dark reading environment. The live site does not ship dark today, but the tokens are documented so a product can offer it later without diverging from the master system. + +| Role | Token | Value | Notes | +| ---------------- | ---------------------- | ---------- | -------------------------------------- | +| Page bg | `--icp-bg` | `#14110d` | deep bark, never pure black | +| Sunk bg | `--icp-bg-sunk` | `#1b1812` | alternating sections in dark | +| Elevated bg | `--icp-bg-elev` | `#1b1812` | card lift | +| CTA bar bg | `--icp-bg-cta-inverse` | `#ffffff` | flips to white on dark | +| Card bg | `--icp-bg-card` | `#1b1812` | | +| Foreground | `--icp-fg` | `#f0ebe0` | bone, never pure white | +| Body text | `--icp-fg-body` | `#f0ebe0` | | +| Secondary | `--icp-fg-secondary` | `#a29a8d` | | +| Muted | `--icp-fg-muted` | `#7a7367` | | +| Hairline | `--icp-rule` | `#2d2820` | soil | +| Strong rule | `--icp-rule-strong` | `#5a5446` | | +| Grid line | `--icp-grid-line` | `rgba(240,235,224,0.05)` | hero grid paper in dark | + +The CTA bar token always inverts the surface around it. In light mode it goes near-black, in dark mode it goes white. This is intentional: it gives the strongest call-to-action on the page a different visual register from everything else. + +#### Section stripes (category coding only) + +The live site uses three stripe colors today, scoped strictly to 3px card top stripes and category markers. They never appear on body text, CTAs, or running emphasis. Two additional muted accents are reserved in the tokens file for sections that do not yet exist on the live site, so a product can introduce them without inventing new colors. + +| Section role | Token | Light (default) | Dark (opt-in) | +| -------------------------------------------- | --------------------------- | --------------- | ------------- | +| Default / hero / page-level | `--icp-section-default` | rust `#a8482b` | ember `#c25a37` | +| Ecosystem, spotlight, governance | `--icp-section-teal` | `#0b5e5c` | `#2c8a85` | +| Build, docs, developers | `--icp-section-blue` | `#1c3d5a` | `#4a7da8` | + +Indicator dots (live tickers, status pills) use a brighter teal `#14938e` (`--icp-indicator-teal`) and the rust accent `--icp-indicator-rust`. + +Use a section stripe only where it earns the label. If a card or section does not belong to a category, it does not get a section stripe, the page-level rust is used instead. + +#### Surface rhythm: parchment, sunk parchment, grid paper + +The brand has **two parchment tones** plus **one near-invisible texture**. Together they let a long page breathe without resorting to boxes, shadows, color blocks, or gradients. Mirrors the live site exactly. + +**Parchment, the page default.** `--icp-bg` (`#faf9f5` light, `#14110d` dark). The default surface for every section. Body text reads on parchment, prose reads on parchment. + +**Sunk parchment, for alternating sections.** `--icp-bg-sunk` (`#f3f1ea` light, `#1b1812` dark). Use to differentiate adjacent sections on long pages, sunk panels, code-example wrappers, and any container that should read as recessed below the page surface. The contrast against parchment is small on purpose, the goal is rhythm, not visual weight. Always pair with a 1px hairline above and below for the section seam. + +**Grid paper, the hero texture.** Two crossed `linear-gradient` layers draw a 24x24px hairline grid in `--icp-grid-line` (4% ink on parchment, 5% bone on dark). Apply at 80% layer opacity, offset `-1px -1px`. This is the texture under the hero on `internetcomputer.org`. **The hero section must use the grid paper overlay.** It is not optional decoration, it is the brand's signature hero texture. Beyond the hero, use it on the occasional feature surface or editorial canvas. Never as a background for body prose. + +The tokens file ships two utility classes: + +```css +/* Apply directly to a container as the background. */ +.icp-grid-paper { ... } + +/* Apply as a positioned overlay layer (preferred, on a hero with content above). */ +.icp-grid-paper-overlay { ... } +``` + +When using the overlay variant, parent must be `position: relative` and `overflow: hidden`. Content sits above with `position: relative; z-index: 1;`. + +**Section rhythm pattern.** On long pages, alternate parchment with sunk parchment. Six sections becomes parchment / sunk / parchment / sunk / parchment / sunk. The hero gets the grid paper overlay on top of parchment. Hairlines remain at every section seam. + +**Do not.** + +- Do not increase the grid line opacity past 6% on either theme. The texture should read as paper grain, not a wireframe grid. +- Do not change the tile from 24px. Smaller tiles read as noise. Larger tiles read as graph paper. +- Do not invent a third parchment tone. Two is the system. If you need more contrast, the design needs an elevated card (`--icp-bg-elev`) or a hairline. +- Do not stack grid paper inside sunk parchment, the texture is for the parchment surface only. +- Do not apply grid paper to body prose. The contrast against text is fine for AA but reads visually noisy under long-form reading. + +#### Color rules + +- One primary accent on the page. Section stripes do not count as a second primary, they are 3px category labels. - No gradients on brand surfaces. Flat color. -- No pure `#000` text and no pure `#fff` backgrounds. +- No pure `#000` text in light mode and no pure `#fff` body text in dark mode (use `--icp-fg` and `--icp-fg-body`). - Hairlines are 1px in `--icp-rule`. No heavy borders. +- Card stripes are 3px (`--icp-card-stripe-w`), not 2px. Live-site value. +- Never invent a new accent. If the design needs another color, the design is wrong. ### 3. Typography -- **Serif (headings):** Newsreader, 500 weight, letter-spacing `-0.01em` to `-0.015em` for h1/h2. Fallback stack: `"Newsreader", "Source Serif 4", "EB Garamond", ui-serif, Georgia, serif`. -- **Sans (body, UI, labels):** Inter. Fallback: `"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`. -- **Mono (code):** system monospace stack. -- Body line-height `1.6`–`1.75`. Headings `1.15`–`1.25`. -- Headings in serif italic only for emphasis words inside an otherwise roman heading (see hero pattern on skills.internetcomputer.org). +The system has **three faces, each with one job**. + +| Face | Role | Token | Weight | Where it shows up | +| ------------- | ----------------------------------------------------------------- | ----------------- | ------------- | ------------------------------------------------------------------------ | +| Newsreader | Editorial: display, body, long-form reading | `--icp-serif` | 380 / 400 / 500 | Hero, all headings, body prose, callout text | +| Inter | UI chrome: things you click and navigate | `--icp-ui` | 400 / 500 / 600 | Top nav, eyebrows, button labels, footer, breadcrumbs | +| JetBrains Mono| Technical readouts: things the system reports | `--icp-mono` | 400 / 500 | Network stats, section markers (`§ 03`), card markers (`№ 01`), code | + +**Type scale** + +| Token | Value | Used for | +| -------------------- | ---------------------- | ------------------------------------- | +| `--icp-fz-h1` | `clamp(40px, 6.4vw, 86px)` | Hero, page-opener headlines | +| `--icp-fz-h2` | `36px` | Section headings | +| `--icp-fz-h3` | `24px` | Subsection / card titles | +| `--icp-fz-body` | `17px` | Default reading text | +| `--icp-fz-body-sm` | `15px` | Meta strips, dense panels | +| `--icp-fz-eyebrow` | `11px` | Inter UPPERCASE 0.18em eyebrows | +| `--icp-fz-marker` | `12px` | JetBrains Mono `§` and `№` markers | + +**Tracking and line-height** + +- Display Newsreader: `letter-spacing: -0.015em` (live-site value, `-1.29px` at 86px), `line-height: 1.05` to `1.15` +- Body Newsreader: tracking 0, `line-height: 1.55` +- Inter eyebrows: UPPERCASE, `letter-spacing: 0.18em`, weight 500 +- JetBrains Mono markers: UPPERCASE, `letter-spacing: 0.04em`, weight 400 to 500 + +**Casing** + +- **Sentence case** for all headlines, body, and prose. +- **UPPERCASE** is reserved for two specific patterns and only those two: Inter eyebrows above sections, and JetBrains Mono markers (`§ 01`, `№ 03`, metadata strips like `DEFAULT THEME · LIGHT`). +- Buttons and CTAs are UPPERCASE Inter at small sizes (11 to 13px), tracked. This matches the live site and is the one place Inter goes uppercase outside eyebrows. +- Match the live site's casing technique: write the source string in sentence case and apply UPPERCASE in the markup or class, not via `text-transform: uppercase`. This keeps screen-reader output natural. +- Proper nouns and acronyms (DFINITY, ICP, NNS) keep their natural case in any context. + +**Italic** + +- Newsreader italic carries a single emphasis word inside an otherwise roman headline ("Sovereign *frontier* cloud", "What *ICP* is"), captions, attributions, and asides. The emphasis word is colored in the rust accent on the live site. The italic word is always **the subject of the heading**, the noun or noun phrase the line is about, never a verb, copula, article, or connector. Test, can the heading still stand if the italic word is removed; if yes, the emphasis is on the wrong word. +- Never italic for stress in body copy. Never italic for entire paragraphs. + +**Weights** + +- Newsreader 380 for display (hero, the live-site value), 400 for body, 500 for emphasis inside body. +- Inter 400 for nav and most chrome, 500 for eyebrows and tab labels, 600 for primary button labels. +- JetBrains Mono 400 for markers and meta, 500 for stat numerals. +- Never bold (700+). 600 only on Inter button labels and rare inline emphasis. ### 4. Layout and spacing -- Container max width: `68rem` (~1088px). -- Prose max width: `48rem` (~768px). Never run body text wider. -- Horizontal gutter: `1.75rem` (28px). -- Generous vertical rhythm. Sections separated by 1px hairlines in `--icp-rule`, not boxes. +- **Container max width**: `1280px` (`--icp-container`). The live site uses this. +- **Prose max width**: `720px` (`--icp-prose`). Never run body text wider than this. +- **Horizontal gutter**: `32px` (`--icp-gutter`). +- **Section rhythm**: 144px between major sections (`--icp-space-section`), separated by 1px hairlines in `--icp-rule`. No boxes. +- **Vertical scale**: spacing tokens go 4 / 8 / 12 / 16 / 24 / 32 / 48 / 64 / 96 / 128 / 144. Use the tokens, not raw pixels. ### 5. Radii -- Inline code: `3px` -- Buttons, pre blocks, meta cards: `6px` -- Search bars, callout right-hand side: `8px` -- No pills, no fully rounded shapes anywhere except circular avatars. +- Inline code, mono badges: `3px` (`--icp-radius-inline`) +- Cards, code blocks, meta panels: `6px` (`--icp-radius-card`) +- Inputs, search bars: `8px` (`--icp-radius-input`) +- Pill CTAs only: `9999px` (`--icp-radius-pill`) + +Pills are scoped strictly to the CTA pattern. Cards, panels, and inputs never go fully rounded. Avatars are circular. ### 6. Iconography and imagery - Line icons, 1.5px stroke, rounded joins. No filled or duotone icons in product chrome. +- External-link affordance: trailing `↗` (U+2197) in Inter or JetBrains Mono. Never an SVG. - Photography is rare. When used, warm-toned, documentary, no stock illustrations. -- No 3D renders, no isometric illustrations, no crypto iconography. +- No 3D renders, no isometric illustrations, no crypto iconography (no chains, no shields, no padlocks). +- The DFINITY infinity logo is the only mark. Always paired with the wordmark in nav, never alone outside small avatar contexts. ### 7. Motion - Default transition: `0.15s ease` on `background`, `color`, and `border-color`. - No bounce, no slide-ins on load. Respect `prefers-reduced-motion`. +- Hover on links: color shifts to `--icp-accent`, no underline animation. + +### 8. Components -### 8. Components (mirror the reference) +Use these patterns directly. Never invent a new primary button, card, or callout without a brand review. -Use the component patterns from the brand guide directly. Never invent a new primary button, card, or callout without a review. Key patterns: +#### Pill CTA (primary) -- **Primary CTA**: terracotta fill, white text, `6px` radius, sans-serif, no shadow. -- **Secondary CTA**: transparent with 1px rule border, fg text. -- **Eyebrow label**: uppercase, `0.06em` letter-spacing, muted color, small caps feel. -- **Callout**: blush (`--icp-accent-dim`) left stripe on cream card. -- **Meta card**: cream bg, 1px rule, serif title, sans body. -- **List row**: 1px bottom hairline, serif label, muted right-hand value. -- **Code block**: sand background, mono, no syntax colors beyond fg + muted. -- **Trust banner**: row of monochrome logos, no boxes. +Rust fill, white text, fully rounded (`--icp-radius-pill`). Inter UPPERCASE 11 to 13px, weight 600, tracking 0.06em. Used as the single primary action on a page. + +``` +[ START AT OPENCLOUD.ORG ] +``` + +#### Pill CTA (inverse) + +White fill on near-black surfaces (CTA bar). Dark text, rust trailing arrow. Used inside the CTA bar pattern. + +``` +[ BROWSE THE LIBRARY → ] +``` + +#### Pill CTA (secondary) + +Outlined: 1px `--icp-rule-strong` border, transparent fill, foreground text, trailing arrow. Used beside a primary or as a standalone soft action. + +``` +( READ THE SOURCE → ) +``` + +#### CTA bar (inverse strip) + +Always near-black `#1a1a1a` background, regardless of theme. White Newsreader heading, white meta line, inverse pill or arrow CTA. This is the page's most assertive call to action and gets a different visual register from the rest of the surface. + +``` +┌──────────────────────────────────────────────┐ +│ JOIN THE FRONTIER │ +│ Create a sovereign cloud engine in minutes. │ +│ START → │ +└──────────────────────────────────────────────┘ +``` + +#### Editorial card + +3px top stripe in `--icp-section-default` (rust) by default, or a section stripe color when used inside a category. JetBrains Mono `№ 01` marker top-left. Newsreader 500 title, Newsreader 400 body. 1px hairline border, `--icp-radius-card` corners. + +#### Network stats ticker + +JetBrains Mono numerals at h2 size, Inter eyebrow caption beneath. Used for live metrics (block rate, query throughput, fault tolerance). Small indicator dot in `--icp-indicator-teal`. Never use Newsreader for stat numerals. + +#### Section marker + +`§ 01`, `§ 02`, etc. JetBrains Mono 12px, `--icp-fg-secondary`. Sits in the left gutter of a section, vertically aligned with the section heading. Same treatment as the live site. + +#### Card marker + +`№ 01`, `№ 02`, etc. Same face and size as section markers, used inside cards to enumerate sequence. + +#### Eyebrow (Inter) + +UPPERCASE, 11px, weight 500, tracking 0.18em, `--icp-fg-secondary`. Sentence case is broken here on purpose because it is system label, not editorial copy. + +#### Metadata strip + +Inter UPPERCASE label, JetBrains Mono value, separated by `·`. Example: `DEFAULT THEME · LIGHT`. Use for deck-style annotations beneath hero copy. + +#### "Ask how this works" pattern + +Inline soft prompt: `+ ASK HOW THIS WORKS –`. Inter UPPERCASE, hairline. Invites a chat or canister-call interaction without shouting. + +#### List row + +1px bottom hairline in `--icp-rule`, Newsreader label on the left, `--icp-fg-muted` value on the right. No boxes, no zebra stripes. + +#### Code block + +Sand background (`--icp-code-bg`), JetBrains Mono, no syntax colors beyond fg + muted. 6px radius. Never colorful syntax highlighting. ### 9. Accessibility -- WCAG AA contrast minimum. The palette is designed to pass; verify on every surface. +- WCAG AA contrast minimum on every surface. The light theme passes for `#1a1a1a` on `#faf9f5` at body sizes. The dark theme passes for `#f0ebe0` body on `#14110d` at body sizes. Verify any custom pairings against a contrast checker before shipping. - Real `