Skip to content

Now in the official shadcn registry directory.

Start free
Back to gallery
design tools

Spline

The 3D-tool landing that refuses to flatten itself into a screenshot — pure #000 canvas, a three-family Spline Sans / Brockmann / Spline Sans Mono trinity, and a semantic rainbow of accent CSS variables used one tone at a time. Spline demonstrates a rare creative-tool discipline: zero shadow, zero gradient, a single 1px hairline carrying every layer distinction, all motion compressed into a 0.2s CSS transition with no library overhead. The spacing scale starts at 2px so embedded canvases and video loops can breathe without feeling airy.

spline.designAdded 2026-04-24
Spline - Desktop

Editorial disclaimer

Editorial note

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 Policy
FreePrompt kit

Copy 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 Spline’s language, not just a screenshot.

Paste into your agent. No signup, no cost.
Dark-first creative-tool identity where a single 2 px-base rhythm, a three-family type system, and a code-editor accent palette (lifted from VS Code Dark+) carry the entire load of hierarchy — no shadow, no gradient, no decorative chrome. The page exists to stage the product's own canvas; every surface detail is tuned to recede.
Main prompt
Design a dark-first landing for a browser-native creative tool where the product's own output (3D scenes, interactive canvases, embedded video loops) is the visual centerpiece. Use a trio of fonts only: Spline Sans (body + UI), Brockmann (display headings), Spline Sans Mono (code, coordinates, shortcuts). Page background is pure #000000 (tokenized as `--color-bg`) with white text at full opacity (#ffffff tokenized as `--color-white-090`) plus mid-gray #888888 for de-emphasized surfaces and #191a1d for panel backgrounds. The accent vocabulary is borrowed from VS Code Dark+ syntax theme — `#569cd6` keyword cyan and `#0062ff` link blue carry the brand-tier surface (10 + 6 measured uses); `#ce9178` string orange, `#6a9955` comment green, and `#3ddc84` success green provide the supporting cast (1-6 measured uses each), applied one tone per concept, never combined decoratively. Zero box-shadow, zero linear/radial gradient (extraction gradient count: 0). Corner-radius ladder is 8 / 12 / 16 / 24 / 50 / 99 px. Spacing scale anchored on 2 / 4 / 6 / 8 / 10 / 12 / 16 px dominant with 18 / 20 / 24 / 30 appearing at lower frequency. Container widths stay narrow: 340 / 460 / 480 / 500 / 552 / 652 px. Motion vocabulary captured: 0.2 s on ease / ease-out / ease-in-out / linear for interactive feedback plus a single 100 s linear ambient drift for atmospheric loops; no motion library captured (pure CSS transitions).
Layout
centered narrow column with full-width canvas and video bands bleeding to edge; sticky nav at z-10/11 is the only persistent chrome
Content width
652px primary reading width, 460–552px for utility cards and callouts, full-viewport for embedded canvases and video
Framing
pure #000 canvas with content floating at narrow widths; canvases and video replace decorative hero art
Grid strength
implied — typography weight and spacing rhythm carry hierarchy; no visible column rails or divider grid

Pure #000000 page (tokenized as `--color-bg`) with white text (#ffffff at `--color-white-090`) and a code-editor accent palette borrowed from VS Code Dark+. Two brand-tier accents — cyan #569cd6 (10 measured uses) and link blue #0062ff (6 uses, tokenized as `--color-blue`) — carry recurring surface; supporting cast #ce9178 string-orange, #6a9955 comment-green, #3ddc84 success-green, plus #191a1d panel and #888888 mid-gray fill out the system.

Mode strategydark-only — no light mode alternate; the identity is the void itself, and switching themes would invalidate the rest of the system
  • bg #000000 (`--color-bg`) across the entire page — no alternate surface tone
  • text #ffffff (tokenized as `--color-white-090`) for headlines and primary body — 2194 measured occurrences
  • panel #191a1d for elevated surfaces (27 measured occurrences) and #888888 for mid-gray de-emphasized text (11 occurrences)
  • brand-tier cyan #569cd6 for syntax-style highlights and code-editor surfaces (10 measured uses)
  • brand-tier link blue #0062ff (`--color-blue`) for primary CTA, link, and active state (6 measured uses)
  • supporting code-editor accents #ce9178 (string orange), #6a9955 (comment green), #3ddc84 (success green) applied semantically — one tone per concept
  • One sans (Spline Sans), one display (Brockmann), one mono (Spline Sans Mono) — do not introduce a fourth family
  • Preload the four hero weights locally as woff2: SplineSans-Regular, SplineSans-Medium, Brockmann-Regular, Brockmann-Medium
  • Hero display maximum is 36px / 44 line-height at weight 500 — do not scale the heading type beyond this
  • Body paragraph 18px / 28 line-height at weight 400 is the only comfortable reading size on dark
  • Utility text 14px / 20 line-height at weight 400–500, captions 12px / 16–18 line-height
  • Mono appears only in code blocks, coordinates, shortcuts, and API signatures — never in prose
  • Letter-spacing stays 'normal' across the entire system — do not track-open for atmosphere
  • Base unit is 2px — scale is strictly 2 / 4 / 6 / 8 / 10 / 12 / 14 / 16 / 18 / 20 / 24 / 30
  • No value above 30px in a single gap — larger vertical distance is implied by section height, not margin
  • 24–30 for section padding, 12–16 for component internal rhythm, 2–6 for chip and pill micro-spacing
  • Gap values inherit from the scale — no improvised 22px or 28px steps
Surface styleflat — zero box-shadow, zero filter: drop-shadow; elevation reads through border contrast and spacing
  • Elevation is communicated by 1px solid border at white/10–20 opacity, never by shadow
  • Layering uses z-index 1–11 only: inline-overlap 1–4, sticky-nav 10–11
  • Modal and popover surfaces (if introduced) should match the same flat-with-hairline treatment

Techniques

border-only layering

Cards sit on #000 with a single 1px solid hairline at rgba(255,255,255,0.08–0.16) that separates them from the canvas without adding mass

z-index minimalism

Only two semantic bands in use — inline-overlap (1–4) for local stacking and sticky-nav (10–11) for the persistent header

Radii8 / 12 / 16 / 24 / 50 / 99Icon treatmentline-weight SVG, monochrome, sized alongside typography — icons inherit currentColor and scale with textIcon setscustom in-house SVG — no Remix / Lucide / Phosphor detected
  • 8px for chips and small inline buttons
  • 12–16px for cards, inputs, and panels
  • 24px for feature blocks and larger containers
  • 50–99px pill radius for primary CTA and tag chips
  • Primary CTA pill
    background
    #0062ff
    color
    #ffffff
    padding
    10px 20px
    borderRadius
    99px
    transition
    all 0.2s ease

    Tailwind

    inline-flex items-center gap-2 rounded-full bg-[#0062ff] px-5 py-2.5 text-sm font-medium text-white transition-all duration-200 ease-out hover:opacity-90
  • Card panel (flat + hairline)
    background
    #000
    border
    1px solid rgba(255,255,255,0.12)
    borderRadius
    16px
    padding
    24px

    Tailwind

    rounded-2xl border border-white/10 bg-black p-6 text-white/90
  • Code-editor accent chip (cyan brand-tier)
    background
    transparent
    border
    1px solid rgba(255,255,255,0.16)
    color
    #569cd6
    padding
    4px 10px
    borderRadius
    99px
    fontFamily
    Spline Sans Mono
    fontSize
    12px

    Tailwind

    inline-flex items-center rounded-full border border-white/15 px-2.5 py-1 font-mono text-xs text-[#569cd6]
  • Sticky top nav
    position
    sticky
    top
    0
    zIndex
    10
    background
    #000
    borderBottom
    1px solid rgba(255,255,255,0.08)
    padding
    14px 24px

    Tailwind

    sticky top-0 z-10 flex items-center justify-between border-b border-white/8 bg-black px-6 py-3.5
  • link-inline
    color
    #ffffff
    textDecoration
    underline
    textDecorationColor
    rgba(255,255,255,0.4)
    textDecorationThickness
    1px
    textUnderlineOffset
    3px
    transition
    color 200ms ease, text-decoration-color 200ms ease

    Tailwind

    text-white underline decoration-white/40 decoration-[1px] underline-offset-[3px] transition-colors duration-200 ease-out hover:text-[#569cd6] hover:decoration-[#569cd6] focus-visible:outline-none focus-visible:decoration-[#569cd6]
LevelexpressiveDurations0.2s / 100s

Easings

easeease-outease-in-outlinear
Hovercolor fade 0.2s ease for link and nav items, transform 0.2s ease-out on buttons and interactive cards (scale or translate micro-shift), opacity 0.2s ease for secondary text reveal

Scroll patterns

  • sticky nav pins at z-10/11 with hairline appearing on scroll
  • canvas and video sections remain in normal flow — no pin-and-release tricks
  • ambient atmospheric loops drift on a long 100 s linear cycle — slow enough to read as static at any single glance
  • Two-tier timing: 0.2 s for interactive feedback (ease / ease-out / ease-in-out) and 100 s linear for ambient atmospheric loops. The two tiers stay separated — interactive transitions never extend, ambient loops never speed up.
  • No motion library captured — CSS transitions only (Framer Motion or GSAP would violate the philosophy).
  • Reserve transform for interactive feedback; use color and opacity for state change.
  • Gate all transitions on `@media (prefers-reduced-motion: reduce)` — collapse to 0.01 ms; pause the 100 s ambient drift.
  • Hover on interactive text: color fade 0.2s toward solid white
  • Buttons: subtle scale or translate shift on press, never a shadow-lift
  • Focus: underline + opacity shift; avoid heavy focus rings that clash with the flat surface
  • Canvases are interactive by default — no modal gate before the user can touch the scene
  • Links in paragraph adopt the primary blue #0062ff with hover handled by an opacity dim — no separate lighter-blue token in the captured palette.
Approachdesktop-first

sm 500 / md 720 / lg 1080 / xl 1160 / 2xl 1536 — deliberately small sm breakpoint catches narrow phones before the layout resets

  • Below md (720) canvases become full-bleed video loops with reduced text overlay
  • lg (1080) unlocks narrow container stacking and two-column feature grids
  • xl (1160) is the comfortable read width; 2xl (1536) is the max container cap
  • Mobile retains the 2px spacing scale but favors 12–16px section gaps over 24–30px
  • White on black = 21:1 contrast — the foundational guarantee
  • Secondary text at 60–70% opacity still exceeds AAA on #000 — do not drop below 60%
  • Accent blue #0062ff on #000 measures ~4.8:1 — AA for CTA text, sufficient for large display
  • All interactive elements keyboard reachable; focus state via underline + opacity, no ring needed
  • Motion 0.2s fits prefers-reduced-motion — gate all transitions on the media query
  • Embedded canvases require keyboard alternative or explicit opt-out for reduced-motion users
Spline WebGL runtime for hero and feature canvasesHTMLVideoElement with `loop` + `muted` + `playsInline` for feature loopsNext.js Image with lazy loading (100% lazy usage across 30 images)

The product itself is the graphic language — pages embed live Spline scenes and short video loops where a screenshot would otherwise sit

  • Lazy-load canvases with IntersectionObserver; instantiate only when in view
  • Provide poster frames for all videos so the page shape is stable pre-load
  • Fall back to a still image when WebGL is unavailable or prefers-reduced-motion is on
  • Let canvases and video dominate visually; keep the surrounding UI quiet
  • Use accent colors semantically — one color per concept, reused across the page
  • Stick to the 2px spacing scale — improvised 22px or 28px values will break the rhythm
  • Preload the four hero weights (SplineSans + Brockmann Regular/Medium) so first paint wears the real type system
  • Use 1px hairline borders at white/8–20 opacity for every surface distinction
  • Don't add drop shadows to cards — the system is shadow-free by design
  • Don't introduce gradients for atmosphere — the page is pure #000 on purpose
  • Don't exceed 30px in a single gap — section rhythm is carried by height, not margin
  • Don't combine the code-editor accents on a single component — one concept = one color (cyan or blue or string-orange or comment-green, never two together)
  • Don't replace the mono font with a generic — Spline Sans Mono is the coordinate/code voice
  • No shadow tokens in the system (0 box-shadow, 0 drop-shadow)
  • No gradient tokens in the system (0 linear, 0 radial)
  • Exactly three font families (Spline Sans, Brockmann, Spline Sans Mono)
  • Exactly 6 border-radius steps: 8 / 12 / 16 / 24 / 50 / 99px
  • Only 1px solid borders — no 2px, no dashed, no dotted
  • Motion: 0.2 s for interactive (ease / ease-out / ease-in-out) and a single 100 s linear ambient drift — no spring, no custom cubic-bezier captured.
  • grep 'box-shadow:' in output stylesheets returns zero non-inherited rules
  • grep 'linear-gradient\|radial-gradient' in custom CSS returns zero matches
  • font-family enumeration returns exactly {Spline Sans, Spline Sans Mono, Brockmann} plus ui-monospace fallback
  • border-radius values grep shows only 8px / 12px / 16px / 24px / 50px / 99px
  • transition-duration grep across components shows {0.2s, 100s} only — no intermediate values
  • CSS variables `--color-bg` (#000000), `--color-blue` (#0062ff), `--color-white-090` (#ffffff) resolve to the spec hexes; the brand-tier palette derives from VS Code Dark+ syntax theme rather than custom invention

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. 15 nodes across 5 levels, shallow to deep by color.

  • body1
    • div3
      • Header1
        • Nav
      • Main6
        • Section (×5)
        • div1
          • Section
        • Section
        • div1
          • Section
        • Section (×2)
        • [+3 more]
      • Footer1
        • Section (×2)

Accessibility

Contrast matrix

54 combinations - 26 pass AA - 12 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.

Normal text passes AAALarge text passes AAA
fg
#FFFFFF
bg
#000000
APCA Lc
-108
Use
background on foreground
Normal text passes AAALarge text passes AAA
fg
#000000
bg
#FFFFFF
APCA Lc
+106
Use
foreground on background
Normal text passes AAALarge text passes AAA
fg
#FFFFFF
bg
#191A1D
APCA Lc
-107
Use
background on foreground
Normal text passes AAALarge text passes AAA
fg
#191A1D
bg
#FFFFFF
APCA Lc
+104
Use
foreground on background
Normal text passes AAALarge text passes AAA
fg
#000000
bg
#3DDC84
APCA Lc
+71
Use
foreground on accent
Normal text passes AAALarge text passes AAA
fg
#3DDC84
bg
#000000
APCA Lc
-70
Use
accent on foreground
Normal text passes AAALarge text passes AAA
fg
#191A1D
bg
#3DDC84
APCA Lc
+70
Use
foreground on accent
Normal text passes AAALarge text passes AAA
fg
#3DDC84
bg
#191A1D
APCA Lc
-69
Use
accent on foreground
Normal text passes AAALarge text passes AAA
fg
#000000
bg
#CE9178
APCA Lc
+53
Use
foreground on accent

Images

Image strategy

Observable image posture - total count, lazy-loading ratio, and format mix. The hero image is measured above the fold.

Total images
30
Lazy loaded
100%
Format mix
  • webp26 · 67%
  • unknown13 · 33%

Hero image

https://spline.design/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fspline_logo.54f4e584.png&w=64&q=75
Format
UNKNOWN
Dimensions
64x64
Loading
lazy
srcset
yes
srcset descriptor
/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fspline_logo.54f4e584.png&w=64&q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fspline_logo.54f4e584.png&w=128&q=75 2x
Industry
design-tools
Theme
Dark
Added
2026-04-24

FAQ

Questions people ask about Spline

3questions

Answers 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