Skip to content

Now in the official shadcn registry directory.

Start free
Back to gallery
fintech · saas

Ramp

A finance product that treats confidence as design discipline, not marketing tone — solar-lime CTA, smolder-green dark sections, TWK Lausanne. Brex's bolder rival.

ramp.comAdded 2026-06-23
Ramp - 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 Ramp’s language, not just a screenshot.

Paste into your agent. No signup, no cost.
Light-first warm-neutral canvas with one high-voltage signal. The surface is near-white (#fff) over a pinkish-gray panel system (#f4f2f0 / #d2cecb), text rides a warm brown-black axis (#0c0a08 ink → #6e6a68 secondary), and a single electric lime accent (#e4f222) carries every primary call to action — used homeopathically, under ~3% of surface. TWK Lausanne ('lausanne') is the sole family, carrying voice across a 300/350/400/700 weight ladder; display headings bind with px-based negative tracking (-0.01px at 64px, -0.005px at 40px). Elevation is delivered through 1px hairline borders and soft low-opacity shadows, not bloom. Discipline over decoration; one accent, used with conviction.
Main prompt
Use this capture as a design language transfer brief for my project. Adopt the palette (light-first near-white canvas + warm brown-black ink #0c0a08 + pinkish-gray neutrals #f4f2f0/#d2cecb + a single electric lime accent #e4f222 reserved for primary CTAs), typographic system (TWK Lausanne as the only family with a 300/350/400/700 weight ladder and px-based negative tracking on display sizes), the 4/8/12/16/24/64px spacing rhythm, hairline-border-first elevation (1px #d2cecb + low-opacity soft shadow), cubic-bezier(0.4, 0, 0.2, 1) @ 0.3s motion curve, and image-lazy-by-default strategy across every page and component I ship. Treat this as my project's constitution — any new component should pass as if crafted in the same studio. Apply the language, not the source brand's specific copy or identity. Keep the lime as the single signal color; never let a second element compete for it. When I ask you to build a page or component, enforce these rules by default and call out any decision that deviates.
Layout
Grid
Content width
Bounded
Framing
Flat
Grid strength
Soft

Light-first warm-neutral system — #fff canvas with #f4f2f0 / #d2cecb pinkish-gray panels and hairlines doing the structural work, all text on a warm brown-black axis (#0c0a08 primary → #6e6a68 secondary). The brand layer is a single electric lime (#e4f222, with #f5ff78 light variant), backed by a #17332d deep-green smolder and a #e96516 blaze used only for sectional atmosphere — never as competing CTAs.

Mode strategylight-first
  • Warm brown-black ink #0c0a08 (text-primary, weight 400) is the dominant reading layer; #0c0a0899 (text-hushed, ~60% alpha) and #6e6a68 (grayDark) descend for captions, metadata, de-emphasized labels.
  • Neutral skeleton #fff canvas + #f4f2f0 (grayLight) panel + #d2cecb (grayMedium / border-primary) hairlines — a pinkish-warm gray family, never cold blue-gray.
  • Electric lime #e4f222 (--solar) is the single signal color, reserved for the primary CTA and key emphasis — surface area under ~3%. #f5ff78 (--solarLight) is its hover/tint variant.
  • Deep green #17332d (--smolder) and blaze orange #e96516 (--blaze) appear only as sectional background/atmosphere; spring blue #5683d2 (--spring) and #e4ebf6 (--springLight) for illustrative accents — none ever read as a button.
  • Black-on-white panel alternation uses #1a1919 (--black) / #212121 background-black for dark sections, maintaining 4.5+ contrast with #fff foreground.

Gradients (paste-ready)

linear-gradient(in oklab to top, #e4ebf6 8%, #c3d3ef 20%, #5683d2 48%, #001b4a 100%)
linear-gradient(in oklab to bottom, #000 0%, #112d5b 100%)
linear-gradient(in oklab to bottom, #d2dff3 22%, #f2f5f9 93%)
linear-gradient(rgba(23, 18, 14, 0.2) 0%, rgba(23, 18, 14, 0.6) 60%, rgba(23, 18, 14, 0.82) 100%)
  • Single family: TWK Lausanne (self-hosted as 'lausanne', preloaded woff2 from /_next/static/media/). No second display face, no serif rescue — the entire hierarchy is one family.
  • Weight ladder: 300 / 350 / 400 / 700. 400 is the reading default; 700 carries bold emphasis and primary headings; 300/350 handle large light display moments. Do not introduce 500/600.
  • Display tracking is px-based and negative: -0.01px on the 64px hero (heading-1), -0.005px on 40px (heading-2). Smaller headings (28/24px) and body sit at normal tracking; the 10px caption variant uses +0.5px positive tracking.
  • Heading line-height runs tight: 64/64px (1.0) on hero, 40/42px on heading-2, 28/32 and 24/28 on sub-heads. Body 16/24px (1.5), small 14/20–21px, caption 10/15px.
  • Type scale (observed): hero 64px, 40px, 28px, 24px headings; 18px lead; 16px body; 14/13px small UI; 12px small; 10px caption. Material Icons Outlined for iconography at 12/16px.
  • No italic for emphasis — Lausanne carries through weight shift (400→700). Reserve italic for genuinely quoted editorial content.
  • Paragraph measure 45–60 ch at 16px body; dense UI rows may run tighter at 13–14px with 20–21px line-height.
  • 4px base unit. Scale (observed): 1 / 4 / 6 / 8 / 12 / 16 / 20 / 24 / 32 / 48 / 64 px. The 24px and 8px steps dominate (highest frequency); 6/12px handle dense padding.
  • Named macro spacers: --spacer-m 40px, --spacer-l 80px for section-level vertical rhythm.
  • Container max-width 1440px (--container-md); narrow content clusters bound at 500px (--container-sm).
  • Card / surface padding: 24px desktop (dominant), 12–16px on dense or mobile contexts. Always pick from the scale; no magic numbers.
  • Flex/grid gutters: 8px (dominant) and 16px. Section vertical rhythm: 64px blocks (--space-11) stacked with 40/80px macro spacers.
  • Nav height calc(62px + var(--nav-banner-height)); banner 40px when present — reserve this offset in sticky-header layouts.
Surface styleFlat
  • Primary structure comes from 1px solid hairline borders in #d2cecb (--border-primary) — reach for a border before any shadow.
  • Drop shadows are soft and near-invisible: stacked low-alpha layers (0.008–0.09 opacity) with large blur and zero spread — atmospheric depth, never a hard halo.
  • An inset 2px white-0.6 highlight (shadow-sm) is used to give pressed/raised controls a subtle top-light, not an outer glow.
  • Dark sections (#1a1919 / #17332d) gain depth through background-shift and gradient overlays, not stacked shadow.

Techniques

Hairline border as surface delimiter

Cards and inputs default to `border: 1px solid #d2cecb` with radius 12px. Hover deepens the border tone or adds the lime accent ring; the surface stays flat. Never switch to a heavy drop-shadow on hover.

Stacked low-opacity ambient shadow

Where elevation is genuinely needed, layer multiple shadows at 0.008–0.09 opacity (e.g. `0 232px 65px rgba(0,0,0,0.008), 0 20px 50px rgba(0,0,0,0.09), 0 9px 20px rgba(0,0,0,0.086)`) — a wide, diffuse lift with no visible edge.

Radii4 / 6 / 12Icon treatmentLinearIcon setsMaterial Icons Outlined, Remix Icon, Lucide
  • Radius scale is tight: 4px (components/badges), 6px (buttons/inputs), 12px (cards/containers). The 12px radius is dominant (28 observed occurrences).
  • Buttons and inputs default to 6px radius; cards and containers to 12px; small chips/badges to 4px.
  • Icons are outlined / stroke-based (Material Icons Outlined observed) at a light weight; no filled or duotone variants for UI affordances.
  • Tap targets minimum 40×40px on pointer, 44×44 on touch — per observed control sizing.
  • button-primary
    backgroundColor
    #e4f222
    textColor
    #0c0a08
    radius
    6px
    padding
    8px 16px
    border
    1px solid transparent
    boxShadow
    none
    fontWeight
    700
    fontSize
    16px
    lineHeight
    24px

    Tailwind

    inline-flex items-center gap-2 rounded-[6px] bg-[#e4f222] px-4 py-2 text-[16px] font-bold text-[#0c0a08] transition-colors duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] hover:bg-[#f5ff78] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#0c0a08] focus-visible:ring-offset-2
  • button-secondary
    backgroundColor
    #ffffff
    textColor
    #0c0a08
    radius
    6px
    padding
    8px 16px
    border
    1px solid #d2cecb
    boxShadow
    none
    fontWeight
    400
    fontSize
    16px
    lineHeight
    24px

    Tailwind

    inline-flex items-center gap-2 rounded-[6px] border border-[#d2cecb] bg-white px-4 py-2 text-[16px] text-[#0c0a08] transition-colors duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] hover:bg-[#f4f2f0] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#0c0a08] focus-visible:ring-offset-2
  • card-surface
    backgroundColor
    #ffffff
    textColor
    #0c0a08
    radius
    12px
    padding
    24px
    border
    1px solid #d2cecb
    boxShadow
    0 9px 20px rgba(0,0,0,0.086), 0 20px 50px rgba(0,0,0,0.09)

    Tailwind

    rounded-[12px] border border-[#d2cecb] bg-white p-6 text-[#0c0a08] shadow-[0_9px_20px_rgba(0,0,0,0.086),0_20px_50px_rgba(0,0,0,0.09)] transition-colors duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] hover:border-[#6e6a68]
  • input-field
    backgroundColor
    #ffffff
    textColor
    #0c0a08
    radius
    6px
    padding
    8px 12px
    border
    1px solid #d2cecb
    boxShadow
    none
    fontWeight
    400
    fontSize
    16px
    lineHeight
    24px

    Tailwind

    w-full rounded-[6px] border border-[#d2cecb] bg-white px-3 py-2 text-[16px] leading-6 text-[#0c0a08] placeholder:text-[#6e6a68] transition-colors duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] focus-visible:border-[#0c0a08] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[#0c0a08]
  • section-dark
    backgroundColor
    #17332d
    textColor
    #ffffff
    radius
    12px
    padding
    64px 24px
    border
    none
    boxShadow
    none

    Tailwind

    rounded-[12px] bg-[#17332d] px-6 py-16 text-white [&_a]:text-[#e4f222] [&_h2]:text-[40px] [&_h2]:leading-[42px] [&_h2]:tracking-[-0.005px] [&_h2]:font-bold
  • badge-accent
    backgroundColor
    #f5ff78
    textColor
    #0c0a08
    radius
    4px
    padding
    4px 8px
    border
    none
    fontWeight
    400
    fontSize
    12px
    lineHeight
    18px
    letterSpacing
    0.5px

    Tailwind

    inline-flex items-center rounded-[4px] bg-[#f5ff78] px-2 py-1 text-[12px] leading-[18px] tracking-[0.5px] text-[#0c0a08]
LevelmoderateDurations0.15s / 0.24s / 0.25s / 0.3s

Easings

cubic-bezier(0.4, 0, 0.2, 1)cubic-bezier(0, 0, 0.2, 1)cubic-bezier(0.45, 0.05, 0.55, 0.95)cubic-bezier(0.6, 0, 0.2, 0.5)
Hovercolor / background-color shift (0.3s on cubic-bezier(0.4, 0, 0.2, 1)) — the dominant interactive transition, color-only fade (0.24s on cubic-bezier(0.45, 0.05, 0.55, 0.95)) for text links, rotate on disclosure chevrons (0.25s on cubic-bezier(0.6, 0, 0.2, 0.5))

Scroll patterns

  • Intersection-triggered opacity + translateY reveals at 0.3s on cubic-bezier(0, 0, 0.2, 1) (ease-out tier)
  • Width/height/clip-path/opacity choreography on cubic-bezier(0.45, 0.05, 0.55, 0.95) for expanding panels
  • Stagger 40–80ms between grouped cards; no parallax beyond subtle translateY
  • Primary easing: cubic-bezier(0.4, 0, 0.2, 1) — the standard ease-in-out anchoring most color/background transitions at 0.3s (20 observed occurrences).
  • Supporting easings: cubic-bezier(0, 0, 0.2, 1) for entrance/reveal (ease-out), cubic-bezier(0.45, 0.05, 0.55, 0.95) for symmetric color fades, cubic-bezier(0.6, 0, 0.2, 0.5) for rotate.
  • Four durations captured: 0.15s (snappy state flips), 0.24s (link color), 0.25s (rotate), 0.3s (dominant — color/background and reveals). Most interactive transitions sit on 0.3s.
  • Framer Motion is the animation library (window.MotionIsMounted observed). Use deterministic cubic-bezier curves; the accent lime never animates as a fill change.
  • useReducedMotion mandatory: all animations collapse to opacity-only or disable.
  • No loop animations except explicit loaders; no spring physics — stay on the captured cubic-bezier set.
  • One primary CTA per view, always in lime (#e4f222); secondary actions are bordered white buttons — never two lime buttons competing.
  • Disclosure via accordion with a rotating chevron (0.25s); single-open for FAQ, multi-open only for nested documentation.
  • Tooltips reveal on hover + focus; dismiss on blur. Dropdowns at z-index 30, sticky nav at z 10–20, toasts at 400+.
  • Modals for confirmations; never nested modals. Mobile expansions reflow in place rather than opening alternate architecture.
  • Form validation inline below the field on blur; primary submit stays lime and disabled until valid.
  • Empty states: caption-size icon + one-line copy + a single lime action. No decorative illustration.
  • Loading states: skeleton shimmer for content (gradient from rgba(0,0,0,0.06) to rgba(0,0,0,0.15)); inline indicator for buttons.
Approachdesktop-first

Desktop-first because the audience is finance operators and admins working on wide displays (container extends to 1440px). Mobile adapts the same language without reinventing it — no hamburger-revealed alternate architecture; the page reflows into a narrower rail while keeping the single-lime-CTA discipline intact.

  • Breakpoints (observed): sm 640 / md 768 / lg 992 / xl 1280 / 2xl 1536. Note lg sits at 992, not the generic 1024.
  • Container max-width 1440px desktop; bounded 500px rail for narrow content clusters.
  • Hide-on-mobile is discouraged — if a control exists on desktop it should reach mobile via reflow.
  • Tap target minimum 44×44 on touch; 40×40 on pointer.
  • Typography scales down proportionally: hero 64 → ~40 → ~32; negative tracking eases toward normal at smaller sizes.
  • focus-visible: 2px ring in #0c0a08 with offset on light surfaces (the lime CTA is too bright to double as a focus ring — use the ink color). Mandatory on every interactive element.
  • All interactive elements reachable via Tab in logical reading order; never rely on hover to expose actions.
  • Color contrast: #0c0a08 ink on #fff ≈ 19:1 (AAA); #6e6a68 secondary on #fff ≈ 4.5:1 (AA) — never drop below 4.5:1 for body text. Lime #e4f222 is a background for dark ink, never light text on lime.
  • ARIA labels on icon-only buttons; aria-expanded on accordions; aria-live='polite' on toasts and status updates.
  • Motion respects prefers-reduced-motion — animations reduce to opacity-only or disable (media query observed in source).
  • Tap targets minimum 44×44 on touch; 40×40 on pointer.
  • Never signal state with the lime accent alone — pair color with text/icon, since a single bright hue fails for color-blind users.
  • Form errors announced via aria-describedby on the associated input; never color-only signaling.
Framer MotionNext/ImageMaterial Icons Outlined

Framer Motion drives interaction and scroll choreography (window.MotionIsMounted observed) with transitions on cubic-bezier(0.4, 0, 0.2, 1) at 0.3s. Next/Image handles imagery with lazy-loading by default (the hero treasury-card webp is the only above-fold candidate). Icons are Material Icons Outlined, stroke-based and light-weight.

  • Framer Motion `motion.div` with `whileInView` + `viewport={{ once: true }}` for scroll reveals; `ease: [0.4, 0, 0.2, 1]`, `duration: 0.3` as constants.
  • useReducedMotion guard wraps every animation primitive — no exceptions.
  • Next/Image with `sizes` always set; `priority` only on the LCP hero (treasury-card webp); everything else `loading='lazy'`.
  • oklab gradients (--dusk / --midnight / --daylight) as CSS background tokens for atmospheric sections — gate behind feature detection if supporting legacy browsers.
  • No canvas / WebGL / Lottie observed — static-first, animated-discreet.
  • Reserve the lime accent #e4f222 for exactly one primary action per view; everything else is neutral.
  • Use the warm brown-black axis (#0c0a08 ink → #6e6a68 secondary) and pinkish-gray neutrals (#f4f2f0 / #d2cecb) — never cold blue-gray.
  • Carry the entire type hierarchy on TWK Lausanne via the 300/350/400/700 weight ladder; bold (700) for primary headings and CTA text.
  • Apply px-based negative tracking on display sizes (-0.01px at 64px, -0.005px at 40px); let smaller text sit at normal tracking.
  • Reach for a 1px #d2cecb hairline border before any drop shadow; keep shadows soft and low-opacity.
  • Default interactive transitions to cubic-bezier(0.4, 0, 0.2, 1) at 0.3s; pass every page through useReducedMotion.
  • Lazy-load all imagery except the LCP hero.
  • Never let a second element compete with the lime CTA — two signal colors in one view destroys the entire effect.
  • Never substitute a cold blue-gray neutral for the warm brown-black axis; the temperature is load-bearing.
  • Never introduce a second display font — one family (TWK Lausanne) plus icon font is the boundary.
  • Never add 500/600 weights — the ladder is strictly 300/350/400/700.
  • Never use em for display tracking — the px-based scale (-0.01 / -0.005) is an optical constant, not layout-relative.
  • Never invent durations or easings outside the captured set {0.15, 0.24, 0.25, 0.3}s and {cubic-bezier(0.4,0,0.2,1), cubic-bezier(0,0,0.2,1), cubic-bezier(0.45,0.05,0.55,0.95), cubic-bezier(0.6,0,0.2,0.5)}; no springs.
  • Never use light text on the lime accent — it is a background for dark ink only.
  • Tailwind v4 @theme inline only — no runtime style concatenation, no CSS-in-JS.
  • Spacing base 4px, scale 1/4/6/8/12/16/20/24/32/48/64 plus macro spacers 40/80px.
  • Container max 1440px — do not exceed.
  • Single font family: TWK Lausanne (+ Material Icons Outlined for iconography).
  • Weight ladder strictly 300 / 350 / 400 / 700.
  • Accent strictly one lime #e4f222 (+ #f5ff78 tint) for primary action; #17332d / #e96516 / #5683d2 atmosphere only.
  • Motion: four captured durations (0.15 / 0.24 / 0.25 / 0.3 s) and four easings (cubic-bezier(0.4,0,0.2,1) primary, plus (0,0,0.2,1), (0.45,0.05,0.55,0.95), (0.6,0,0.2,0.5)). No springs.
  • Radius scale: 4 / 6 / 12 px.
  • Accent audit: exactly one #e4f222 primary CTA per view; lime surface area under ~3% of the page.
  • Color audit: neutrals draw from the warm axis {#0c0a08, #6e6a68, #d2cecb, #f4f2f0, #fff}; no cold blue-gray (#64748b-family) in the skeleton.
  • Container width: no page exceeds 1440px wide.
  • Spacing grep: no values outside the 1/4/6/8/12/16/20/24/32/48/64 ladder (plus 40/80 macro spacers).
  • Font-family grep: only 'lausanne' (TWK Lausanne) and the icon font appear — no second display family.
  • Font-weight grep: only 300, 350, 400, 700 — no 500 or 600.
  • Tracking audit: display-size text uses px-based negative tracking (-0.01 / -0.005), not em.
  • Transition grep: timing-functions draw from the four captured easings; durations from {0.15, 0.24, 0.25, 0.3}s; primary cubic-bezier(0.4,0,0.2,1) carries most transitions.
  • Shadow audit: every elevation uses a 1px #d2cecb border first; drop shadows stay soft and low-opacity.
  • Image audit: loading='lazy' on every non-LCP image; priority only on the hero.
  • Contrast audit: body text on its background ≥ 4.5:1 (WCAG AA); lime used only as a background for dark ink.

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

  • body4
    • Nav1
      • Header
    • Main2
      • Section1
        • div1
          • div1
            • div1
              • Form
      • div1
        • Section (×6)
    • Footer
    • iframe (×2)

Accessibility

Contrast matrix

24 combinations - 14 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
#000000
bg
#FFFFFF
APCA Lc
+106
Use
foreground on background
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
#0C0A08
bg
#FFFFFF
APCA Lc
+106
Use
background on background
Normal text passes AAALarge text passes AAA
fg
#FFFFFF
bg
#0C0A08
APCA Lc
-108
Use
background on background
Normal text passes AAALarge text passes AAA
fg
#212121
bg
#FFFFFF
APCA Lc
+103
Use
foreground on background
Normal text passes AAALarge text passes AAA
fg
#FFFFFF
bg
#212121
APCA Lc
-106
Use
background on foreground
Normal text passes AAALarge text passes AAA
fg
#000000
bg
#D2CDCA
APCA Lc
+78
Use
foreground on neutral
Normal text passes AAALarge text passes AAA
fg
#D2CDCA
bg
#000000
APCA Lc
-77
Use
neutral on foreground
Normal text passes AAALarge text passes AAA
fg
#0C0A08
bg
#D2CDCA
APCA Lc
+77
Use
background on neutral

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
40%
Format mix
  • svg24 · 80%
  • unknown6 · 20%

Hero image

https://ramp.com/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fplatform-treasury-card-mobile.0wu50bih6oc8f.webp&w=3840&q=75&dpl=dpl_CnX3y3FEjXXeAX5T7aRPGsuvYpdQ
Format
UNKNOWN
Dimensions
0x0
Loading
lazy
srcset
yes
srcset descriptor
/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fplatform-treasury-card-mobile.0wu50bih6oc8f.webp&w=1080&q=75&dpl=dpl_CnX3y3FEjXXeAX5T7aRPGsuvYpdQ 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fplatform-treasury-card-mobile.0wu50bih6oc8f.webp&w=3840&q=75&dpl=dpl_CnX3y3FEjXXeAX5T7aRPGsuvYpdQ 2x
Industry
fintech
Industry
saas
Theme
Light + Dark
Added
2026-06-23

FAQ

Questions people ask about Ramp

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