Dribbble Shot Page Design System
Overview
Dribbble's shot detail page presents a restrained, editorial canvas where the work itself commands attention. The system rests on a near-white foundation ({colors.surface-soft} — #ffffff) with near-black ink ({colors.ink} — #0d0c22) carrying all textual information. Brand voltage arrives through two deliberate channels: a vivid pink accent ({colors.accent} — #ea4889) that activates only the search submission button, and deep navy-black fills that anchor primary actions and the announcement banner. The overall mood is one of professional curation—content-forward, typographically precise, and visually calm.
The typography relies entirely on Mona Sans, a geometric humanist face that carries hierarchy through weight modulation (450 for readable body text, 600–700 for display roles) and size steps (12px micro-labels up to 32px display headlines). There is no decorative letter-spacing, no uppercase transforms, no italic flourishes—just clean weight-on-size contrast. Shape language favors the practical: 8px standard rounding on cards and inputs, perfect circles for avatars and icon buttons, and pill-shaped terminations on all call-to-action buttons. The radius vocabulary never exceeds 12px except for intentional circles and pills.
The page architecture divides into three distinct zones: the persistent top navigation bar (search-first, utility-right), the shot metadata header (designer identity + action cluster), and the immersive shot display area (full-width canvas with floating interaction tools). A fourth zone—the dark announcement banner—overlays at the viewport top on certain visits. Each zone carries its own surface treatment while remaining visually unified through consistent token application.
Key Characteristics:
- Canvas anchored at
{colors.surface-soft}(#ffffff) with{colors.ink}(#0d0c22) as the sole primary text color - Brand accent
{colors.accent}(#ea4889) reserved exclusively for the search trigger and high-intent CTAs - Primary actions rendered in
{colors.primary}(#0d0c22) solid fills with{colors.on-primary}(#ffffff) counter-text - Body copy set in
{typography.body-md}(Mona Sans, 16px, weight 450) at generous 1.75 line-height - Standard corner rounding of
{rounded.DEFAULT}(8px) across cards, inputs, and containers;{rounded.pill}for buttons - Announcement banner uses inverted scheme:
{colors.primary}background,{colors.on-dark}text - Floating action buttons employ
{rounded.circle}geometry at 48px touch targets - Spacing scale built on
{spacing.xl}(36px) as the dominant rhythm unit - Shadows remain minimal:
{extensions.shadows.sm}for cards,{extensions.shadows.md}for elevated surfaces
Colors
Brand & Accent
- Primary (
{colors.primary}— #0d0c22): Deep navy-black used for the "Log in" button fill, "Get in touch" CTA, announcement banner background, and all primary interactive states. Carries maximum visual weight. - Primary Active (
{colors.primary-active}— #060318): Slightly deeper variant for pressed/focused states on primary buttons. - Accent (
{colors.accent}— #ea4889): Vibrant pink reserved for the search submit button (circle icon) and as the single injective color in an otherwise neutral palette. Never used for backgrounds. - Accent Hover (
{colors.accent-hover}— #d63d78): Darkened pink for hover/active states on the accent-colored search button.
Surface
- Canvas (
{colors.canvas}— #9e9ea7): Neutral medium-gray background behind the shot image frame, creating visual separation between the page chrome and the displayed artwork. - Surface (
{colors.surface}— #f3f3f4): Light gray used for the search input field background and subtle container fills. - Surface Soft (
{colors.surface-soft}— #ffffff): Pure white—primary canvas for navigation, shot header, FAQ items, and all content-bearing surfaces. - Surface Strong (
{colors.surface-strong}— #e7e7e9): Medium-light gray for dividers, rule lines, and subtle borders. - Surface Elevated (
{colors.surface-elevated}— #fdfdfd): Near-white for elements needing slight lift from pure white (cards, dropdowns). - Surface Dark (
{colors.surface-dark}— #05080a): Near-black for the shot image frame interior and any inverted-scheme containers.
Text & Ink
- Ink (
{colors.ink}— #0d0c22): Primary text color for headlines, navigation labels, button text, and all high-importance copy. - Body (
{colors.body}— #6e6d7a): Secondary text color for designer studio names, follow links, stat labels, and supporting metadata. - Muted (
{colors.muted}— #3d3d4e): Dark gray for tertiary text, ghost button labels, and subdued UI chrome. - Muted Soft (
{colors.muted-soft}— #9e9ea7): Light gray text for disabled states, placeholder text, and the announcement close button icon. - On Primary (
{colors.on-primary}— #ffffff): White text for legibility against{colors.primary}and{colors.accent}backgrounds. - On Dark (
{colors.on-dark}— #ffffff): White text for the dark announcement banner and any inverted-scheme surfaces. - On Surface (
{colors.on-surface}— #262627): Dark charcoal for subtle surface-level text elements.
Hairlines & Borders
- Hairline (
{colors.hairline}— #e7e7e9): Default border color for card outlines, input fields, and separator lines. - Hairline Soft (
{colors.hairline-soft}— #dbdbde): Lighter border for subtle dividers and inactive state indicators. - Border Strong (
{colors.border-strong}— #3a3546): Dark border for focused states and emphasized containment.
Semantic
- Success (
{colors.success}— #4daa57): Green used specifically for the "Available for work" status indicator next to designer names. - Link (
{colors.link}— #0d0c22): Inline link color matches primary ink—links are distinguished by underline or context, not hue. - Link Active (
{colors.link-active}— #060318): Darkened link state for visited or active inline links.
Typography
Font Family
The entire system runs on Mona Sans, a geometric humanist sans-serif designed by Dalton Maag. The font stack includes "Helvetica Neue", Helvetica, Arial, sans-serif as fallbacks. Mona Sans plays every role—from 12px micro-buttons to 32px shot-title displays—with no secondary typeface introduced. The face's slightly geometric terminals and open apertures contribute to the clean, modern voice without veering into coldness. No serif, monospace, or decorative faces appear in the interface.
Hierarchy
| Token | Size | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
| {typography.display-xl} | 32px | 700 | 1.2 | -0.02em | Hero-scale headlines (not present on this page but in system) |
| {typography.display-lg} | 24px | 600 | 1.21 | 0 | Shot title ("Solara. Solar Energy Website Design"), Dribbble logo |
| {typography.title-md} | 24px | 700 | 1.21 | 0 | Alternate heading weight for emphasis moments |
| {typography.title-sm} | 16px | 700 | 1.5 | 0 | Section headings within components (FAQ questions) |
| {typography.label-md} | 15px | 500 | 1.4 | 0 | Subheading labels (used in dark/inverted contexts per CSS) |
| {typography.body-md} | 16px | 450 | 1.75 | 0 | Designer name, description paragraphs, primary body copy |
| {typography.body-sm} | 14px | 400 | 1.5 | 0 | Navigation links, metadata text, secondary body |
| {typography.caption} | 13px | 400 | 1.38 | 0 | Stat badges, timestamps, tertiary info |
| {typography.button} | 14px | 500 | 1.25 | 0 | CTA button labels ("Get in touch", "Sign up", "Log in") |
| {typography.button-xs} | 12px | 500 | 1.25 | 0 | Micro-button text ("Get Started" in announcement) |
Principles
The typography system trusts weight contrast over size jumps for most hierarchy needs. Notice how display-lg and title-md share the same 24px size but diverge at weight 600 vs 700—a subtlety that keeps the shot title prominent without shouting. Body text sits at an unusually light 450 weight (not quite book, not quite medium) paired with an extremely generous 1.75 line-height, giving the designer's description paragraph an airy, editorial feel. Buttons step up to 500 weight for just enough presence without bolding.
Color also carries hierarchical signals: {colors.ink} for what you must read, {colors.body} for supporting context, {colors.muted} for chrome. The "Available for work" label breaks this with {colors.success} green—a deliberate semantic exception that draws the eye to hireability status.
No uppercase transforms appear anywhere in the interface. No negative letter-spacing beyond the theoretical display-xl. Italic is unused. The system achieves emphasis purely through size × weight × color multiplication.
Note on Font Substitutes
Mona Sans is not available on Google Fonts. For open-source reimplementation, substitute DM Sans (Google Fonts) as the nearest match—it shares similar geometric proportions, a humanist warmth, and excellent screen rendering. Define the substitution via CSS custom properties:
:root {
--font-sans: "DM Sans", "Mona Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
If Mona Sans is available via your build pipeline (self-hosted or CDN), retain it as the primary entry in the stack.
Layout
Spacing System
-
Base unit: 4px (implied by the 4/8/12/16/24/36/40 progression).
-
Tokens:
{spacing.xxs}(4px) — tight internal gaps, icon margins{spacing.xs}(8px) — compact component internals, small gaps between inline elements{spacing.sm}(12px) — form field gaps, list item spacing{spacing.md}(16px) — card padding baseline, grid gutters{spacing.lg}(24px) — section-internal padding, major block separation{spacing.xl}(36px) — dominant rhythm unit; vertical space above/below shot header{spacing.xxl}(40px) — larger section breaks{spacing.section}(64px) — major vertical band separation (nav-to-content)
-
Section padding (vertical):
{spacing.xl}(36px) — applied between the navigation bar bottom edge and the shot title. -
Card internal padding:
{spacing.md}(16px) to{spacing.lg}(24px) depending on card density; FAQ items use{spacing.md}horizontal with{spacing.md}vertical. -
Gutters: Content constrains to an implicit ~1240px max-width centered in viewport; left/right margins auto-balance.
Grid & Container
The shot page uses a single-column centered layout for the main content area. The shot container spans nearly full viewport width (with modest side margins), while the metadata header and action cluster sit in a narrower column (~900-1000px) aligned left. The navigation bar stretches full-width with internal content constrained to ~1240px. No multi-column grids appear on this page—the layout is intentionally linear: title → designer → shot → related content.
Whitespace Philosophy
Generous and editorial. The 36px ({spacing.xl}) gap between nav and title gives the shot room to breathe before the metadata cascade begins. Inside the designer info row, 16px ({spacing.md}) separates avatar from name, name from studio attribution. The shot image itself has zero internal padding—it bleeds to its container edges. This contrast (tight imagery, loose surroundings) focuses attention on the work product.
Header Architecture
|--------------------------------------------------------------------------------------------------|
| [Dribbble Logo] [Search Input........] [🔍] Shots ▾ Explore ▾ Hire Talent ▾ Get Hired ▾ Community ▾ Sign up [Log in] |
|==============================================================================================max:~1240px==|
Navigation is a single-row flex bar: logo left, search center-left (input + accent circle button), navigational dropdowns center-right, auth utilities far-right. Height: ~72px. Background: {colors.surface-soft}. Bottom border: 1px {colors.hairline}.
Hero / Shot Header Section
|-----------------------------------------------------------------------------------|
| |
| Solara. Solar Energy Website Design |
| |
| [Avatar] Permadi Satria Dewanto for Plainthing Studio · Available for work · Follow [♡] [🔖] [Get in touch] |
| |
|===================================================================================|
Shot title renders at {typography.display-lg} (24px/600). Designer row combines 48px circular avatar, name in {typography.body-md}, studio in {typography.body-sm} with {colors.body}, green availability badge, and "Follow" link. Action cluster floats right: heart icon button, bookmark icon button, filled primary CTA button.
Shot Display Area
|-----------------------------------------------------------------------------------|
| |
| +---------------------------------------------------------------------------+ |
| | | |
| | [Embedded Website Preview Image] | |
| | | |
| | | |
| +---------------------------------------------------------------------------+ |
| [💬][⬆][🕐]|
|-----------------------------------------------------------------------------------|
Shot container has {colors.canvas} background with {rounded.lg} corners. Inside, the shot image (the Solara website mockup) frames against {colors.primary} dark interior. Three floating action buttons dock to the right edge: comment count bubble, share/up arrow, clock/history icon. Each is a 48px {rounded.circle} button with {colors.surface-soft} background.
Announcement Banner (Overlay)
|===================================================================================|
| Get 20% (up to $100) off... WELCOME20 🎉 [Get Started] [×] |
|===================================================================================|
Full-viewport-width dark bar at top. Background {colors.primary}, text {colors.on-dark}. CTA button is {button-cta-white} style (pill, white bg, ink text). Close button is small circle in {colors.muted} with X icon.
FAQ / Accordion Section (Right Rail)
|---------------------------|
| How do portable panels... | -
| Are solar panels... | +
| Do solar panels cut... | +
| Installation time? | +
|---------------------------|
Accordion items sit in a narrow rail beside/within the shot area. Each item has {colors.surface-soft} background, {rounded.sm} corners, question text in {typography.title-sm} (16px/700). Expanded item reveals answer text below. Plus/minus icons indicate state.
Elevation & Depth
| Level | Treatment | Use |
|---|---|---|
| 0 — Flat | No shadow, {colors.surface-soft} background | Navigation bar, page base, FAQ collapsed items |
| 1 — Hairline outline | 1px {colors.hairline} border, no shadow | Search input, card boundaries, dividers |
| 2 — Soft drop | {extensions.shadows.sm} (0 2px 6px rgba(0,0,0,0.03)) | Elevated cards, dropdown menus |
| 3 — Raised | {extensions.shadows.md} (0 -6px 40px rgba(0,0,0,0.06)) | Announcement banner, modal-style overlays |
| 4 — Modal | {extensions.shadows lg} (inferred) | Shot overlay lightbox (not visible but implied) |
The depth philosophy is layered-minimal: shadows exist but are deliberately faint. The announcement banner uses the strongest shadow in the system ({extensions.shadows.md}) because it sits atop all content. Cards and inputs rely on 1px hairline borders rather than shadows for definition. The shot container itself casts no shadow—it sits flat against the {colors.canvas} background, letting the color contrast provide separation. Focus rings on interactive elements likely use {colors.border-strong} or a subtle outline treatment.
Shapes
Border Radius Scale
| Token | Value | Use |
|---|---|---|
| {rounded.sm} | 6px | Compact elements, FAQ items, small tags |
| {rounded.DEFAULT} | 8px | Standard cards, inputs, default containers |
| {rounded.md} | 8px | Alias for DEFAULT; general-purpose medium rounding |
| {rounded.lg} | 12px | Shot container, search input field, large cards |
| {rounded.xl} | 16px | Not actively used but available for large panels |
| {rounded.pill} | 9999px | All CTA buttons ("Log in", "Get in touch", "Get Started") |
| {rounded.circle} | 50% | Avatars, icon-only buttons, search submit, close buttons |
| {rounded.full} | 9999px | Alias for pill; fully rounded terminations |
The shape language is functionally categorical: anything clickable and text-bearing gets pill geometry; anything iconic gets circular geometry; anything containing content gets 8–12px squircle rounding. No asymmetric radii, no "blob" shapes, no decorative corner treatments.
Photography Geometry
The shot image itself (Solara website preview) displays as a rectangular frame with {rounded.lg} (12px) corners, contained within the shot container. No aspect-ratio constraints are forced—the image maintains its native proportions (appears ~16:10 landscape). The designer avatar is a perfect circle ({rounded.circle}, 48px diameter) with overflow hidden. Embedded imagery within the shot preview (photos of solar panel installations) shows natural rectangular cropping with no applied border-radius.
Components
No hover states documented. Hover behavior is unreliable to extract from a single screenshot. State variants live as separate entries in the
components:frontmatter (e.g.{component.button-primary-active},{component.text-input-focus}); add hover styling at implementation time per your stack's conventions.
Buttons
{component.button-primary} — Filled call-to-action button with {colors.primary} background and {colors.on-primary} white text. Uses {typography.button} (14px/500), {rounded.pill} geometry, and {padding: "10px 24px"}. Appears as the "Log in" button in navigation and "Get in touch" button in the shot header. Its active state is documented as {component.button-primary-active} with {colors.primary-active} background. Transition: likely {extensions.motion.easing} over {extensions.motion.duration} for background-color.
{component.button-secondary} — Icon-only circular button for secondary actions. Background {colors.canvas} (neutral gray), text/icon color {colors.muted-soft}, 40px diameter with {rounded.circle}. Used for the bookmark and heart outline actions in the shot header. Active variant {component.button-secondary-active} shifts background to {colors.hairline-soft} and text to {colors.ink}. These have no visible border—definition comes from background contrast.
{component.button-cta-white} — Inverted pill button for the announcement banner. White ({colors.surface-soft}) background, ink-colored text at {typography.button-xs} (12px/500), {rounded.pill} shape. Reads clearly against the dark announcement background. Padding: 8px 16px.
{component.nav-search-button} — The pink accent circle inside the search bar. Background {colors.accent} (#ea4889), white icon, 44px diameter matching the search input height, {rounded.circle}. This is the only surface in the entire system bearing the brand accent color. Its hover state would use {colors.accent-hover}.
{component.floating-action-btn} — Right-docked tool buttons (comment, share, timer). 48px {rounded.circle} with {colors.surface-soft} background and {colors.ink} icon/text. These float beside the shot container with subtle vertical stacking.
{component.announcement-banner-close} — Small circular dismiss button in the announcement bar. 28px diameter, {colors.muted} background, {colors.muted-soft} X icon, {rounded.circle}.
Cards & Containers
{component.shot-container} — The primary content housing for the displayed shot. Background {colors.canvas} (medium neutral gray), {rounded.lg} (12px) corners, no internal padding—the shot image bleeds edge-to-edge. This creates a "mat" effect that separates the artwork from the page chrome. Width spans most of viewport with auto margins.
{component.shot-image-frame} — The inner frame holding the actual shot image. Background {colors.primary} (near-black), {rounded.lg} corners matching parent, no padding. The Solara website preview image sits directly inside this dark frame, simulating a browser window or presentation mode.
{component.faq-item} — Collapsible accordion row for Q&A content. {colors.surface-soft} background, {colors.ink} text for the question, {rounded.sm} (6px) corners, padding {spacing.md} horizontally and vertically. Question text uses {typography.title-sm} (16px/700). The plus/minus toggle icon aligns right. Expanded variant {component.faq-item-expended} shares the same tokens but reveals answer content below with additional vertical padding.
{component.stat-badge} — Small inline tag showing metrics ("100+ country client", "$68k in revenue"). Pill-shaped ({rounded.pill}), {colors.surface-soft} background, {colors.body} text at {typography.caption} size, tight padding 4px 12px.
{component.top-nav} — Full-width navigation bar. {colors.surface-soft} background, 72px height, bottom border 1px {colors.hairline}. Contains logo, search composite, nav links, and auth utilities arranged in a flex row with space-between distribution.
Inputs & Forms
{component.nav-search-input} — The main search field in the navigation. {colors.surface} background (light gray), {colors.ink} text, {typography.body-sm} (14px), {rounded.lg} (12px) corners, 44px height, left-padding 24px for breathing room before placeholder text. The search button ({component.nav-search-button}) nests inside/at the right end of this input as a sibling, together forming a composite search control. Placeholder text: "What are you looking for?"
Navigation
{component.nav-logo} — Dribbble wordmark. Transparent background, {colors.ink} color, {typography.display-lg} weight (though scaled to fit nav height). Custom SVG mark + logotype.
{component.nav-link} — Top-level navigation menu items ("Shots", "Explore", "Hire Talent", etc.). Transparent background, {colors.ink} text at {typography.body-sm}, padding 8px 12px, each followed by a chevron-down indicator (implied dropdown). These are not buttons in the traditional sense—they're text triggers.
{component.nav-signup-link} — "Sign up" link in nav. Text-only, {typography.button} weight for slight prominence, transparent background, same padding convention as nav-links but visually distinct through weight alone.
Signature Components
{component.announcement-banner} — Promotional overlay bar at viewport top. Full-width, {colors.primary} dark background, {colors.on-dark} white text at {typography.body-md}. Contains promotional copy, a {component.button-cta-white} call-to-action, and a {component.announcement-banner-close} dismiss button. This component represents the highest-elevation element on the page, using both strong background contrast and {extensions.shadows.md} depth.
{component.designer-avatar} — Circular profile photograph. 48px diameter, {rounded.circle}, {colors.surface} fallback background, 2px implied border or shadow for lift from the white header surface. Clickable (links to profile).
{component.badge-available} — "Available for work" status label. Transparent background (inherits parent), {colors.success} green text, {typography.caption} size. Positioned inline after the designer's studio attribution. A critical semantic signal for hiring workflows.
{component.action-heart} — Like/favorite toggle. 44px square hit area, transparent background, {colors.ink} heart icon (outline state), {rounded.full} for potential pill-shaped active state. Sits in the action cluster beside bookmark.
{component.action-bookmark} — Save/bookmark toggle. Identical dimensions and treatment to {component.action-heart} but with bookmark icon. Both actions are non-destructive, lightweight engagements.
Do's and Don'ts
Do
- Do use
{colors.ink}(#0d0c22) for all primary text—it's the single source of truth for readability-critical copy. - Do reserve
{colors.accent}(#ea4889) exclusively for the search submit button and one other maximum-one-per-view activation point. - Do apply
{rounded.pill}to every button containing text—CTAs, auth buttons, micro-conversions all terminate in full rounding. - Do set body paragraph text at
{typography.body-md}(16px/450) with 1.75 line-height for optimal scannability. - Do use
{colors.surface}(#f3f3f4) as the input field background, never pure white—inputs need subtle differentiation from their container. - Do give icon-only buttons (heart, bookmark, close) a minimum 40–48px hit area with
{rounded.circle}geometry. - Do maintain 36px (
{spacing.xl}) vertical rhythm between major sections—this is the system's breathing room constant. - Do use
{colors.success}(#4daa57) only for availability/hireability status indicators—its semantic meaning is specific. - Do render the shot container with
{colors.canvas}background to create visual mat separation from the page. - Do keep FAQ/accordion items at
{rounded.sm}(6px) to differentiate them from primary cards ({rounded.DEFAULT}at 8px).
Don'ts
- Don't use
{colors.accent}for button backgrounds, links, or text highlights—it exists solely for the search trigger in this system. - Don't exceed 700 font weight anywhere in the interface—even display roles cap at semibold.
- Don't apply border-radius larger than
{rounded.lg}(12px) to content-containing cards—save bigger radii for pills and circles only. - Don't add gradient backdrops or textured backgrounds to hero areas; the canvas is
{colors.surface-soft}white throughout. - Don't use shadows stronger than
{extensions.shadows.md}for any element except true modals/overlays. - Don't mix font families—every text element from 12px micro-copy to 32px headlines uses Mona Sans exclusively.
- Don't apply letter-spacing tighter than 0 (normal) or wider than -0.02em (display-xl only); the system avoids tracking adjustments.
- Don't render primary CTA buttons in anything other than
{colors.primary}fill with{colors.on-primary}text—no outlines, no ghosts, no secondary styles for main conversion actions. - Don't place the announcement banner anywhere except the viewport top—it's an overlay, not an inline section.
- Don't use
{colors.muted-soft}(#9e9ea7) for body text—it fails contrast requirements; reserve it for placeholders and disabled states.
Motion & Animation
Transition Tokens
CSS transitions extracted from the live DOM reveal a nuanced motion system:
/* Color/property transitions — snappy for interactive feedback */
--transition-rapid: color 0.05s cubic-bezier(0.32, 0, 0.59, 0.03),
background-color 0.05s cubic-bezier(0.32, 0, 0.59, 0.03),
border 0.05s cubic-bezier(0.32, 0, 0.59, 0.03),
border-radius 0.05s cubic-bezier(0.32, 0, 0.59, 0.03),
padding 0.05s cubic-bezier(0.32, 0, 0.59, 0.03);
/* Background fade — moderate for state changes */
--transition-bg: background-color 0.25s ease-out;
/* Bouncy spring — playful for accent interactions */
--transition-spring: background-color 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
--transition-spring-all: 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
/* Smooth exit */
--transition-opacity: opacity 0.4s ease-in-out 0.1s;
/* Instant color shift */
--transition-instant: color 0.1s;
/* Exit/collapse transition */
--transition-collapse: 0.3s cubic-bezier(0.32, 0, 0.59, 0.03);
Keyframe Animations
skeleton-translate-d82d0ff5— Loading skeleton shimmer effect for content placeholders (horizontal sweep).skeleton-translate-24eaf5a2— Variant skeleton animation with alternate timing/offset.
These keyframes power loading states that appear when shot images or user data are fetching.
Interaction Patterns
- Search focus expansion: The search input likely expands or transitions its border/shadow on focus using
--transition-rapidtiming. - Button press scale: Accent and primary buttons may use
--transition-spring(the bouncy cubic-bezier) for a subtle press-down effect on mousedown/touchstart. - FAQ accordion slide: FAQ items expand/collapse with
--transition-collapse(300ms ease-out), revealing answer content vertically. - Announcement dismiss: The announcement banner fades out with
--transition-opacity(400ms with 100ms delay) when the close button is clicked. - Floating action tooltip: Right-docked floating buttons likely reveal tooltips or expand on hover with
--transition-bgtiming. - Heart toggle animation: The like button may animate between outline and filled states using
--transition-rapidfor color/property morphing. - Bookmark fill: Similar rapid transition for bookmark state changes.
- Nav dropdown reveal: "Shots", "Explore", etc. dropdown menus likely use
--transition-bgfor smooth background appearance on open.
The motion level is subtle ({extensions.motion.level})—nothing feels slow or heavy, and the bouncy spring curve on accent interactions adds a moment of delight without breaking professionalism.
Imagery Style
- The shot image itself is a website mockup/screenshot showing a solar energy landing page ("Solara") with photographic imagery of workers installing solar panels on rooftops.
- Photography within the shot is documentary/lifestyle: real workers in safety gear (hard hats, harnesses) performing installation tasks, shot from low angles to convey scale and effort.
- Color grading of embedded photography leans slightly cool/desaturated, harmonizing with the blue sky backgrounds and the technical nature of the subject matter.
- The mockup is presented as a browser-window frame simulation with a thin top chrome bar containing "Solara." branding and navigation links, grounding the design in realistic context.
- Hero imagery in the embedded shot features a worker mid-installation overlaid with large white headline text ("Innovative Solar Home Lightning Solution.")—text and photo blend with the photo providing atmospheric texture beneath semi-transparent dark overlay areas.
- Stat counters (50%, 12M+) appear as large white numerals floated over the lower-right portion of the hero image, creating data-within-context composition.
- Secondary imagery in the shot shows a second worker photo in an orange safety vest, suggesting a two-photo alternating layout pattern in the original Solara design.
- Image treatment in the Dribbble interface is presentation-neutral: no filters, no duotones, no artistic framing—the platform's job is to show the work as-is.
- Aspect ratio of the displayed shot is approximately 16:10 landscape, fitting common laptop/browser proportions for web design presentations.
- The shot image has no border-radius applied internally—rounding happens at the Dribbble container level (
{rounded.lg}), not on the artwork itself.
Icon System
- Library: Custom SVG icons (Dribbble's proprietary icon set). No third-party library detected.
- Specific icons observed:
- Search magnifying glass (inside the pink circle button)
- Chevron down (4× — for nav dropdown indicators: Shots, Explore, Hire Talent, Get Hired, Community)
- Heart outline (like/favorite action)
- Bookmark outline (save action)
- Comment/speech bubble (floating action with "51" count badge)
- Share/upload arrow (floating action)
- Clock/history (floating action)
- Close/X (announcement dismiss)
- Dribbble wordmark (custom SVG logo)
- Plus symbol (FAQ expanded-state indicator)
- Minus symbol (FAQ collapsed-state indicator)
- Treatment: All icons are stroke-based (outline style) rather than filled, maintaining a lightweight, modern aesthetic. Color is typically
currentColorinherited from the parent element'scolorproperty. The search icon inverts to white against the{colors.accent}background. - Size alignment: Icons scale to their container—16px inside 40px buttons, 20px inside 44px buttons, 24px for standalone decorative use. They center vertically and horizontally within their button bounds via flexbox.
- Stroke width: Appears consistent at approximately 1.5–2px, balancing visibility against delicacy.
Recommended Frontend Stack
- Framework: Next.js 14+ (React-based SSR/SSG; matches Dribbble's apparent stack)
- Styling: CSS Modules or Tailwind CSS (utility-first with design-token plugin)
- Fonts: Self-hosted Mona Sans via @font-face or CDN; fallback stack: "DM Sans", "Helvetica Neue", sans-serif
- Animation: CSS transitions (no JS animation library needed; extracted transitions are pure CSS)
- Icons: Custom SVG sprite or inline SVGs (matching Dribbble's proprietary set)
- Component lib: Radix UI primitives for accessible accordion/dropdown behaviors (FAQ, nav menus)
Responsive Behavior
Breakpoints
| Name | Width | Key Changes | |---|---|---| | Mobile | < 640px | Nav collapses to hamburger; shot image full-bleed; action buttons become bottom-bar; FAQ becomes full-width stacked | | Tablet | 640–1024px | Nav search may hide behind icon; shot container narrows; designer info wraps to two lines | | Desktop | 1024–1440px | Full layout as shown: nav expanded, shot centered with margins, FAQ in right rail | | Wide | > 1440px | Additional horizontal padding; shot container max-width constraint engages |
Touch Targets
{component.button-primary}: ~44px height × variable width (pill) — meets WCAG AAA{component.nav-search-button}: 44px × 44px circle — meets WCAG AAA{component.action-heart}/{component.action-bookmark}: 44px × 44px — meets WCAG AAA{component.floating-action-btn}: 48px × 48px circle — exceeds WCAG AAA{component.announcement-banner-close}: 28px × 28px — below 44px recommendation; should enlarge to 40px+ for mobile{component.nav-search-input}: 44px height — meets WCAG AAA
Collapsing Strategy
- Navigation bar: On mobile, the horizontal nav links (Shots, Explore, Hire Talent, etc.) collapse into a hamburger menu. The search input may reduce to a icon-only trigger that expands into an overlay. Logo remains left-aligned; Sign up/Log in move into the menu or shrink to icons.
- Shot container: Maintains full viewport width minus small margins on all breakpoints. Internal image scales proportionally (fluid width, auto height).
- Designer info header: Avatar stays 48px; name and studio wrap to multiple lines on narrow viewports; action cluster (heart, bookmark, Get in touch) stacks vertically or moves below the designer name.
- FAQ/accordion rail: On mobile, the FAQ detaches from beside the shot and stacks below it as a full-width accordion section. On tablet, it may sit below the shot in a narrower column.
- Floating action buttons: On mobile, these may move from right-docked position to a fixed bottom bar (like Instagram/TikKit style) to remain thumb-accessible.
- Announcement banner: Remains full-width on all breakpoints but text size may reduce slightly; CTA button maintains tap-friendly size.
Image Behavior
- Shot preview image: Uses
width: 100%; height: auto; object-fit: contain;to scale proportionally within the{component.shot-container}. No cropping—full image always visible. - Designer avatar: Fixed 48px × 48px circle regardless of viewport; image uses
object-fit: coverto fill the circle without distortion. - Embedded photography (within shot): Scales with the shot container; aspect ratio preserved. No art-direction or responsive image swapping detected.
Iteration Guide
- Build a shot-detail-page clone using Next.js with CSS Modules (or Tailwind mapped to these tokens). Start with the HTML structure: announcement banner (optional/conditionally rendered) → fixed/sticky nav → shot header → shot container → floating actions → FAQ sidebar → footer.
- Pull every color, font, radius, and spacing value from the YAML frontmatter via the
{section.token}paths. Define CSS custom properties for all tokens in:rootso your implementation referencesvar(--color-ink)rather than hard-coded hex values. - Add state variants (
-hover,-disabled,-focus) per your stack's conventions. The spec documents Default and Active/Pressed for buttons; implement hover as intermediate states using the transition timings from the Motion section. - When adding new components (e.g., comment section, related shots carousel), decide which sub-system they belong to: page-chrome (nav, announcement, footer), shot-context (header, actions, designer info), or shot-content (the displayed artwork area). Apply the appropriate surface and rounding tokens per zone.
- Variants of an existing component must live as separate frontmatter entries (
button-primary-active,faq-item-expanded)—never nest variants inside the default component definition. - Run
npx @google/design.md lint DESIGN.mdafter edits —broken-ref,contrast-ratio, andorphaned-tokenswarnings flag issues automatically. Pay special attention to the announcement close button's undersized 28px hit area (contrast warning likely). - When in doubt about emphasis: prefer larger type size over bolder weight (the system uses 450–700 range, never 800+); prefer
{colors.primary}filled buttons over outlined alternatives for primary CTAs; prefer{rounded.pill}for any button with text content. - Implement the search composite (input + circle button) as a wrapper
divwithdisplay: flex; align-items: stretch;so the input and button share height seamlessly. The button's{rounded.circle}will clip naturally against the input's{rounded.lg}ends. - Font setup: If you cannot license Mona Sans, substitute DM Sans from Google Fonts (
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;450;500;600;700&display=swap');). Map weights: 400→regular, 450→medium (simulate if unavailable via font-weight: 450), 500→medium, 600→semibold, 700→bold. - Test the FAQ accordion with real content—the
--transition-collapsetiming (300ms cubic-bezier(0.32, 0, 0.59, 0.03)) should produce a smooth height animation. Usegrid-template-rows: 0fr → 1frormax-heighttransitions for the expand/collapse behavior.
Known Gaps
- Hover state styling: Per the no-hover policy, exact hover background/color changes for buttons, links, and nav items were not extractable from a static screenshot. Implement using the active-state tokens as guidance plus conventional darken-by-~10% logic.
- Loading skeletons: While
skeleton-translatekeyframes were detected in CSS, the exact skeleton component markup (placeholder rectangles, shimmer animation application points) was not observable in the static DOM snapshot. - Form validation states: Error, warning, and success states for the search input (beyond the default and inferred focus state) are not documented. The
{colors.error}token is defined but unused in components. - Dropdown menu interiors: Navigation dropdowns (Shots ▾, Explore ▾, etc.) show chevron indicators but their opened-panel contents, item lists, and hover behaviors are invisible without interaction.
- Shot overlay/lightbox: The
shot-overlaydiv class exists in the DOM but its styled state (backdrop, close button positioning, image scaling, prev/next navigation) is not captured in the static screenshot. - Responsive breakpoint specifics: Exact pixel values where nav collapses, FAQ reflows, and action buttons relocate are inferred from typical patterns, not extracted from
@mediaqueries (none found in provided CSS). - Focus-visible rings: Interactive elements likely acquire focus rings on keyboard navigation, but the exact ring offset, color (
{colors.border-strong}?), and spread were not observable. - Dark mode tokens: The
modeextension is set to"light"based on canvas detection. A complete dark-mode token set (inverted surfaces, adjusted text colors) was not derivable from this single light-mode capture. - Typography
font-weight: 450: This unusual weight value requires a font file that supports it (Mona Sans does; many Google Fonts substitutes do not). Fallback rendering may snap to 400 or 500 depending on font-metric synthesis. - Announcement banner conditionality: The DOM shows the announcement present, but the logic controlling its visibility (cookie-based dismissal, A/B test targeting, geo-gating) is backend/template logic not exposed in CSS.