- fg
#000000- bg
#FFFFFF- APCA Lc
- +106
- Use
- foreground on background
Luma
The rare AI-media landing that resists dressing its chrome in the product's darkness — white gallery-wall canvas, Graphik + PP Editorial serif, monochrome. The editorial face of Dream Machine.

Editorial disclaimer
This entry documents observable design-language patterns for educational transfer and AI-agent briefing. Screenshots and trademarks are property of their respective owners. AI2 Design is not affiliated with or endorsed by the featured brand. Inspiration here is about language and rhythm - do not reproduce brand identity, logo, product copy, or proprietary features.
Fair Use & Gallery PolicyCopy the full design language into your agent
A typed, paste-ready design system brief - philosophy, tokens, rules, techniques, and fitness checks. Drop it into Claude, Cursor, v0 or any coding agent and it builds in Luma’s language, not just a screenshot.
Light-canvas, media-first gallery framing. The chrome is pure monochrome — #ffffff background, #000000 foreground, and a four-step neutral grey descender (#737373 / #8c8c8c / #a6a6a6 / #cccccc) for de-emphasis — so that dark, cinematic generative media reads as lit objects floated on a neutral wall. Two type voices and no more: Graphik grotesque does all functional work across a 14→52px scale with negative px tracking; a single editorial serif (PP Editorial New) is reserved for authored display moments. Spacing leaps in large architectural intervals (up to 80 / 160px). Elevation is soft and photographic — large 24px radii, diffuse low-alpha shadow. No accent color in the UI; saturation lives only inside the media.
Use this capture as a design language transfer brief for my project. Adopt the palette (light-first #ffffff canvas + #000000 foreground + a monochrome grey descender #737373/#8c8c8c/#a6a6a6, zero accent color in the chrome), the dual-voice typography (Graphik-style grotesque for all functional text + a single editorial serif used sparingly for display only), the large-interval spacing rhythm (6/8/10/12/14/16/20/24/32/40/80/160px), soft photographic elevation (24px radius cards with a diffuse low-alpha shadow, 1px solid hairlines), and a 0.15s / 0.3s motion vocabulary on cubic-bezier(0.4, 0, 0.2, 1). Treat media as the only place color and spectacle are allowed — keep the chrome neutral so content reads as lit objects on a gallery wall. Apply the language, not the source brand's specific copy or identity. When I ask you to build a page or component, enforce these rules by default and flag any deviation.
- Layout
- Grid
- Content width
- Bounded
- Framing
- Flat
- Grid strength
- Soft
Strictly monochrome chrome. #000000 foreground does the reading on a #ffffff canvas, with a four-step neutral grey descender (#737373 → #8c8c8c → #a6a6a6 → #cccccc) handling captions, metadata, and progressive de-emphasis. There is no brand accent in the UI — all color and saturation is deliberately confined to the media tiles, so the page behaves as a neutral gallery wall for dark cinematic content.
- #000000 text (Graphik 400-700) on a #ffffff canvas — the dominant high-contrast reading layer
- #737373 (~45% L) for secondary text and supporting copy — the primary de-emphasis grey
- #8c8c8c (~55% L) and #a6a6a6 (~65% L) for captions, metadata, and tertiary labels
- #cccccc (~80% L) for the faintest hairline-adjacent text and disabled states — used rarely
- Zero accent color in the chrome by design — generative media tiles are the only saturated surface
Gradients (paste-ready)
linear-gradient(to right bottom, oklab(0.999994 0.0000455678 0.0000200868 / 0.5) 0px, oklab(0 0 0 / 0.5) 100%)
- Two families only. Functional voice: Graphik (self-hosted woff2, font-display: swap) for nav, body, UI labels, and most headings. Display voice: PP Editorial New (self-hosted OTF, the `__ppEditorial` family) — an editorial serif reserved exclusively for authored display moments.
- Weight set: 400 (reading) / 500 (UI labels + medium headings) / 600 (dense emphasis) / 700 (bold headings). Graphik carries all four; the serif appears at display sizes only.
- Display tracking in px, not em — it tightens with size: -0.4px at 16px body, -0.88px at 22px, -1.28px at 32px, -1.92px at 48px, up to -2.08px on the 52px hero. Constant optical correction.
- Type scale: 14 / 16 / 18 / 22 / 32 / 48 / 52px. Body sits at 16px/24px (line-height 1.5); the 18px reading variant runs 25.2px line-height with -0.54px tracking.
- Heading line-height tightens upward: 1.2 at 48-52px display, 1.2 at 32px, ~1.3 at 22px; body and UI hold 1.5 (24px on 16px).
- Small UI labels run 14px at weight 500-600 with line-height 14px (1.0) — tight, single-line control text.
- Reserve the editorial serif for the page's one or two authored statements; never let it into nav, buttons, form fields, or repeated UI.
- Large-interval architectural rhythm. Scale: 6 / 8 / 10 / 12 / 14 / 16 / 20 / 24 / 32 / 40 / 80 / 160px — note the deliberate jumps from 40 → 80 → 160 for section-level breathing room.
- Container max-widths: 1280px (md, primary content rail) and 896px (sm, narrow reading/centered clusters). Do not exceed 1280px.
- Section vertical rhythm leans on the 80 / 160px steps on desktop — exhibits spaced like gallery rooms, not a dense feed; compress to 40 / 80px on mobile.
- Card and block padding draws from 16 / 24 / 32px; gaps from the 8 / 10 / 12 / 16 / 20 / 24 / 40px portion of the scale (observed flex/grid gutters cluster at 10, 20, 16, 12, 8px).
- No magic numbers — every margin, padding, and gap must resolve to a value on the 6→160 scale.
- Soft photographic elevation — cards float with a diffuse, low-alpha drop shadow, never a hard or colored one.
- Two captured shadow tiers: a resting `0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1)` (shadow-xs) and a lifted `0 20px 25px -5px rgba(0,0,0,0.1), 0 8px 10px -6px rgba(0,0,0,0.1)` (shadow-sm).
- Structure where shadow isn't needed comes from 1px solid hairlines in a neutral grey — never dashed.
- Shadow alpha stays at 0.1; never bloom, never tint. Depth reads as photographic lighting, not as a glow.
Techniques
Diffuse floating-card shadow
Media and content cards rest on `box-shadow: rgba(0,0,0,0.1) 0 4px 6px -1px, rgba(0,0,0,0.1) 0 2px 4px -2px` and lift on hover/scroll to the larger `rgba(0,0,0,0.1) 0 20px 25px -5px, rgba(0,0,0,0.1) 0 8px 10px -6px`. Both at 0.1 alpha, large negative spread — a soft photographic float, never a hard edge.
Image scrim overlay
Dark media tiles carrying light text receive a `linear-gradient(to right bottom, oklab(0.999994 ... / 0.5) 0px, oklab(0 0 0 / 0.5) 100%)` white→black 50%-alpha scrim to guarantee legibility without flattening the underlying clip.
- Two-step radius scale: 8px for buttons, inputs, chips, and small controls; 24px for cards, media tiles, and large surfaces (the dominant card radius, observed 14× vs 8px's 8×).
- Large 24px radii are what give media tiles their soft, photographic, gallery-frame feel — pair them with the diffuse shadow.
- Borders are 1px solid hairlines only; no dashed, no double, no thick strokes.
- Icons are stroke-based and monochrome to match the neutral chrome — no filled or duotone variants competing with the media.
button-primary- backgroundColor
- #000000
- textColor
- #ffffff
- radius
- 8px
- padding
- 10px 20px
- border
- none
- boxShadow
- none
- fontWeight
- 500
- fontSize
- 14px
- lineHeight
- 14px
- letterSpacing
- -0.42px
Tailwind
inline-flex items-center gap-2 rounded-[8px] bg-[#000000] px-5 py-2.5 text-[14px] font-medium leading-[14px] tracking-[-0.42px] text-[#ffffff] transition-colors duration-150 ease-[cubic-bezier(0.4,0,0.2,1)] hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#000000] focus-visible:ring-offset-2
button-secondary- backgroundColor
- #ffffff
- textColor
- #000000
- radius
- 8px
- padding
- 10px 20px
- border
- 1px solid #cccccc
- boxShadow
- none
- fontWeight
- 500
- fontSize
- 14px
- lineHeight
- 14px
Tailwind
inline-flex items-center gap-2 rounded-[8px] border border-[#cccccc] bg-[#ffffff] px-5 py-2.5 text-[14px] font-medium leading-[14px] text-[#000000] transition-colors duration-150 ease-[cubic-bezier(0.4,0,0.2,1)] hover:border-[#8c8c8c] hover:bg-[#ffffff] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#000000] focus-visible:ring-offset-2
media-card- backgroundColor
- #ffffff
- textColor
- #000000
- radius
- 24px
- padding
- 0px
- border
- none
- boxShadow
- rgba(0, 0, 0, 0.1) 0 4px 6px -1px, rgba(0, 0, 0, 0.1) 0 2px 4px -2px
- overflow
- hidden
Tailwind
group overflow-hidden rounded-[24px] bg-[#ffffff] shadow-[rgba(0,0,0,0.1)_0_4px_6px_-1px,rgba(0,0,0,0.1)_0_2px_4px_-2px] transition-shadow duration-300 ease-[cubic-bezier(0,0,0.2,1)] hover:shadow-[rgba(0,0,0,0.1)_0_20px_25px_-5px,rgba(0,0,0,0.1)_0_8px_10px_-6px]
input-field- backgroundColor
- #ffffff
- textColor
- #000000
- radius
- 8px
- padding
- 12px 16px
- border
- 1px solid #cccccc
- boxShadow
- none
- fontWeight
- 400
- fontSize
- 16px
- lineHeight
- 24px
- letterSpacing
- -0.4px
Tailwind
w-full rounded-[8px] border border-[#cccccc] bg-[#ffffff] px-4 py-3 text-[16px] leading-[24px] tracking-[-0.4px] text-[#000000] placeholder:text-[#a6a6a6] transition-colors duration-150 ease-[cubic-bezier(0.4,0,0.2,1)] focus-visible:border-[#000000] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#000000]/10
editorial-display- fontFamily
- 'PP Editorial New', Georgia, serif
- color
- #000000
- fontWeight
- 400
- fontSize
- 48px
- lineHeight
- 57.6px
- letterSpacing
- -1.92px
Tailwind
font-[var(--font-editorial,'PP_Editorial_New',Georgia,serif)] text-[48px] font-normal leading-[57.6px] tracking-[-1.92px] text-[#000000]
caption-label- color
- #737373
- fontWeight
- 500
- fontSize
- 14px
- lineHeight
- 14px
- letterSpacing
- normal
Tailwind
text-[14px] font-medium leading-[14px] text-[#737373]
Easings
cubic-bezier(0.4, 0, 0.2, 1)cubic-bezier(0, 0, 0.2, 1)Scroll patterns
- transform reveals — translate/scale on cubic-bezier(0, 0, 0.2, 1) at 0.3s for media entering the viewport
- opacity reveals at 0.3s on cubic-bezier(0.4, 0, 0.2, 1) for text blocks
- Stagger grouped media tiles by 40-80ms; let each clip settle before the next
- No parallax beyond a subtle translateY — media floats, it does not lurch
- Primary easing: cubic-bezier(0.4, 0, 0.2, 1) — the standard ease-in-out that anchors most state changes (observed 52× vs 13×).
- Secondary easing: cubic-bezier(0, 0, 0.2, 1) — an ease-out used for transform/scroll choreography on entering media.
- Two durations only: 0.15s for interactive state changes, 0.3s for transform and scroll reveals. Do not invent a third tier.
- opacity and transform are the first-class animated properties — keep media transitions GPU-friendly.
- useReducedMotion mandatory: all reveals collapse to opacity-only or static render.
- No spring animations and no loops except explicit media playback — deterministic cubic-bezier only.
- Media tiles are the primary interactive surface — hover lifts the card shadow and may auto-play a preview clip; the whole tile is the click target.
- Tabs / segmented controls for switching between product modes (video / 3D / image) rather than separate pages.
- Tooltips reveal on hover + focus; dismiss instantly on blur. No persistent helper chrome.
- Modals reserved for sign-in and destructive confirmations; media expands inline or to a lightbox, never a nested modal.
- Form validation inline below the field on blur; submit stays disabled until valid.
- Empty states: one-line 16px copy in #737373 plus a primary #000000 action button — no decorative illustration competing with real media.
- Loading states: skeleton shimmer sized to the eventual media tile; inline spinner inside buttons. No full-page overlay.
Desktop-first because the product is large, cinematic media that wants width — the primary container runs to 1280px with a 896px narrow rail for centered reading. Mobile reflows the same gallery language into a single column without inventing an alternate architecture; the large 80/160px spacing intervals compress but the rhythm survives. The media tile is the unit at every size.
- Breakpoints: sm 640 / md 768 / lg 1024 / xl 1280 / 2xl 1536 — standard Tailwind ladder.
- Container max-width 1280px (primary) and 896px (narrow); never exceed 1280.
- Media grids: multi-column at lg+, two-up at md, single column on mobile — tiles keep their 24px radius at every tier.
- Section spacing compresses 160 → 80 → 40px as the viewport narrows; never collapse below the 40px floor between sections.
- Type scales down proportionally: hero 52 → 32, headings drop ~25% per tier while px tracking eases toward 0.
- Tap targets minimum 44×44 on touch; never hide a desktop control on mobile — reflow it.
- Contrast: #000000 on #ffffff = 21:1 (AAA). Secondary #737373 on #ffffff ≈ 4.7:1 (AA body); #8c8c8c ≈ 3.5:1 and #a6a6a6 ≈ 2.5:1 are large-text / decorative only — never body copy.
- focus-visible: 2px ring at #000000 with a 2px offset on every interactive element — replaces the default outline.
- Dark media carrying text must use the 50%-alpha scrim (or an equivalent) to maintain ≥ 4.5:1 against the underlying clip.
- All interactive elements reachable via Tab in logical order; never rely on hover to expose actions on media tiles.
- Auto-playing preview clips respect prefers-reduced-motion — pause and show a static poster frame instead.
- ARIA labels on icon-only controls; aria-expanded on collapsible regions; aria-live='polite' on status and toast updates.
- Provide captions/poster frames for video media; never rely on color alone to signal state in the monochrome chrome.
- Tap targets minimum 44×44 on touch, 40×40 on pointer.
Built on Next.js (observed /_next/image pipeline and __next-hashed self-hosted fonts). No animation library was detected in the extract (libraries: []), but the motion profile (opacity/transform transitions at 0.15s/0.3s on cubic-bezier(0.4,0,0.2,1) and cubic-bezier(0,0,0.2,1)) matches Framer Motion or plain CSS transitions. Media is the core asset class — images run through Next/Image with responsive srcset, and video tiles carry the product's generative output.
- Next/Image with full `srcset` + `sizes` for every media still; `priority` only on the LCP hero tile, the rest lazy.
- Framer Motion `motion.div` with `whileInView` + `viewport={{ once: true }}` for scroll reveals; `transition={{ duration: 0.3, ease: [0, 0, 0.2, 1] }}` for transforms, `0.15` for opacity.
- useReducedMotion guard around every reveal and around auto-playing media previews.
- Self-host both font families (Graphik woff2, PP Editorial New OTF) with font-display: swap; preload only the above-the-fold weights.
- Apply the 50%-alpha image scrim as a CSS overlay layer, not baked into the asset, so the same clip can sit on light or dark sections.
- Keep the chrome strictly monochrome (#000000 / #ffffff + #737373/#8c8c8c/#a6a6a6/#cccccc greys) — let all color live inside the media.
- Reserve the editorial serif for one or two authored display moments; everything functional is the grotesque.
- Use the large 24px radius + diffuse 0.1-alpha shadow on media cards to make them float like lit objects.
- Lean on the 80 / 160px spacing steps for section rhythm — give media room to breathe.
- Scrim dark media before overlaying text; verify ≥ 4.5:1 against the clip.
- Default interactive transitions to 0.15s on cubic-bezier(0.4, 0, 0.2, 1); reserve 0.3s + cubic-bezier(0, 0, 0.2, 1) for transform/scroll reveals.
- Pass every page through useReducedMotion — including auto-playing previews — before shipping.
- Never introduce a brand accent color into the chrome — the monochrome neutrality is what makes the media pop.
- Never let the editorial serif into nav, buttons, inputs, or repeated UI — scarcity is its whole power.
- Never add a third type family beyond the grotesque + the editorial serif.
- Never use #8c8c8c, #a6a6a6, or #cccccc for body copy on white — they fail AA at body sizes; they are large-text/decorative only.
- Never deepen the card shadow past 0.1 alpha or tint it — depth is photographic, not glowing.
- Never invent durations or easings outside the captured set {0.15s, 0.3s} × {cubic-bezier(0.4, 0, 0.2, 1), cubic-bezier(0, 0, 0.2, 1)}.
- Never use em for display tracking — the px-based scale (-0.4 → -2.08px) is an optical constant.
- Never default the page to dark mode 'because it's an AI tool' — the light canvas is the deliberate, load-bearing inversion.
- Tailwind v4 @theme inline only — no runtime style concatenation, no CSS-in-JS.
- Spacing scale: 6 / 8 / 10 / 12 / 14 / 16 / 20 / 24 / 32 / 40 / 80 / 160px.
- Container max 1280px (primary) / 896px (narrow) — do not exceed.
- Two font families: Graphik-style grotesque (functional) + PP Editorial New serif (display only).
- Weight set: 400 / 500 / 600 / 700.
- Radius scale: 8 / 24px.
- Monochrome chrome: #000000 / #ffffff + greys #737373 / #8c8c8c / #a6a6a6 / #cccccc. No accent.
- Motion: durations {0.15s, 0.3s}, easings {cubic-bezier(0.4, 0, 0.2, 1), cubic-bezier(0, 0, 0.2, 1)}. No springs, no loops except media.
- Shadow: 0.1-alpha diffuse only (shadow-xs resting, shadow-sm lifted). 1px solid hairlines.
- Color grep: only #000000, #ffffff, #737373, #8c8c8c, #a6a6a6, #cccccc (and the scrim oklab values) appear in the chrome — no accent hue.
- Container width: no content rail exceeds 1280px; narrow clusters cap at 896px.
- Spacing grep: no values outside the 6/8/10/12/14/16/20/24/32/40/80/160 ladder.
- Font audit: exactly two families — a grotesque for all functional text, the editorial serif only at display sizes; no third family.
- Weight grep: only 400, 500, 600, 700 appear.
- Radius grep: only 8px and 24px corner radii.
- Transition grep: durations draw from {0.15s, 0.3s}; timing-functions draw from {cubic-bezier(0.4, 0, 0.2, 1), cubic-bezier(0, 0, 0.2, 1)}.
- Shadow audit: every elevation uses a 0.1-alpha diffuse shadow (xs resting / sm lifted); no tinted or >0.1 shadows.
- Tracking audit: display text uses px-based negative tracking (-0.4 → -2.08px), not em.
- Contrast audit: body copy is #000000 (or #737373 for secondary) on #ffffff — never the lighter greys; dark media text is scrimmed to ≥ 4.5:1.
- Image audit: loading='lazy' on every non-LCP media tile; priority only on the hero.
Design tokens
Observed token system
Color, type, spacing, gradients, and stacking order captured from the live page and rendered here as living, paste-ready previews.
Inspector
Observable layers
Structure, breakpoints, motion, fonts, and images captured from the live page and kept paste-ready alongside the tokens.
Depth-first walk of the meaningful sections. 10 nodes across 7 levels, shallow to deep by color.
- body2
- Main2
- Nav
- div (×4)2
- Nav
- div1
- div1
- div1
- Form
- div
Accessibility
Contrast matrix
26 combinations - 10 pass AA - 6 pass AAA. Each pair is previewed with its real foreground on background; APCA Lc sits alongside the WCAG 2.1 ratio for draft WCAG 3 awareness.
- fg
#FFFFFF- bg
#000000- APCA Lc
- -108
- Use
- background on foreground
- fg
#000000- bg
#CCCCCC- APCA Lc
- +77
- Use
- foreground on foreground
- fg
#CCCCCC- bg
#000000- APCA Lc
- -76
- Use
- foreground on foreground
- fg
#000000- bg
#A6A6A6- APCA Lc
- +56
- Use
- foreground on foreground
- fg
#A6A6A6- bg
#000000- APCA Lc
- -54
- Use
- foreground on foreground
- fg
#000000- bg
#8C8C8C- APCA Lc
- +43
- Use
- foreground on foreground
- fg
#8C8C8C- bg
#000000- APCA Lc
- -41
- Use
- foreground on foreground
- fg
#FFFFFF- bg
#737373- APCA Lc
- -78
- Use
- background on foreground
Images
Image strategy
Observable image posture - total count, lazy-loading ratio, and format mix. The hero image is measured above the fold.
- unknown27 · 100%
- Industry
- ai
- Industry
- content
- Theme
- Light
- Added
- 2026-06-24
FAQ
Questions people ask about Luma
3questionsAnswers are pulled from the curator verdict and design brief - the same text your AI agent sees when it paste-reads this page.
Compare this with



