duply
Preview of Dagster

Dagster

A clean, developer-tooling marketing surface built on white canvas with near-black ink and a single indigo brand accent. The system reads as precise, technical, and modern — Geist typeface throughout, soft 12px cards with no shadow, pill-shaped CTAs, purple-tinted micro-shadows, and dark indigo product bands that anchor long-scroll pages. Brand voltage comes from the indigo accent (#4f43dd) used on the hero's second headline line and from real product-UI dashboards shown directly inside the page.

---
version: alpha
name: Dagster-design-analysis
description: A clean, developer-tooling marketing surface built on white canvas with near-black ink and a single indigo brand accent. The system reads as precise, technical, and modern — Geist typeface throughout, soft 12px cards with no shadow, pill-shaped CTAs, purple-tinted micro-shadows, and dark indigo product bands that anchor long-scroll pages. Brand voltage comes from the indigo accent (#4f43dd) used on the hero's second headline line and from real product-UI dashboards shown directly inside the page.

colors:
  primary: "#4f43dd"
  primary-active: "#332aa6"
  ink: "#030615"
  ink-dark: "#111927"
  ink-deep-purple: "#1b0130"
  neutral-black: "#000000"
  body: "#1f2a37"
  muted: "#384250"
  muted-soft: "#a4a7ae"
  canvas: "#ffffff"
  surface-soft: "#fbfaff"
  surface-lilac: "#f7f7ff"
  surface-gray: "#f7f8f9"
  surface-faint: "#fafafa"
  hairline: "#e3e8ef"
  neutral-cc: "#cccccc"
  neutral-dd: "#dddddd"
  accent-blue: "#3898ec"
  on-primary: "#ffffff"
  on-dark: "#ffffff"

typography:
  h1:
    fontFamily: "Geist, sans-serif"
    fontSize: 64px
    fontWeight: 600
    lineHeight: 1.12
    letterSpacing: normal
  h2:
    fontFamily: "Geist, sans-serif"
    fontSize: 48px
    fontWeight: 600
    lineHeight: 1.2
    letterSpacing: -0.16px
  h3:
    fontFamily: "Geist, sans-serif"
    fontSize: 18px
    fontWeight: 500
    lineHeight: 1.55
    letterSpacing: 0.18px
  body:
    fontFamily: "Geist, sans-serif"
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.25
    letterSpacing: 0.32px

rounded:
  sm: 8px
  md: 12px
  lg: 16px
  xl: 24px
  xxl: 48px
  pill: 100px

spacing:
  xxs: 4px
  xtiny: 6px
  xs: 8px
  sm: 12px
  md: 16px
  lg: 20px
  xl: 24px
  xxl: 32px

components:
  top-nav:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.ink}"
    typography: "{typography.body}"
    padding: 12px 24px
  button-primary:
    backgroundColor: "{colors.ink-deep-purple}"
    textColor: "{colors.on-dark}"
    typography: "{typography.body}"
    rounded: "{rounded.pill}"
    padding: 12px 24px
  button-primary-active:
    backgroundColor: "{colors.primary-active}"
    textColor: "{colors.on-dark}"
    rounded: "{rounded.pill}"
  button-secondary:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.primary}"
    typography: "{typography.body}"
    rounded: "{rounded.pill}"
    padding: 12px 24px
  button-icon-circular:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.ink}"
    rounded: "{rounded.pill}"
    size: 40px
  card:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.ink}"
    typography: "{typography.body}"
    rounded: "{rounded.md}"
    padding: 24px
  product-mockup-card:
    backgroundColor: "{colors.ink-dark}"
    textColor: "{colors.on-dark}"
    rounded: "{rounded.md}"
    padding: 20px
  feature-callout-card:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.ink}"
    typography: "{typography.h3}"
    rounded: "{rounded.md}"
    padding: 20px
  customer-story-card:
    backgroundColor: "{colors.surface-gray}"
    textColor: "{colors.ink}"
    typography: "{typography.body}"
    rounded: "{rounded.lg}"
    padding: 20px
  logo-cloud:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.muted}"
    typography: "{typography.body}"
    padding: 24px
  cta-band-dark:
    backgroundColor: "{colors.ink-dark}"
    textColor: "{colors.on-dark}"
    typography: "{typography.h2}"
    rounded: "{rounded.xl}"
    padding: 32px
  input:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.ink}"
    typography: "{typography.body}"
    rounded: "{rounded.sm}"
    padding: 12px 16px
  pricing-card:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.ink}"
    typography: "{typography.body}"
    rounded: "{rounded.md}"
    padding: 24px
---

## Overview

Dagster's marketing surface is a clean, developer-tooling interface — white canvas (`{colors.canvas}`#ffffff) with near-black ink (`{colors.ink}`#030615), the **Geist** typeface throughout, and a single indigo brand accent (`{colors.primary}`#4f43dd). The system reads as precise and technical without being cold: generous vertical whitespace, soft-cornered cards (`{rounded.md}` — 12px), pill-shaped CTAs, and real product-UI dashboards shown directly inside the page rather than illustrated.

Type voice is unusually unified: every role — h1, h2, h3, body — runs **Geist**, the open-source geometric sans. Hierarchy is carried by size and weight (600 for display, 500 for h3, 400 for body) rather than by switching families. The hero pairs a black first line ("Data your team trusts.") with an indigo second line ("AI that runs on it.") — the accent appears as a typographic highlight, not a button fill.

Brand voltage comes from two places: the **indigo accent** used sparingly on headline highlights and inline links, and **real product chrome** — dark dashboard mockups (`{colors.ink-dark}`#111927) showing the actual Dagster catalog, run timelines, and Dagster+ AI panels embedded directly into the marketing flow. Dagster shows the product; it doesn't paint marketing illustrations of it.

The system also has a signature detail: **purple-tinted micro-shadows**. Cards and elevated surfaces carry `rgba(79, 67, 221, 0.05)` 1–2px shadows — the brand indigo bled into the shadow color rather than a neutral gray.

**Key Characteristics:**
- White canvas with near-black ink (`{colors.ink}`#030615), single indigo accent (`{colors.primary}`#4f43dd).
- **Geist** typeface across every role — hierarchy by size/weight, not by family switching.
- Pill-shaped CTAs (`{rounded.pill}` — 100px): a dark deep-indigo primary ("Sign In", "Talk to sales") and a white-outline secondary ("Get started for free", "Try Dagster+").
- Soft 12px cards (`{rounded.md}`) that mostly run shadowless — flat surfaces on white canvas.
- Real dark product-UI dashboards (`{colors.ink-dark}`#111927) embedded as content, not illustration.
- Purple-tinted shadow signature: `rgba(79, 67, 221, 0.05)` micro-shadows on elevated elements.
- Indigo as a typographic highlight (hero second line) and inline-link color rather than a CTA fill.

## Colors

### Brand & Accent
- **Primary** (`{colors.primary}`#4f43dd): The indigo brand accent. Used on the hero's second headline line, inline links, and the purple-tinted shadow color. Press/deepened state shifts to `{colors.primary-active}` (#332aa6 — derived as the active/darker pairing observed in the palette).
- **Accent Blue** (`{colors.accent-blue}`#3898ec): A secondary blue appearing rarely on small UI accents inside product chrome. Not used on marketing CTAs.

### Surface
- **Canvas** (`{colors.canvas}`#ffffff): The default page floor.
- **Surface Soft** (`{colors.surface-soft}`#fbfaff): Barely-tinted off-white band background.
- **Surface Lilac** (`{colors.surface-lilac}`#f7f7ff): A faint lilac wash used on alternating sections.
- **Surface Gray** (`{colors.surface-gray}`#f7f8f9): Neutral light-gray card / panel fill (customer-story cards).
- **Surface Faint** (`{colors.surface-faint}`#fafafa): The lightest neutral divider tone.
- **Ink Dark** (`{colors.ink-dark}`#111927): The dark dashboard / product-mockup surface and the dark CTA band background.
- **Ink Deep Purple** (`{colors.ink-deep-purple}`#1b0130): The deepest near-black indigo — used as the primary button fill.
- **Hairline** (`{colors.hairline}`#e3e8ef): 1px border tone on light surfaces — inputs, dividers, card outlines.
- **Neutral CC / DD** (`{colors.neutral-cc}`#cccccc, `{colors.neutral-dd}`#dddddd): Faint neutral borders and disabled tones.

### Text
- **Ink** (`{colors.ink}`#030615): All headlines and primary text.
- **Body** (`{colors.body}`#1f2a37): Default running-text color.
- **Muted** (`{colors.muted}`#384250): Secondary text and labels.
- **Muted Soft** (`{colors.muted-soft}`#a4a7ae): Tertiary text, logo-cloud captions, fine print.
- **Neutral Black** (`{colors.neutral-black}`#000000): Pure black used in icons/logos.
- **On Primary / On Dark** (`{colors.on-primary}` / `{colors.on-dark}`#ffffff): Text on dark buttons, dark CTA bands, and product mockups.

### Semantic
No dedicated success/warning/error tokens were measured on the marketing surface — status colors appear only inside embedded product chrome (red/yellow run-failure dots) and are not extractable as system tokens. See Known Gaps.

## Typography

### Font Family
The entire system runs **Geist** — Vercel's open-source geometric sans — across display and body. There is no secondary family. Geist is an open-source typeface (`fonts_licensed` is empty), so it can ship directly with the recommended fallback stack `Geist, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`.

The notable detail is positive letter-spacing on the smaller roles: h3 carries +0.18px and body carries +0.32px tracking — a slightly loosened, technical-feeling rhythm. Only h2 uses negative tracking (-0.16px); h1 sits at `normal`.

### Hierarchy

| Token | Size | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
| `{typography.h1}` | 64px | 600 | 1.12 | normal | Hero headline ("Data your team trusts. / AI that runs on it.") |
| `{typography.h2}` | 48px | 600 | 1.2 | -0.16px | Section heads ("Bad data breaks decisions, not just pipelines.") |
| `{typography.h3}` | 18px | 500 | 1.55 | 0.18px | Sub-heads, card titles, eyebrow lines |
| `{typography.body}` | 14px | 400 | 1.25 | 0.32px | Running text, button labels, nav links, captions |

### Principles
Hierarchy is driven by size and weight inside one family. Display sizes (h1/h2) sit at weight 600; the h3 sub-head role drops to 500; body runs 400. The accent (`{colors.primary}`) appears in headlines as a colored span — the hero's second line is the canonical example — rather than as decoration.

Button labels and nav links are not separately measured; they reuse `{typography.body}` (Geist 14px). The slightly loosened tracking is part of the technical voice — don't tighten body copy to 0.

### Note on Font Substitutes
Geist is open-source and ships directly — no substitution required. If unavailable in a given context, **Inter** is the closest fallback (both are humanist-leaning geometric sans), though Inter's letterforms are slightly wider; preserve the +0.32px body tracking signature either way.

## Layout

### Spacing System
- **Base unit:** 4px.
- **Tokens:** `{spacing.xxs}` 4px · `{spacing.xtiny}` 6px · `{spacing.xs}` 8px · `{spacing.sm}` 12px · `{spacing.md}` 16px · `{spacing.lg}` 20px · `{spacing.xl}` 24px · `{spacing.xxl}` 32px.
- **Dominant rhythm:** 12px (`{spacing.sm}`) is by far the most frequent gap/padding value, followed by 20px and 24px — the system favors tight 12px internal spacing with 20–24px between grouped elements.
- **Card internal padding:** `{spacing.xl}` (24px) for content cards; `{spacing.lg}` (20px) for product mockups and callout cards.
- **Section-level vertical rhythm** between major bands is large but was not captured as a discrete token — see Known Gaps.

### Grid & Container
- **Editorial body:** Centered single-column hero with the headline + sub-head + CTA row stacked and centered, then a full-width product dashboard below.
- **Logo cloud:** Multi-column grid of grayscale customer logos (≈6-up at desktop, wrapping on smaller widths).
- **Customer-story cards:** 2–3-up card row with prev/next carousel controls.
- **Pricing:** Multi-column tier cards (`{component.pricing-card}`).

### Whitespace Philosophy
Dagster uses generous vertical whitespace around a centered hero and lets large dark product mockups carry the visual weight. Internal element spacing is tight (12px dominant), but band-to-band spacing is open — the contrast between dense product chrome and airy marketing copy is the core layout tension.

## Elevation & Depth

| Level | Treatment | Use |
|---|---|---|
| Flat | No shadow, no border | Body sections, top nav, most cards (`{component.card}` ships `shadow: none`) |
| Hairline | 1px `{colors.hairline}` border | Inputs, dividers, occasional card outlines |
| Purple micro-shadow | `rgba(79, 67, 221, 0.05) 0px 1px 2px 0px` (and 1px 1px variant) | The signature elevated-element shadow — brand indigo bled into the shadow color |
| Neutral micro-shadow | `rgba(10, 13, 18, 0.05) 0px 1px 2px 0px` / `rgba(0,0,0,0.06) 0px 1px 8px 0px` | Small neutral elevation on a handful of UI chips |
| Floating panel | `rgba(0,0,0,0.05) 0px 12px 33px 3px` and `rgba(16,24,40,0.08) 0px 12px 16px -4px, rgba(16,24,40,0.03) 0px 4px 6px -2px` | Floating notification toasts and elevated product panels |

The elevation philosophy is **soft and mostly flat** — the dominant shadow is a barely-there 1–2px purple-tinted micro-shadow at 0.05 alpha. Larger drop shadows appear only on floating product notifications (the "Freshness failure" / "Run failure" toasts in the hero). No heavy shadows, no neumorphism.

### Decorative Depth
- Embedded product dashboards carry their own internal chrome shadows from the product UI — these are content, not system tokens.
- A faint white-glow shadow `rgba(255,255,255,0.1) 0px 2px 15px 0px` appears once on dark surfaces to lift content off the dark band.

## Shapes

### Border Radius Scale

| Token | Value | Use |
|---|---|---|
| `{rounded.sm}` | 8px | The most frequent radius — inputs, small chips, inner panels |
| `{rounded.md}` | 12px | Standard content cards and product-mockup containers |
| `{rounded.lg}` | 16px | Larger customer-story cards |
| `{rounded.xl}` | 24px | Large feature/CTA band containers |
| `{rounded.xxl}` | 48px | Oversized rounded feature panels / decorative blocks |
| `{rounded.pill}` | 100px | Pill CTAs and circular icon buttons |

Two minor radii (10px, 14px) were measured at low frequency and are treated as incidental rounding rather than system tokens — see Known Gaps.

### Photography & Geometry
Customer-story cards crop imagery to `{rounded.lg}` (16px) corners. Product dashboard mockups use `{rounded.md}` (12px). Logos in the logo cloud are rendered as flat grayscale marks with no container radius. The note worth flagging: the `input` component was measured at **0px radius** in one form context, contradicting the otherwise rounded system — see Components and Known Gaps.

## Components

### Top Navigation

**`top-nav`** — White nav bar pinned to the top of every page. `{colors.canvas}` background, `{colors.ink}` text in `{typography.body}` (Geist 14px). Carries the Dagster wordmark + spiral logo at left, a center menu (Product, Solutions, Pricing, Company, Resources with dropdown carets), and a right-side cluster: a circular GitHub icon button, a white-outline "Try Dagster+" pill, and a dark "Sign In" pill.

### Buttons

**`button-primary`** — The dark pill CTA ("Sign In", "Talk to sales"). Background `{colors.ink-deep-purple}` (#1b0130), text `{colors.on-dark}`, type `{typography.body}`, rounded `{rounded.pill}` (100px), padding ~12px × 24px (derived from the dominant spacing tokens). Active/deepened state `button-primary-active` shifts toward `{colors.primary-active}` (#332aa6).

**`button-secondary`** — White-outline pill ("Get started for free", "Try Dagster+"). Background `{colors.canvas}`, text `{colors.primary}` (indigo), 1px `{colors.hairline}` border, same pill radius and padding as primary.

**`button-icon-circular`** — The GitHub icon button in the nav. Background `{colors.canvas}`, ink-color icon, rounded `{rounded.pill}` for a full circle (the analyzer measured `radius: 50%`, mapped here to the pill token), ~40px diameter. The measured `button` props (`color: #ffffff, radius: 50%, padding: 0px`) correspond to this circular icon button.

### Cards & Containers

**`card`** — Standard content card. Background `{colors.canvas}`, rounded `{rounded.md}` (12px), and explicitly **shadow: none** (measured). The flat-on-white card is the system default.

**`product-mockup-card`** — Dark dashboard surface showing real Dagster product UI (catalog, run timeline, Dagster+ AI panel). Background `{colors.ink-dark}` (#111927), text `{colors.on-dark}`, rounded `{rounded.md}` (12px), padding `{spacing.lg}` (20px). These display the actual product chrome at scale — they're content, not decoration.

**`feature-callout-card`** — Small card with a heading + "Learn More" link used in the floating "The trust layer for your entire stack" sequence (Orchestrate / Observe / Activate). Background `{colors.canvas}`, type `{typography.h3}`, rounded `{rounded.md}`, padding `{spacing.lg}` (20px), with the signature purple micro-shadow.

**`customer-story-card`** — Image-topped story card ("14x fresher data", "90x faster onboarding"). Background `{colors.surface-gray}`, rounded `{rounded.lg}` (16px), padding `{spacing.lg}` (20px). Carries a cropped image with overlaid stat label.

**`logo-cloud`** — Grayscale customer-logo grid ("Adopted worldwide"). Background `{colors.canvas}`, logo marks in `{colors.muted}`/grayscale, caption in `{typography.body}`, padding `{spacing.xl}` (24px).

**`cta-band-dark`** — The dark mid-page band ("From operational context to confident action"). Background `{colors.ink-dark}` (#111927), text `{colors.on-dark}`, heading in `{typography.h2}`, rounded `{rounded.xl}` (24px), padding `{spacing.xxl}` (32px). Contains an embedded Dagster+ AI conversation panel and a "Meet Dagster+ AI" button.

**`pricing-card`** — Tier card on the pricing page. Background `{colors.canvas}`, rounded `{rounded.md}` (12px), padding `{spacing.xl}` (24px). Carries plan name, feature list in `{typography.body}`, and a CTA button.

### Inputs & Forms

**`input`** — Text input. Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.body}`, 1px `{colors.hairline}` border. **Note:** the measured input radius was **0px** (square corners) in the captured form context — this conflicts with the system's otherwise-rounded surfaces. The frontmatter applies `{rounded.sm}` (8px) as the recommended system-consistent value; treat the 0px measurement as a documented gap rather than canon.

## Do's and Don'ts

### Do
- Use **Geist** for every text role. Hierarchy comes from size and weight (600 / 500 / 400), not from family switching.
- Reserve the indigo accent (`{colors.primary}`#4f43dd) for headline highlights and inline links — apply it as a colored span, like the hero's second line.
- Keep cards flat on white — `{component.card}` ships shadow-none by default.
- When you do elevate, use the purple-tinted micro-shadow (`rgba(79, 67, 221, 0.05)`) — the brand-bled shadow is signature.
- Embed real product dashboards (`{component.product-mockup-card}`) on `{colors.ink-dark}` rather than illustrating the product.
- Use pill CTAs (`{rounded.pill}`): dark deep-indigo for primary, white-outline for secondary.
- Preserve the loosened body tracking (+0.32px) — it's part of the technical voice.

### Don't
- Don't fill primary CTAs with the bright indigo `{colors.primary}` — the button fill is the deep near-black indigo `{colors.ink-deep-purple}`; the bright indigo is a type/link accent.
- Don't add heavy or colored drop shadows beyond the floating-toast level. Default is flat.
- Don't introduce a second typeface. The system is single-family Geist.
- Don't bold display weight past 600.
- Don't scatter dark surfaces — `{colors.ink-dark}` is reserved for product mockups and the single dark CTA band.
- Don't tighten body letter-spacing to 0 — keep the +0.32px technical tracking.

## Responsive Behavior

| Name | Width | Key Changes |
|---|---|---|
| Mobile | < 768px | Hamburger nav; hero h1 64→~32px and stays centered; product dashboard scales down below the fold; logo cloud wraps to 2–3 per row; story cards 1-up; pricing tiers 1-up |
| Tablet | 768–1024px | Nav tightens but stays horizontal; logo cloud reduces columns; story cards 2-up |
| Desktop | 1024–1440px | Full top-nav with all dropdown menus; centered hero; logo cloud ~6-up; story-card carousel |
| Wide | > 1440px | Same as desktop with more outer breathing room around the centered content column |

### Touch Targets
- `{component.button-primary}` / `{component.button-secondary}` pills meet comfortable tap height at ~12 × 24 padding on `{typography.body}`.
- `{component.button-icon-circular}` is ~40px diameter — close to but slightly under the 44px ideal; the full-circle silhouette compensates.
- `{component.input}` uses body-scale text with 12 × 16 padding for a tappable field.

### Collapsing Strategy
- Top nav collapses to a hamburger sheet on mobile.
- The centered hero stacks naturally (eyebrow → headline → sub-head → CTA row) at every breakpoint.
- Product dashboard mockups scale proportionally and keep their dark surface intact.
- Story-card rows become a swipeable carousel on narrow widths.

### Image Behavior
- Embedded product dashboards retain native aspect ratios; their containers resize.
- Customer-story imagery crops to `{rounded.lg}` corners at every breakpoint.
- Logo-cloud marks stay grayscale and scale uniformly.

## Iteration Guide

1. Focus on ONE component at a time. Reference its YAML key directly (`{component.product-mockup-card}`, `{component.cta-band-dark}`).
2. Variants of an existing component (`-active`, etc.) live as separate entries in `components:`.
3. Use `{token.refs}` everywhere — never inline hex.
4. Never document hover. Default and Active/Pressed states only.
5. Keep the single-family Geist discipline — change size/weight, not typeface.
6. The bright indigo is a type/link accent; the deep near-black indigo is the button fill. Don't swap them.
7. Use the purple-tinted micro-shadow for any elevation; reserve large shadows for floating toasts.

## Known Gaps

- **Section-level vertical spacing** between major bands was not captured as a discrete token — only padding/margin/gap values up to 32px were measured. Large band rhythm is derived from screenshots, not measured.
- **Button padding** (12 × 24) is derived from the dominant spacing tokens, not directly measured — the only measured button props (`radius: 50%, padding: 0px`) correspond to the circular GitHub icon button, not the pill CTAs.
- **Input radius conflict:** the measured `input` radius was 0px, contradicting the otherwise-rounded system. The frontmatter recommends `{rounded.sm}` (8px) for consistency; the 0px measurement is flagged rather than enshrined.
- **Minor radii (10px, 14px)** were measured at low frequency and excluded as incidental rounding.
- **Semantic status colors** (success/warning/error) appear only inside embedded product chrome (run-failure red/yellow dots) and could not be extracted as reliable system tokens.
- **`primary-active` (#332aa6)** is documented as the active/pressed pairing for the indigo primary based on its presence as a darker sibling in the measured palette; the exact interaction state was not captured.
- **Pricing page specifics** (tier counts, featured-tier treatment, toggle controls) were captured at the palette/type level but individual pricing components beyond `{component.pricing-card}` are not fully specified.
- Animation, transition timings, and dropdown-menu open states are out of scope.

<!-- Documented by duply · real-world design systems as ready-to-use DESIGN.md for AI coding agents · https://duply.ai/dagster/design-md -->

Color Palette

Accent

Neutrals

Typography

h164px · 600 · 1.12
The quick brown fox jumps
h248px · 600 · 1.2
The quick brown fox jumps
h318px · 500 · 1.55
The quick brown fox jumps
body14px · 400 · 1.25
The quick brown fox jumps

Spacing & Shape

Spacing

NameValuePreview
xxs4px
xtiny6px
xs8px
sm12px
md16px
lg20px
xl24px
xxl32px

Border Radius

NameValuePreview
sm8px
md12px
lg16px
xl24px
xxl48px
pill100px

More like this

Build in any
design language

Free to browse. Real design systems, documented as DESIGN.md. New designs land weekly.

Browse the libraryHow it works