---
title: "Extraction guide (inspire)"
description: "Headless Chromium (SwiftShader on, so WebGL/video pages don't screenshot black) at 1440×900 and 390×844."
canonical: https://void-design.vercel.app/docs/inspire/extraction-guide
lastModified: 2026-09-16
---

# Extraction guide

## 1. What `void extract` measures

Headless Chromium (SwiftShader on, so WebGL/video pages don't screenshot black) at 1440×900 and 390×844. Load + wait, wheel-scroll in steps (so Lenis/ScrollTrigger fire), capture computed styles, CSS, animations, inline-style diffs, network. Output schema: `packages/cli/src/extract/types.ts` (`DesignDNA`, schema version 1). Every inferred field is `{ value, confidence 0–1, evidence?[] }`.

## 2. Fields and how to use them

| `dna.json` path | Meaning | Use it for |
|---|---|---|
| `typography.display` | H1 px (+ mobile px, px/viewport ratio), weight, line-height ratio, tracking in em, transform | **the single best fingerprint**; map to `text-display*` + `--weight-display` + `--tracking-display` |
| `typography.roles[]` | display/heading/body/ui/mono/label → real family name (hash-cleaned), weights, classification, `free`, licence, `alternatives[]` | font choice; never self-host non-free families |
| `typography.styles[]`, `sizes[]` | text-style histogram (size, weight, lh, tracking, family, character count) | workhorse size (usually 13–14px), mono texture, positive small-size tracking |
| `typography.scale` | fitted base + ratio, clamp() steps | only if confidence ≥ 0.6; otherwise keep void's scale |
| `typography.labels` | uppercase share, label tracking, px | `--label-tracking`, whether mono labels are the voice |
| `typography.features`, `textWrap` | OpenType features (`cv01`, `ss03`…), balance/pretty usage | `font-feature-settings` override (only if the free alternative has them) |
| `color.scheme`, `respondsToColorScheme`, `alternate` | dark/light default and whether a second scheme exists | `theme.default` in site.config |
| `color.roles.*` | measured bg, bgSubtle, surface, fg, fgMuted, fgSubtle, line, brand (null = monochrome), selection | ramp relationships: L steps between tiers, hairline alpha |
| `color.neutral` | hue, chroma, temperature (cool/warm/neutral/green) | neutral hue/chroma for the generator |
| `color.accent` | hue, chroma, step-9 L, text on solid | accent L and chroma (change the hue: departure) |
| `color.palette[]` (coverage, channels, roles) | weighted colors per channel | accent **share**: restrained (1 hue, few elements) vs playful |
| `color.bands[]` | alternating dark/light section bands | whether to use `bg-bg-subtle`/inverted bands |
| `color.pixels` | dominant colors of the full screenshot, colorfulness, imagery share | how much of the feel comes from imagery (can't copy that) |
| `color.tokens` | void semantic tokens generated with the source's lightness feel | already baked into `direction.css` |
| `layout.contentWidth`, `containers`, `gutter` | content width at 1440, gutter desktop/mobile | `--container-page`, `--gutter` |
| `layout.sectionPadding` | desktop/mobile padding values | `--section-y` and rhythm variation (low confidence when spacing lives on children) |
| `layout.nav` | height, position, blur, translucent, floating, item count | header variant |
| `layout.hero` | align (left/center/split), h1 px, media side, height in vh, CTA count | hero archetype |
| `layout.density` | text blocks per viewport → airy/balanced/dense | spacing scale feel |
| `layout.radius` | knob px, value histogram, pill share | `--radius`, pill vs rounded buttons |
| `layout.shadows[]` (kind ring/soft/hard/inset/layered) | shadow grammar | elevation style (draft `direction.css` picks one) |
| `layout.texture` | grain, SVG filters, blend modes, backdrop blur | `--grain-opacity`, header blur |
| `components` (in brief) | button spec: height, padding, radius, font, bg/fg, shadow, transition | `Button` size/variant tuning |
| `motion.durations`, `easings`, `properties` | CSS transition/animation inventory | personality → duration tokens |
| `motion.animationsOnLoad/OnScroll`, `scrollDriven`, `viewTransitions`, `reducedMotionQueries` | what moves and how | what to rebuild; reduced-motion coverage (0 = don't copy the behaviour) |
| `motion.libraries` | GSAP, ScrollTrigger, Lenis, OGL/three, Lottie, motion… | effect-downgrades table |
| `motion.smoothScroll` | hijacked + library | never reproduce |
| `motion.cursor` | custom/hidden cursor | never hide the real cursor |
| `motion.effects[]` | named effects with evidence and a suggested rebuild | Step 4 |
| `motion.personality` | label + suggested tokens + summary | design statement line 5 |
| `tech.transfer` | total/JS/CSS/font/image/media KB, requests; third-party KB; HTML KB; webgl | the weight comparison |
| `structure.sections[]` | per-section composition, counts (images, cards, logos, columns), bg, padding, crop screenshot | section plan (adapt order; our content) |
| `structure.headings`, `ctaLabels` | outline and CTA wording | **structure only; never reuse the words** |
| `direction` | recommended void direction, confidence, per-direction scores with reasons, token overrides with why | Step 3 |
| `warnings[]` | capture problems (timeouts, consent walls, black WebGL) | what to verify manually |

## 3. Reliability

| Aspect | Reliable automatically | Sanity-check | Needs your judgement |
|---|---|---|---|
| Type | families in use, sizes, weights, lh, tracking, features, font files | alias → real typeface; display style when the H1 is hidden or split into spans | which free face matches; whether a serif accent is the voice or a one-off |
| Color | frequency-ranked bg/text/border, alpha, selection, theme-color | brand accent vs product-screenshot or syntax colors; dark bands inside light pages | temperature intent; photographic color |
| Layout | container, gutter, header, section padding on `<section>`, centered ratio | rhythm when spacing lives on children/margins; grid columns | section archetypes, narrative, what the hero shows |
| Components | radius, padding, heights, shadow strings, focus ring, `:active` | which button is primary; hover states | whether a recipe works out of context |
| Motion | CSS transitions/keyframes, easings, scroll timelines, WAAPI, reduced-motion count, library presence | which elements animate (inline diffs show transforms, not intent); GSAP params as sets | choreography quality; essential vs decorative |
| Imagery | formats, sizes, counts, lazy/priority, video attributes | product UI vs illustration vs photo | art direction (never replicable) |
| Performance | transfer by type, requests, third parties | full-scroll totals include lazy + tracking pixels | trade-offs (a 2 MB video may be the brand) |

## 4. Manual fallback (no CLI, ~15 minutes in DevTools)

Open the site at 1440×900, disable cache, scroll the whole page once, then record:

1. **Display tuple.** Inspect the largest heading in the fold (not just `h1`; it may be hidden or split): Computed → `font-family`, `font-size`, `font-weight`, `line-height` (÷ size), `letter-spacing` (÷ size = em).
2. **Workhorse text.** Inspect nav links, buttons, card text: size/weight/tracking; is there mono? uppercase labels + tracking?
3. **Fonts.** Network → Font: file names reveal real faces (`HaasGrotDisp-75Bold.otf`, `SuisseIntl_Book`); count and KB. Check the licence before mapping.
4. **Neutral ramp.** `html`/`body` background; color of H1, body paragraph, muted meta text; the most common border color (Elements → Computed → filter `border`).
5. **Accent.** Primary CTA background; link color; count roughly how many elements in the fold use it; `::selection` (select text).
6. **Radius mode.** Primary button, cards, inputs, images. Pill ratio.
7. **Shadows.** Copy `box-shadow` from button, card, menu. Note ring layers, inset highlights, negative spread, tint.
8. **Layout skeleton.** Main container max-width and padding; section padding (several sections); header height/position/blur; how many headings are centered.
9. **Button spec.** Height, padding, radius, font size/weight, transition string, `:active` transform (Styles pane → `:active` toggle).
10. **Motion inventory.** Styles: `transition` values and `cubic-bezier`s; Animations panel while loading and scrolling; Sources search for `gsap`, `ScrollTrigger`, `lenis`, `three`, `ogl`, `lottie`, `animation-timeline`.
11. **Reduced motion.** Rendering panel → emulate `prefers-reduced-motion: reduce`, reload, scroll. Does content still appear?
12. **Weight.** Network summary after full scroll: transferred KB total; filter JS, Font, Img, Media.
13. **Screenshots.** Full-size screenshot of fold and full page (Command menu → "Capture full size screenshot") at 1440 and 390 (device toolbar).

Write the numbers into the Step 2 table in `inspire` and continue.

## 5. Pitfalls

- **Preloaders** hide the real fold (hellohello ~8s). Measure after content appears; never reproduce a preloader.
- **Consent banners and geo redirects** (Stripe served `/in`) change layout and colors; dismiss first; note the region.
- **`getAnimations()` misses JS motion.** GSAP/Framer/Lenis/canvas are invisible to it; rely on library detection and inline-style diffs.
- **`framer-motion` / `startViewTransition` strings** appear inside frameworks: weak evidence of use.
- **Product screenshots inflate the palette.** Exclude colors inside images, canvases and app mocks before choosing an accent.
- **CSS-in-JS** (styled-components, Framer, StyleX) isn't in fetched CSS files; counts under-report.
- **Hidden or split headings:** hellohello's `h1` is 1×1px; Stripe's H1 contains the subhead; use the largest visible text.
- **Units:** tracking in em, line-height as a ratio, colors in OKLCH, fluid sizes as "vw at 1440 + floor", or values won't transfer across viewports.
- **Mobile timeouts** on media-heavy pages: mobile values may be missing (check `warnings`).
- **Heavy isn't premium.** The best-feeling sites in the teardown were not the heaviest (Paco 367 KB, Rauno 640 KB vs Family 15.3 MB); don't import weight to import feel.
