Skip to main content
vibld

Template

Quayline

A shared customer-support inbox where agents triage emails and chats. The conversation pane opens with an AI-generated one-line summary of the issue and auto-applied topic tags, so an agent understands the ticket before reading the full message.

Shared support inbox with AI conversation summary · App screen: inbox · Small tools and apps · full-stack app (auth + DB)

A mock-up of the screen, drawn from its layout, palette and typefaces. A build follows the full prompt below.

Start from this screenRead the build prompt

Typefaces

The catalog's own faces. A screen composed into a template is drawn in that template's typefaces.

  • InterHeadings: Inter 600, 18px conversation subject
  • InterBody: Inter 400 16px/1.5 in messages; 15px in the list

Patterns

  • three-pane inbox (nav, list, conversation)
  • status buckets with counts (open, later, done)
  • pinned tags and shared team inboxes in nav
  • filter chips over conversation list
  • unread dot and coloured tag pills in list rows
  • AI one-line summary under conversation header
  • metadata chip row (inbox, ticket id, participants, links)
  • far-right integrations rail
  • system event line in thread

States it is designed for

  • unread vs read rows
  • selected conversation
  • snoozed (clock icon and wake time)
  • summary generating (shimmer line)
  • summary unavailable (hidden, not an error)
  • empty bucket ('Nothing waiting -- nice.')
  • offline (composer disabled, banner)
  • long thread (collapsed earlier messages)
  • conflict: another agent replying (presence indicator)

Who it is for

  • support agents
  • support team leads
  • customer success managers

Layout

  1. left nav (~220px): inbox switcher, search, compose '+' button; status buckets Open/Later/Done/More with counts; Pinned (tags with counts); Views; Shared inboxes (coloured icons, counts); Assigned conversations
  2. middle list (~300px): bucket title, sort and filter icons, chips (All, Snoozed, Waiting); rows with unread dot, sender, subject or preview, tag pills, age, selected row outlined
  3. conversation pane: subject header with overflow, snooze, assignee button, status button; chip row (team inbox, ticket id, participants, links, counters, add); AI summary line with sparkle icon; message card (avatar, name, address, recipient, body, reply icon); event line 'topic identified, tag added'
  4. far-right rail (~44px): integration app icons
  5. mobile: one pane at a time with back navigation; summary stays pinned under header

Palette

Calm and efficient; soft lavender-grey chrome with purple as the single action colour.

  • app background#fcfcfe
  • nav / list surface#f4f3f8
  • selected row#e9e6f3
  • primary text#1b1b22
  • secondary text#5c5b68
  • compose / accent#6a4ae8
  • unread dot#6a4ae8
  • urgent tag fill#fdf1c7
  • urgent tag text#7a5200
  • vip tag fill#dcf5e3
  • vip tag text#1c6b37
  • card surface#ffffff

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text on card17.12:14.5:1
Aamuted text on pane6.04:14.5:1
Aatext on selected row13.92:14.5:1
Aaurgent tag6.12:14.5:1
Aavip tag5.68:14.5:1
Aacompose icon on accent5.59:14.5:1
unread dot on pane5.06:13:1
Aaaccent link on background5.45:14.5:1

As vibld’s tokens

The palette on the fifteen colour tokens vibld styles a project with, each text colour on the fill it is read on. Marked tokens are solved from the palette, because no swatch held that role at 4.5:1.

  • background
  • card
  • muted
  • primary
  • secondary
  • accent
  • destructive *

Type scale

Display
Inter 600, 18px conversation subject
Body
Inter 400 16px/1.5 in messages; 15px in the list

Nav 14px 500; counts tabular 13px muted; tags 12px 500; summary line 15px with sparkle icon.

Spacing and imagery

Dense: list rows ~72px with 12px padding; nav rows 30px; message card 16px padding, 8px radius, 1px border; chips 24px tall.

Round avatars for customers and agents; tiny coloured icons for inboxes; AI sparkle glyph; integration app icons in the rail (generic shapes in mocks).

Components

  • InboxNav (switcher, search, compose, buckets, pinned tags, views, shared inboxes)
  • ConversationList (FilterChips, ConversationRow with UnreadDot and TagPill)
  • ConversationHeader (subject, snooze, AssigneeButton, StatusButton)
  • MetaChipRow
  • AiSummaryLine
  • MessageCard
  • EventLine
  • Composer
  • IntegrationsRail

Interactions

  • J/K move through the list, Enter opens, E marks done, H snoozes
  • snooze opens presets (later today, tomorrow, next week, custom)
  • clicking a tag pill filters the list
  • summary line expands to a longer AI brief with 'regenerate' and 'mark wrong'
  • assignee button opens a searchable teammate menu
  • reply icon opens the composer inline below the message

Data

  • Conversation{id, inbox_id, subject, status (open|later|done), snoozed_until, assignee_id, priority, ticket_ref, last_message_at}
  • Message{id, conversation_id, author_type (customer|agent|system), author_id, body_html, sent_at}
  • Tag{id, name, color}
  • ConversationTag{conversation_id, tag_id, source (agent|ai)}
  • AiSummary{conversation_id, one_liner, brief, model_version, created_at, flagged_wrong bool}
  • Inbox{id, team_id, name, color}

Guardrails

Experience

  • Keep the AI summary to one line under the header, clearly marked as generated, with a way to flag it wrong.
  • Show who applied a tag (AI or person) in its tooltip.
  • Keep bucket counts live and accurate; never show stale counts after an action.
  • Support full keyboard triage with discoverable shortcuts.
  • Distinguish unread with both a dot and bolder sender name.

Accessibility

  • Three panes are landmarks (nav, list region, main) with skip links.
  • The list is a listbox or grid with aria-selected and roving focus; unread is announced.
  • Tag pills have text; colour is secondary.
  • AI summary is marked 'Generated summary' for screen readers.
  • Shortcuts can be disabled and are listed in a help dialog.

Security

  • RLS: conversations, messages and tags visible only to members of the owning team inbox.
  • Sanitise inbound HTML emails (allowlist tags, strip scripts, proxy remote images).
  • Send only the necessary message text to the summarisation service; redact card numbers and secrets first.
  • Audit assignment and status changes; rate-limit outbound replies.

Build prompt

The baseline every prompt in the catalog assumes, then this design’s own ten sections, from goal to guardrails.

The baseline
### How to use these prompts
Paste an entry's build prompt into your coding agent as the first message. Each prompt names its own stack, tokens and acceptance criteria; the rules below apply to all of them and can be prepended once per project.

### Engineering baseline
- TypeScript strict mode, no `any`, small typed components, feature folders, and one source of truth for design tokens (CSS variables consumed by Tailwind).
- Validate every input with a shared zod schema on the client and again on the server or edge function. Never trust client-side checks alone.
- Show loading, empty and error states for every async view. Surface errors in plain language with a retry, and log details to the console in development only.
- Keep secrets out of the bundle. Only publishable keys (for example a Supabase anon key) belong in client code; service-role keys, API keys and webhooks live in server or edge-function environment variables.

### Data and auth baseline (full-stack entries)
- Enable Row Level Security on every table before inserting data. Default-deny, then add owner-scoped policies (`auth.uid() = user_id`) and explicit role checks for admin views.
- Store roles in a separate table checked by a security-definer function, never in a user-editable profile field.
- Upload files to private storage buckets with size and MIME limits, and serve them through signed URLs.
- Rate-limit public endpoints (forms, auth, AI calls) and add a honeypot field or captcha to anonymous forms.
- Take payments through a hosted checkout and verify webhooks by signature. Never handle raw card data.

### Accessibility and UX baseline
- Target WCAG 2.2 AA: 4.5:1 contrast for normal text and 3:1 for large text, input borders, focus rings and meaningful icons or chart lines. Every palette in this catalog lists its verified pairs; re-check with a contrast tool after any colour change.
- Keep body text at 16px or larger with 1.5 line height, nothing below 12px, no light weights under 24px, and uppercase only for short labels.
- Give every interactive element a visible focus ring, full keyboard support, semantic landmarks, labelled form fields, and alt text on meaningful images.
- Respect `prefers-reduced-motion` for every animation. Give drag-and-drop and carousels keyboard and button alternatives.
- Build mobile-first and test at 375px, 768px and 1280px.

### Content guardrails
- Use original copy, fictional sample data and placeholder or licensed imagery. Do not reuse another product's name, logo, screenshots or marketing text.
- Label demo testimonials and metrics as samples. Collect the minimum personal data the feature needs.

### SaaS screen baseline
- Design every screen for its full set of states: first-run empty, loading skeleton, partial data, error with retry, permission-denied, and success feedback. Each entry lists the states its screen needs.
- Keep destructive actions (delete, revoke, downgrade, remove member) behind a confirmation that names the object, and prefer undo over a second dialog where the action is reversible.
- Enforce authorisation on the server for every action a screen exposes. Hiding a button is not access control; check the role again in the API or RLS policy.
- Never show secrets (API keys, tokens) in full after creation. Show them once, then mask them, and offer rotate and revoke.
- Keep the app shell (navigation, workspace switcher, account menu) consistent across screens, and preserve filters, sort and scroll position when the user navigates back.
### Goal
Build **Quayline**, a shared support inbox with three panes and an AI one-line issue summary. Agents triage by status buckets, filter by tags, open a conversation and immediately see what the customer wants, then reply, snooze, assign or close.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Command, Popover, DropdownMenu, Tooltip, ScrollArea), lucide-react, TanStack Query, Tiptap for the composer, date-fns for snooze. Supabase Auth, Postgres, a realtime presence service for 'agent is replying', and an Edge Function that calls a hosted language-model API for summaries.

### Pages & layout
1. **/inbox/:bucket/:conversationId?**: nav, list, conversation, rail.
2. **Snooze popover**, **assignee menu**, **shortcut help dialog**.
3. Responsive: two panes at <1280px (nav collapses to icons), one pane with back button at <768px.

### Design system
- Colors: `--bg: #fcfcfe` (app background), `--pane: #f4f3f8` (nav / list surface), `--selected: #e9e6f3` (selected row), `--fg: #1b1b22` (primary text), `--muted: #5c5b68` (secondary text), `--accent: #6a4ae8` (compose / accent), `--dot: #6a4ae8` (unread dot), `--urgent-bg: #fdf1c7` (urgent tag fill), `--urgent-fg: #7a5200` (urgent tag text), `--vip-bg: #dcf5e3` (vip tag fill), `--vip-fg: #1c6b37` (vip tag text), `--card: #ffffff` (card surface).
- Fonts: Inter 600, 18px conversation subject for headings; Inter 400 16px/1.5 in messages; 15px in the list for body. Nav 14px 500; counts tabular 13px muted; tags 12px 500; summary line 15px with sparkle icon.
- Spacing: Dense: list rows ~72px with 12px padding; nav rows 30px; message card 16px padding, 8px radius, 1px border; chips 24px tall.
- Radius: 8px cards and selected rows, 6px chips, full pills for tags.
- Shadows: none except popovers.
- Motion: 120ms row hover; list item removal slides out 150ms after Done; summary shimmer while generating.

### Components & interactions
InboxNav, BucketItem, PinnedTagItem, SharedInboxItem, ConversationList, FilterChips, ConversationRow, UnreadDot, TagPill, ConversationHeader, SnoozePopover, AssigneeMenu, StatusButton, MetaChipRow, AiSummaryLine, MessageCard, EventLine, Composer, IntegrationsRail, ShortcutHelp.

Interactions: J/K move through the list, Enter opens, E marks done, H snoozes; snooze opens presets (later today, tomorrow, next week, custom); clicking a tag pill filters the list; summary line expands to a longer AI brief with 'regenerate' and 'mark wrong'; assignee button opens a searchable teammate menu; reply icon opens the composer inline below the message.

States to build: unread vs read rows; selected conversation; snoozed (clock icon and wake time); summary generating (shimmer line); summary unavailable (hidden, not an error); empty bucket ('Nothing waiting -- nice.'); offline (composer disabled, banner); long thread (collapsed earlier messages); conflict: another agent replying (presence indicator).

### Data & state
Lists are cursor-paginated per bucket and filter; counts come from a view. Summaries are generated on first open and cached per conversation; 'regenerate' replaces it. Seed 40 invented conversations across three shared inboxes with tags (urgent, vip, billing) and one long hardware-fault email.

Model: `Conversation{id, inbox_id, subject, status (open|later|done), snoozed_until, assignee_id, priority, ticket_ref, last_message_at}`; `Message{id, conversation_id, author_type (customer|agent|system), author_id, body_html, sent_at}`; `Tag{id, name, color}`; `ConversationTag{conversation_id, tag_id, source (agent|ai)}`; `AiSummary{conversation_id, one_liner, brief, model_version, created_at, flagged_wrong bool}`; `Inbox{id, team_id, name, color}`.

### Accessibility
Three panes are landmarks (nav, list region, main) with skip links. The list is a listbox or grid with aria-selected and roving focus; unread is announced. Tag pills have text; colour is secondary. AI summary is marked 'Generated summary' for screen readers. Shortcuts can be disabled and are listed in a help dialog.
Verified contrast: body text on card: #1b1b22 on #ffffff = 17.12:1; muted text on pane: #5c5b68 on #f4f3f8 = 6.04:1; text on selected row: #1b1b22 on #e9e6f3 = 13.92:1; urgent tag: #7a5200 on #fdf1c7 = 6.12:1; vip tag: #1c6b37 on #dcf5e3 = 5.68:1; compose icon on accent: #ffffff on #6a4ae8 = 5.59:1; unread dot on pane: #6a4ae8 on #f4f3f8 = 5.06:1; accent link on background: #6a4ae8 on #fcfcfe = 5.45:1.

### Security
RLS: conversations, messages and tags visible only to members of the owning team inbox. Sanitise inbound HTML emails (allowlist tags, strip scripts, proxy remote images). Send only the necessary message text to the summarisation service; redact card numbers and secrets first. Audit assignment and status changes; rate-limit outbound replies. RLS per table: `inboxes` select for team members; `conversations`, `messages`, `conversation_tags` select/update for members of the conversation's team; `ai_summaries` select for the same, insert/update only by the Edge Function; `tags` managed by team admins.

### Performance & SEO
Virtualise the list; prefetch the next conversation on J/K; lazy-load Tiptap on first reply. App routes noindex.

### Guardrails
- Keep the AI summary to one line under the header, clearly marked as generated, with a way to flag it wrong.
- Show who applied a tag (AI or person) in its tooltip.
- Keep bucket counts live and accurate; never show stale counts after an action.
- Support full keyboard triage with discoverable shortcuts.
- Distinguish unread with both a dot and bolder sender name.
- Write all copy fresh; use invented people, companies and numbers only. No real brands, logos, wordmarks or third-party product names anywhere in the UI or seed data.
- Do not trace or copy any existing product's layout assets, icons or illustrations; draw generic ones.
- Acceptance criteria:
  - [ ] Buckets, chips and tags filter the list with live counts
  - [ ] Opening a conversation shows the AI summary line or a shimmer
  - [ ] Snooze, assign and done update the list immediately
  - [ ] Inbound HTML is sanitised
  - [ ] Full triage is possible with keyboard only

Open the builderAll templatesThis palette on its own