Mael — Email Dashboard
Nuxt 3 email dashboard inspired by Dribbble design — layout, threading, and responsive navigation
Pet project — built to explore Nuxt 3 + design translation
A clean, modern email dashboard that translates a Dribbble design concept into a functional layout — with inbox management, email threading, and responsive sidebar navigation.
Motivation
I built this to practice translating high-fidelity design mockups into working code — a skill that turns out to be very different from designing a UI from scratch. The Dribbble design featured deliberate spacing, specific typography choices, and interaction patterns that go beyond what standard component libraries provide. The challenge was getting the details right: padding that matches the mockup pixel-for-pixel, color values that feel the same in code as they do in the design tool, and hover transitions that replicate the intended micro-interactions.
The Design Translation Process
Translating a static design mockup into a working application involves more than copying hex codes and font sizes. The real work is in the in-between states that the mockup doesn't show — what happens when the sidebar collapses on a tablet, how the email list scrolls when there are a hundred threads, how the panes resize when the user adjusts the browser width.
I approached this by identifying the design's key layout primitives first: the fixed sidebar, the scrollable email list, and the detail panel. Each of these became an independent component with its own responsive behavior. The sidebar collapses first at the tablet breakpoint, then the email list stacks below the detail view on mobile. This systematic approach to responsive design meant each component only needed to know about its own breakpoint behavior, not the entire page layout.
Inbox and Threading
The inbox view presents a scrollable list of email threads grouped by subject line. Each thread shows the most recent sender's avatar, the subject, a preview snippet, and the timestamp. Clicking a thread opens the full conversation in the detail panel, where individual messages are displayed in chronological order with sender avatars and timestamps.
The threading logic turned out to be the most interesting part. Grouping emails by subject required a pass through the inbox data to build thread objects, then sorting those threads by the most recent message timestamp. This is straightforward in principle, but the edge cases — a reply with a modified subject line, a thread with participants added mid-conversation — required careful handling.
Responsive Layout System
The responsive design follows a three-tier system rather than the usual cascade of ad-hoc breakpoint overrides. At the widest tier, all three panes are visible: sidebar on the left, email list in the center, detail panel on the right. At the tablet tier, the sidebar collapses to icons-only, reclaiming horizontal space for the email list and detail panel. At the mobile tier, the inbox and detail views stack vertically, with a hamburger menu replacing the sidebar entirely.
The key insight was that each tier is a fundamentally different layout, not a scaled version of the same layout. On mobile, the navigation pattern changes from persistent sidebar to dismissible overlay — a UX decision, not a CSS one. This meant the component structure needed to support both patterns, not just hide and show elements.
Nuxt 3 impressions
Nuxt 3's auto-imports reduce boilerplate significantly — no manual component imports in templates. The file-based routing makes page organization intuitive, and the built-in TypeScript support works seamlessly with Vue 3's Composition API.
What I Learned
Design fidelity is mostly typography and spacing. Getting the line-height, letter-spacing, and margins to match the mockup made a bigger visual impact than any animation or gradient. I spent more time tweaking leading-relaxed and tracking-tight than on any other single detail — and it was time well spent.
Complex layouts need a systematic approach to responsive design rather than adjusting each element individually at each breakpoint. Defining clear tiers (desktop → tablet → mobile) and designing each tier as a distinct layout made the CSS much more maintainable. Each component knows its own breakpoint behavior, and the page layout emerges from the composition of those behaviors.
Nuxt's auto-imports are genuinely useful for keeping the codebase clean. Not having to manually register every component in a global registry or import them in every parent file is one of those quality-of-life improvements that you notice most when you go back to a project without it.
Not production-ready
This is a UI-only project — no backend integration, no real email fetching. The focus was entirely on layout fidelity, responsive design, and component composition in Nuxt 3.
Built to explore Nuxt 3 and design-to-code translation. View source