- fg
#000000- bg
#FFFFFF- APCA Lc
- +106
- Use
- foreground on background
Modal
Serverless AI-compute marketing surface as composed as the runtime it ships — black canvas, acid-green accent, rich gradient glow. Infra as conviction.

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 Modal’s language, not just a screenshot.
Dark-first developer infrastructure aesthetic on a pure-black canvas (#000000 body, #181818 panel). A single acid-green brand accent (#7fee64) carries every CTA, link, and glow; a secondary teal (#10a550) handles supporting state. The page is lit, not decorated — nearly a dozen low-opacity green radial gradients bleed in from corners and rise from the bottom edge, acting as ambient light sources rather than hero banners. Display voice is carried by a characterful display face (Goga) from 24 to 64px; Inter Variable handles body; Fira Mono handles code and technical labels. Elevation comes from 1px hairlines, not shadows. Motion is expressive — it permits a bouncy overshoot curve where most pages would not.
Use this capture as a design language transfer brief for my project. Adopt the palette (pure-black canvas #000000 + near-black panel #181818, a single high-voltage green accent #7fee64 + supporting teal #10a550, near-white green-tinted text #ddffdc), the ambient lighting strategy (low-opacity green radial gradients used as light sources on the dark canvas, never as fills), the typographic split (a characterful display family for headings scaling to 64px, Inter Variable for body, a monospace for code and technical labels), the 2px-base spacing scale, hairline-first elevation (1px solid borders over drop shadows), the radius scale (4/8/11/12/25px), and the expressive motion vocabulary (cubic-bezier(0.4, 0, 0.2, 1) primary, plus a bouncy cubic-bezier(0.34, 1.56, 0.64, 1) used selectively). Treat this as my project's constitution — any new component I author should pass as if crafted in the same studio. 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 call out any decision that deviates.
- Layout
- Grid
- Content width
- Bounded
- Framing
- Layered
- Grid strength
- Strong
Pure-black-first canvas — #000000 body paired with #181818 panel doing the dominant surface work, lit by a single acid-green brand accent #7fee64 (the most-frequent brand-tier color). Foreground text is a near-white green-tinted #ddffdc; on the rare light section the canvas inverts to #def0dd. Secondary text descends through muted greens: #5b6d5c (the most-measured text color) for de-emphasized body. A supporting teal #10a550 carries secondary accent state. The accent green appears almost exclusively in CTAs, links, and as low-opacity radial glows — never as a large fill.
- Pure-black canvas pair #000000 (body, 1290 measured occurrences) + #181818 (panel) doing the dominant surface work
- Near-white green-tinted text #ddffdc (863 occurrences) as the primary reading layer on the dark canvas
- Muted green #5b6d5c (the single most-measured text color, 1426 occurrences) for de-emphasized / secondary body text
- Acid-green brand accent #7fee64 (isBrandTier) reserved for CTAs, links, focus, and gradient glows — surface area kept scarce
- Secondary teal accent #10a550 (isBrandTier) for supporting state and secondary emphasis, never competing with the primary green
- Light-section inversion #def0dd background only where the page deliberately flips out of dark mode
Gradients (paste-ready)
radial-gradient(165% 110% at 50% 100%, rgba(128, 238, 100, 0.4) 0%, rgba(128, 238, 100, 0.22) 22%, rgba(128, 238, 100, 0.1) 42%, rgba(128, 238, 100, 0.03) 65%, rgba(128, 238, 100, 0) 92%) radial-gradient(55% 45% at 45% -8%, rgba(195, 198, 64, 0.85) 0%, rgba(120, 130, 30, 0.55) 22%, rgba(0, 0, 0, 0) 65%) radial-gradient(35% 45% at 105% 32%, rgba(120, 220, 130, 0.75) 0%, rgba(40, 140, 70, 0.45) 25%, rgba(0, 0, 0, 0) 70%) radial-gradient(60% 80% at -8% 50%, rgba(127, 238, 100, 0.55), rgba(127, 238, 100, 0) 65%) linear-gradient(to top, rgb(33, 37, 37), rgba(0, 0, 0, 0))
- Display family: Goga (self-hosted) carries all headings from 24px to 64px. Body family: Inter Variable. Monospace: Fira Mono (self-hosted, weights 400/500/700) for code, kbd, and technical labels.
- Display weight ladder: Goga 400 (most headings) + 500 (hero / display sizes 42-64px). Body Inter Variable at 400 (reading) / 500 (UI labels + dense body).
- Heading scale (Goga): 24px / 30px / 40px / 54px / 64px — large-step jumps for clear hierarchy. Hero sits at 64px with unitless 1.0 line-height (display sits tight).
- Body Inter Variable: 16px / 14px / 12px with line-heights 24 / 20 / 16px respectively. Default body is 16px/500 with -0.36px tracking.
- Letter-spacing in px, not em: -0.36px is the recurring optical correction on body and most UI text; large Goga headings run at normal tracking; 12px micro-labels use +0.6px positive tracking.
- Monospace mandatory for code, inline `kbd`, and technical identifiers (Fira Mono). Reach for it to signal the developer register the page is built for.
- No second display font beyond Goga — the display/body/mono trio is the boundary; mixing in a fourth family dilutes the technical voice.
- 2px base unit. Scale: 2 / 4 / 6 / 8 / 10 / 12 / 16 / 18 / 20 / 24 / 28 / 32 — 20px (103 occurrences) and 12px (60) are the dominant rhythm values.
- Container max-width 1400px (the primary bounded rail). Narrow content clusters use a 368px secondary rail.
- Gutter values for flex/grid draw from 8 / 12 / 18 / 20 / 24 / 32 / 48 / 64 px — 24px (25 occurrences) is the default flex gap; 32px and 48px appear in grid columns/rows.
- Section padding leans on 32px (49 occurrences) as the primary block padding; 24px and 20px for tighter clusters.
- Card / control padding: 16-24px on desktop, 8-12px on dense mobile. Always pick from scale values; no magic numbers.
- Primary elevation is a 1px solid hairline border (the overwhelmingly dominant border treatment — 89 hairline occurrences, solid style). Use a border before reaching for a drop shadow.
- Drop shadows are rare and soft — the one captured shadow is `0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1)`. Never a bloom or a halo.
- Depth on the black canvas comes from background-shift (#000000 body → #181818 panel) plus the 1px hairline, not from stacked shadow.
- Green radial gradients provide perceived depth and atmosphere as ambient light sources behind content — layer them under text, never over it.
Techniques
Hairline border on near-black panel
Panels separate from the #000000 body via a #181818 background and a 1px solid border (border color descends through #485346 on darker contexts). Hover may brighten the border rather than adding shadow — stay on the surface.
Ambient green radial glow
Sections receive low-opacity green radial gradients bleeding from corners and rising from the bottom edge, e.g. `radial-gradient(165% 110% at 50% 100%, rgba(128,238,100,0.4) 0%, ... rgba(128,238,100,0) 92%)`. Single-digit-to-40% opacity, no hard edges, purely atmospheric lighting — never a content surface.
- Radius scale: 4 / 8 / 11 / 12 / 25 px. 8px (16 occurrences) is the workhorse; 12px for larger cards; 25px for pill-shaped controls and badges.
- Buttons and inputs default to 8px radius; larger cards/panels 11-12px; pills use the 25px radius for tag/indicator chips.
- Icons are stroke-based, thin weight, to match the monospace technical register; no filled or duotone variants.
- Tap targets minimum 40×40px on pointer, 44×44 on touch — per standard accessible control sizing.
button-primary- backgroundColor
- #7fee64
- textColor
- #000000
- radius
- 8px
- padding
- 8px 16px
- border
- 1px solid transparent
- boxShadow
- none
- fontFamily
- Inter Variable
- fontWeight
- 500
- fontSize
- 14px
- lineHeight
- 20px
- letterSpacing
- -0.36px
Tailwind
inline-flex min-h-[40px] items-center gap-2 rounded-[8px] bg-[#7fee64] px-4 py-2 text-[14px] font-medium leading-[20px] tracking-[-0.36px] text-[#000000] transition-colors duration-[150ms] ease-[cubic-bezier(0.4,0,0.2,1)] hover:bg-[#10a550] hover:text-[#ddffdc] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#7fee64] focus-visible:ring-offset-2 focus-visible:ring-offset-[#000000]
button-secondary- backgroundColor
- #181818
- textColor
- #ddffdc
- radius
- 8px
- padding
- 8px 16px
- border
- 1px solid #485346
- boxShadow
- none
- fontFamily
- Inter Variable
- fontWeight
- 500
- fontSize
- 14px
- lineHeight
- 20px
Tailwind
inline-flex min-h-[40px] items-center gap-2 rounded-[8px] border border-[#485346] bg-[#181818] px-4 py-2 text-[14px] font-medium leading-[20px] tracking-[-0.36px] text-[#ddffdc] transition-colors duration-[150ms] ease-[cubic-bezier(0.4,0,0.2,1)] hover:border-[#7fee64] hover:text-[#7fee64] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#7fee64]
card-surface- backgroundColor
- #181818
- textColor
- #ddffdc
- radius
- 12px
- padding
- 24px
- border
- 1px solid #485346
- boxShadow
- none
Tailwind
rounded-[12px] border border-[#485346] bg-[#181818] p-6 text-[#ddffdc] transition-colors duration-[150ms] ease-[cubic-bezier(0.4,0,0.2,1)] hover:border-[#7fee64]
glow-section- backgroundColor
- #000000
- backgroundImage
- radial-gradient(165% 110% at 50% 100%, rgba(128, 238, 100, 0.4) 0%, rgba(128, 238, 100, 0.22) 22%, rgba(128, 238, 100, 0.1) 42%, rgba(128, 238, 100, 0.03) 65%, rgba(128, 238, 100, 0) 92%)
- padding
- 32px
- textColor
- #ddffdc
Tailwind
relative overflow-hidden bg-[#000000] p-8 text-[#ddffdc] before:pointer-events-none before:absolute before:inset-0 before:bg-[radial-gradient(165%_110%_at_50%_100%,rgba(128,238,100,0.4)_0%,rgba(128,238,100,0.22)_22%,rgba(128,238,100,0.1)_42%,rgba(128,238,100,0.03)_65%,rgba(128,238,100,0)_92%)]
input-field- backgroundColor
- #000000
- textColor
- #ddffdc
- radius
- 8px
- padding
- 8px 12px
- border
- 1px solid #485346
- boxShadow
- none
- fontFamily
- Inter Variable
- fontSize
- 16px
- lineHeight
- 24px
- letterSpacing
- -0.36px
Tailwind
w-full rounded-[8px] border border-[#485346] bg-[#000000] px-3 py-2 text-[16px] leading-[24px] tracking-[-0.36px] text-[#ddffdc] placeholder:text-[#5b6d5c] transition-colors duration-[150ms] ease-[cubic-bezier(0.4,0,0.2,1)] focus-visible:outline-none focus-visible:border-[#7fee64] focus-visible:ring-1 focus-visible:ring-[#7fee64]
code-block- backgroundColor
- #181818
- textColor
- #ddffdc
- radius
- 8px
- padding
- 16px
- border
- 1px solid #485346
- fontFamily
- Fira Mono
- fontSize
- 14px
- lineHeight
- 20px
Tailwind
rounded-[8px] border border-[#485346] bg-[#181818] p-4 font-mono text-[14px] leading-[20px] text-[#ddffdc] [font-family:'Fira_Mono',monospace]
Easings
cubic-bezier(0.4, 0, 0.2, 1)cubic-bezier(0, 0, 0.2, 1)cubic-bezier(0.34, 1.56, 0.64, 1)ease-outScroll patterns
- Opacity reveals at 0.5s on cubic-bezier(0.4, 0, 0.2, 1)
- filter + transform reveals at 0.3s on ease-out / cubic-bezier(0.4, 0, 0.2, 1)
- Bouncy translate entrances using cubic-bezier(0.34, 1.56, 0.64, 1) over 0.9s (paired with a 0.6s background-color settle) — used selectively for personality, never on every element
- Marquee / infinite logo scroll at 80s linear for ambient ticker rows only
- Primary easing: cubic-bezier(0.4, 0, 0.2, 1) (the standard ease-in-out, 50 occurrences) anchors most color/background/border transitions.
- Supporting easings: cubic-bezier(0, 0, 0.2, 1) (ease-out, for entering elements), ease-out (legacy keyword), and the signature bouncy cubic-bezier(0.34, 1.56, 0.64, 1) for selective overshoot personality.
- Five durations captured: 0.15s (primary state change, 52 occurrences), 0.3s (reveals + filter), 0.5s (opacity reveals), and 0.6s/0.9s (paired bouncy translate). Most interactive transitions sit on 0.15s.
- The bouncy cubic-bezier(0.34, 1.56, 0.64, 1) is the expressive signature — spend it on hero/entrance moments, not on routine hovers.
- useReducedMotion mandatory: all animations collapse to opacity-only or disable, including the bouncy overshoot.
- No loop animations except the explicit 80s linear logo marquees and loaders.
- CTAs use the solid acid-green button as the single primary action per section; secondary actions use the bordered near-black variant.
- Links carry the green accent on hover/focus; default body links underline only on interaction to keep the dense black canvas calm.
- Code samples are first-class interactive content — copy-to-clipboard on hover, monospace throughout, never screenshotted.
- Accordion: single-open for FAQ; multi-open only for nested documentation.
- Tooltips reveal on hover + focus with a short delay, dismiss instantly on blur.
- Modals for destructive confirmations; never nested modals. Drawers for mobile-only expansions.
- Empty / loading states: monospace caption + green inline spinner for buttons; skeleton shimmer for content. No full-page overlays.
Desktop-first because the audience is engineers on wide displays evaluating infrastructure (Modal's primary container extends to 1400px). Mobile reflows the same language — the dark canvas, green accent, and type scale stay intact; nothing is hidden or re-architected behind a hamburger-only alternate layout. The page is the page, just narrower.
- Breakpoints: sm 640 / md 768 / lg 1024 / xl 1280 / 2xl 1536 — standard Tailwind ladder (matches captured media queries at 768/1024/1200).
- Container max-width 1400px primary, 368px for narrow bounded clusters.
- Hide-on-mobile is banned — if a control exists on desktop, it must reach mobile via reflow.
- Tap target minimum 44×44 on touch; 40×40 on pointer devices.
- Typography scales proportionally: hero 64 → 40 → 30 (Goga), body holds 16 → 14; tracking stays at -0.36px across sizes.
- Honor the captured `prefers-reduced-motion` and `forced-colors` media queries — both are observed in the source.
- focus-visible: 2px green (#7fee64) ring with a #000000 offset on every interactive element. Mandatory, never removed.
- All interactive elements reachable via Tab in logical reading order; never rely on hover to expose actions.
- Color contrast: #ddffdc on #000000 ≈ 18:1 (AAA); the green accent #7fee64 on #000000 ≈ 14:1 — but never place small green text on near-black panels (#181818) without verifying ≥ 4.5:1. Muted #5b6d5c on #000000 is borderline — reserve it for large or de-emphasized text only.
- ARIA labels on icon-only buttons; aria-expanded on collapsible regions; aria-live='polite' on toast and status updates.
- Motion respects prefers-reduced-motion (the media query is present in source) — animations reduce to opacity-only, including the bouncy overshoot curve.
- Honor forced-colors / Windows High Contrast (the media query is present in source) — never rely on the green accent alone to convey state.
- Tap targets minimum 44×44 on touch; 40×40 on pointer.
- Form errors announced via aria-describedby on the associated input; never color-only signaling — pair the green/teal with text or an icon.
The source ships SvelteKit (observable via /_app/immutable/ asset paths and svelte-scoped animation class names). Motion is CSS-driven (css-only font strategy, scoped @keyframes for the 80s logo marquee). The signature green ambient lighting is pure layered CSS radial gradients — no canvas, no WebGL. Icons are stroke-based, thin weight.
- Ambient green glows are layered CSS radial-gradients on the section background — calibrate opacity to single digits to 40% so they read as light, not fill
- Scroll reveals use intersection-triggered opacity/transform with the captured durations (0.3 / 0.5s) and easings — wrap in a reduced-motion guard
- The bouncy cubic-bezier(0.34, 1.56, 0.64, 1) translate entrance is a CSS transition, not a spring — keep it deterministic and selective
- Fonts are self-hosted woff2 with font-display: swap (Goga, Inter Variable, Fira Mono) — no Google Fonts CDN dependency
- Logo marquees use a single @keyframes translate loop at 80s linear; pause on prefers-reduced-motion
- Keep the acid-green accent (#7fee64) scarce — CTAs, links, focus rings, and gradient glows only; verify its surface area stays small against the black.
- Use green radial gradients as ambient light sources behind content at single-digit-to-40% opacity, never as a content fill.
- Reach for a 1px solid hairline border before any drop shadow on the dark canvas.
- Use the monospace (Fira Mono) for all code, kbd, and technical identifiers to hold the developer register.
- Pair the green/teal with text or icon for any state signal — never color alone.
- Default to cubic-bezier(0.4, 0, 0.2, 1) for routine transitions; reserve the bouncy cubic-bezier(0.34, 1.56, 0.64, 1) for selective entrance personality.
- Pass every page through useReducedMotion and verify the forced-colors fallback before shipping.
- Never flood large surfaces with the acid green — it is a pointer, not a paint. Its power is scarcity against #000000.
- Never port the green radial-glow stack onto a light background — these gradients are calibrated for a near-black canvas; on white they turn muddy.
- Never substitute a generic blue or purple for the brand green — the single acid-green accent IS the brand.
- Never introduce a fourth font family — the Goga (display) / Inter Variable (body) / Fira Mono (code) trio is the boundary.
- Never apply the bouncy overshoot curve to every interaction — selective use is what keeps it confident rather than nervous.
- Never invent durations outside the captured set {0.15, 0.3, 0.5, 0.6, 0.9}s or easings beyond {cubic-bezier(0.4,0,0.2,1), cubic-bezier(0,0,0.2,1), cubic-bezier(0.34,1.56,0.64,1), ease-out}.
- Never animate `height: auto` — use measured transforms or scaleY.
- Tailwind v4 @theme inline only — no runtime style concatenation, no CSS-in-JS.
- Spacing base 2px, scale 2/4/6/8/10/12/16/18/20/24/28/32.
- Container max 1400px — do not exceed (368px narrow rail for bounded clusters).
- Three font families only: Goga (display) + Inter Variable (body) + Fira Mono (code).
- Weight ladder: Goga 400/500, Inter Variable 400/500, Fira Mono 400/500/700.
- Color: #000000 / #181818 canvas, #ddffdc / #5b6d5c text, #7fee64 brand accent + #10a550 secondary; light inversion #def0dd only where deliberate.
- Motion: four captured easings (cubic-bezier(0.4,0,0.2,1) primary, cubic-bezier(0,0,0.2,1), cubic-bezier(0.34,1.56,0.64,1) bouncy, ease-out) and five durations (0.15/0.3/0.5/0.6/0.9s). No springs.
- Radius scale: 4 / 8 / 11 / 12 / 25 px.
- Borders: 1px solid hairline is the dominant elevation; drop shadows soft and rare (≤ 0.1 opacity).
- Container width: no page exceeds 1400px wide.
- Spacing grep: no values outside the 2/4/6/8/10/12/16/18/20/24/28/32 ladder.
- Accent audit: #7fee64 appears only in CTAs, links, focus rings, and gradient glows — never as a large fill; total green surface area stays small.
- Font grep: only Goga (headings), Inter Variable (body), and Fira Mono (code) appear — no fourth family.
- Weight grep: Goga 400/500, Inter 400/500, Fira Mono 400/500/700 — no stray weights.
- Transition timing grep: values draw from {cubic-bezier(0.4,0,0.2,1), cubic-bezier(0,0,0.2,1), cubic-bezier(0.34,1.56,0.64,1), ease-out}; the bouncy curve appears only on selective entrances.
- Transition duration grep: values draw from {0.15s, 0.3s, 0.5s, 0.6s, 0.9s}.
- Shadow / border audit: every elevation uses a 1px solid hairline first; drop shadows ≤ 0.1 opacity.
- Gradient audit: green radial glows sit behind content at single-digit-to-40% opacity, never as a content fill, never on a light background.
- Contrast audit: #ddffdc on #000000 ≥ 4.5:1 (AAA); muted #5b6d5c reserved for large/de-emphasized text only.
- Tracking audit: body and UI text use -0.36px tracking; large Goga headings use normal tracking.
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. 14 nodes across 7 levels, shallow to deep by color.
- body1
- div1
- div4
- div1
- div1
- Nav
- Main2
- Section1
- Section
- div (×4)1
- div1
- Article (×4)
- Section
- Footer
Accessibility
Contrast matrix
68 combinations - 40 pass AA - 24 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
#DDFFDC- APCA Lc
- +101
- Use
- foreground on background
- fg
#DDFFDC- bg
#000000- APCA Lc
- -102
- Use
- background on foreground
- fg
#181818- bg
#FFFFFF- APCA Lc
- +105
- Use
- foreground on background
- fg
#FFFFFF- bg
#181818- APCA Lc
- -107
- Use
- background on foreground
- fg
#000000- bg
#DEF0DD- APCA Lc
- +94
- Use
- foreground on background
- fg
#DEF0DD- bg
#000000- APCA Lc
- -95
- Use
- background on foreground
- fg
#DDFFDC- bg
#181818- APCA Lc
- -101
- 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.
- svg3 · 75%
- png1 · 25%
- Industry
- ai
- Industry
- developer-tools
- Theme
- Dark
- Added
- 2026-06-23
FAQ
Questions people ask about Modal
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



