Skip to main content
vibld

Template

Ruskel

After an admin authorises a new data source in an AI workspace, a side sheet confirms the sync has started, explains where the synced data will appear and how to share it (company-wide or restricted spaces), and offers a short explainer video. It turns a long background job into a moment of orientation.

Data-sync-in-progress side sheet with explainer video · App screen: integrations · 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, 20px sheet title
  • InterBody: Inter 400, 16px, line-height 1.55

Patterns

  • right side sheet over dimmed app
  • sparkle icon plus status title
  • highlighted callout box with bullet list
  • embedded explainer video with captions
  • single acknowledge button bottom-right
  • admin sidebar with grouped spaces
  • trial usage meter in sidebar footer

States it is designed for

  • syncing: badge with spinner and item count
  • sync finished: success toast and badge becomes 'Synced'
  • sync failed: row shows error text and Retry; sheet copy switches to error variant
  • partial sync: count of skipped items with a details link
  • video failed to load: poster with 'Watch on docs page' link
  • empty spaces list: 'New' prompt in the sidebar section

Who it is for

  • workspace admins of an AI assistant platform
  • IT or ops leads connecting company data

Layout

  1. top of sidebar: three tabs (Chat, Spaces, Admin) with icons
  2. sidebar sections: Administration (Connections, Tools, Triggers), Open spaces with New action, Restricted spaces with New action; footer with trial message meter and workspace switcher and Help
  3. main (dimmed under scrim): Connections admin page with description and a table of sources (name, used by)
  4. right side sheet (~40% width, min 420px): icon, title, yellow callout, video player, documentation line, 'OK' button bottom-right
  5. below 768px the sheet becomes a full-screen bottom sheet and the video spans full width

Palette

Reassuring and instructional; a warm yellow callout says 'this is normal, here is what happens next'.

  • bg#ffffff
  • canvas#f6f7f9
  • scrim#5b6475
  • text#161b26
  • muted#5e6675
  • callout#fff6c7
  • callout-text#5c4a00
  • link#1a73d9
  • button#1e2533
  • meter#2e7df6

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text17.23:14.5:1
Aamuted text on sidebar5.39:14.5:1
Aacallout text7.91:14.5:1
Aalink text4.67:14.5:1
AaOK button label15.35:14.5:1
usage meter fill vs track3.15:13:1
focus ring4.67:13: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, 20px sheet title
Body
Inter 400, 16px, line-height 1.55

Sidebar group labels 13px 600 in muted text; bold spans inside the callout highlight the two access options.

Spacing and imagery

Density: Medium density. Grid: 8px base; sheet padding 24px; 16px between blocks. Container: sheet width 40vw clamped 420-560px. Radius: 10px callout and video, 8px buttons. Shadows: Sheet casts a large left shadow 0 0 40px rgba(0,0,0,0.18).

A small sparkle glyph as the sheet icon; a 16:9 explainer video poster showing a generic UI tree; no stock photos.

Components

  • AppSidebar with tabs and grouped sections
  • UsageMeter
  • ConnectionsTable
  • SideSheet
  • Callout
  • VideoPlayer with captions toggle
  • SyncStatusBadge
  • Toast

Interactions

  • Sheet opens automatically after OAuth success and can be closed with OK, Esc or clicking the scrim
  • Video has play, captions, volume, settings and fullscreen controls; captions default on when OS prefers them
  • Documentation link opens in a new tab with an external-link icon
  • The source row in the table shows a 'Syncing' badge with progress that updates via polling every 10s
  • When sync finishes a toast offers 'Add to a space'

Data

  • DataSource{id, workspace_id, provider (files|docs|chat|warehouse), status (syncing|synced|failed|paused), items_synced, items_total, last_synced_at}
  • Space{id, workspace_id, name, visibility (open|restricted)}
  • SpaceSource{space_id, source_id}
  • SyncJob{id, source_id, started_at, finished_at, error}

Guardrails

Experience

  • Tell users sync runs in the background and they can close the sheet
  • State exactly where the data will appear and the two ways to share it
  • Never autoplay the video
  • Keep one primary action (OK) in the sheet
  • Show sync progress on the table row after the sheet closes

Accessibility

  • Side sheet is a Radix Dialog with aria-labelledby on the title; focus starts on the title
  • Video has captions and a transcript link
  • Progress uses role=progressbar with aria-valuenow and text count
  • Bold text in the callout is not the only signal; each option is a list item
  • Scrim click-to-close is mirrored by Esc and the OK button

Security

  • Only workspace admins can create data sources (RLS on data_sources: insert/update for admin role)
  • OAuth tokens for sources are stored encrypted server-side and never sent to the client
  • Synced items inherit space visibility; restricted spaces check membership in RLS
  • Audit-log each source connection and each space assignment

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 **Ruskel**, the moment right after an admin connects a company data source to an AI workspace. A side sheet explains that syncing has started, where the data will land and how to share it, with a short captioned video. Build the admin connections page behind a scrim, the sidebar shell and the sheet, with mock sync progress.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui on Radix primitives and lucide-react icons. TanStack Query for server state, react-hook-form + zod for every form, date-fns for relative times. Supabase for Auth, Postgres with row-level security and Edge Functions for anything that needs a secret. Run syncs in a background worker; the client polls or subscribes through a realtime channel.

### Pages & layout
1. **Sidebar**: tabs Chat / Spaces / Admin; Administration group; Open spaces and Restricted spaces groups each with a '+ New' action; footer with a trial usage meter (e.g. 3 of 100 messages) and a workspace switcher.
2. **Connections admin page**: title with icon, two-line description with a help link, table with Name (sortable) and Used by columns.
3. **Sync side sheet**: sparkle icon, title 'Syncing your data…', yellow callout with a sentence and two bullets (open space vs restricted space), 16:9 video with controls, 'See the docs' line, OK button bottom-right.
Responsive: sheet becomes full-screen below 768px.

### Design system
- Colors: `--bg: #ffffff` (sheet surface), `--canvas: #f6f7f9` (sidebar and page), `--scrim: #5b6475` (overlay at 55% opacity), `--text: #161b26` (primary text), `--muted: #5e6675` (secondary text), `--callout: #fff6c7` (callout fill), `--callout-text: #5c4a00` (callout body), `--link: #1a73d9` (links), `--button: #1e2533` (OK button fill), `--meter: #2e7df6` (usage meter fill).
- Fonts: Inter 600, 20px sheet title for headings; Inter 400, 16px, line-height 1.55 for body. Sidebar group labels 13px 600 in muted text; bold spans inside the callout highlight the two access options.
- Spacing: Medium density. 8px base; sheet padding 24px; 16px between blocks. Container: sheet width 40vw clamped 420-560px.
- Radius: 10px callout and video, 8px buttons.
- Shadows: Sheet casts a large left shadow 0 0 40px rgba(0,0,0,0.18).
- Motion: Sheet slides in from the right over 220ms ease-out with scrim fade; video never autoplays; reduced motion swaps slide for fade.

### Components & interactions
The Callout is a rounded yellow box with dark olive text, a lead sentence and a two-item list whose key words are bold. The VideoPlayer is a rounded card with a centred play button and a control bar; add a captions toggle.

- Sheet opens automatically after OAuth success and can be closed with OK, Esc or clicking the scrim
- Video has play, captions, volume, settings and fullscreen controls; captions default on when OS prefers them
- Documentation link opens in a new tab with an external-link icon
- The source row in the table shows a 'Syncing' badge with progress that updates via polling every 10s
- When sync finishes a toast offers 'Add to a space'

### Data & state
Mock one source moving from 0 to 1,240 items over 60 seconds using a fake timer, then flip to synced. Server state via TanStack Query with a 10s refetch interval while status is syncing; stop polling when done.

Entities: `DataSource{id, workspace_id, provider (files|docs|chat|warehouse), status (syncing|synced|failed|paused), items_synced, items_total, last_synced_at}`; `Space{id, workspace_id, name, visibility (open|restricted)}`; `SpaceSource{space_id, source_id}`; `SyncJob{id, source_id, started_at, finished_at, error}`.

States to build and show in a dev-only state switcher:
- syncing: badge with spinner and item count
- sync finished: success toast and badge becomes 'Synced'
- sync failed: row shows error text and Retry; sheet copy switches to error variant
- partial sync: count of skipped items with a details link
- video failed to load: poster with 'Watch on docs page' link
- empty spaces list: 'New' prompt in the sidebar section

### Accessibility
- Side sheet is a Radix Dialog with aria-labelledby on the title; focus starts on the title
- Video has captions and a transcript link
- Progress uses role=progressbar with aria-valuenow and text count
- Bold text in the callout is not the only signal; each option is a list item
- Scrim click-to-close is mirrored by Esc and the OK button
Verified contrast: body text: #161b26 on #ffffff = 17.23:1; muted text on sidebar: #5e6675 on #f6f7f9 = 5.39:1; callout text: #5c4a00 on #fff6c7 = 7.91:1; link text: #1a73d9 on #ffffff = 4.67:1; OK button label: #ffffff on #1e2533 = 15.35:1; usage meter fill vs track: #2e7df6 on #e3e7ee = 3.15:1; focus ring: #1a73d9 on #ffffff = 4.67:1.

### Security
- Only workspace admins can create data sources (RLS on data_sources: insert/update for admin role)
- OAuth tokens for sources are stored encrypted server-side and never sent to the client
- Synced items inherit space visibility; restricted spaces check membership in RLS
- Audit-log each source connection and each space assignment
RLS detail: `data_sources` select for workspace members, write for admins; `spaces` select for members of open spaces or members listed in `space_members` for restricted ones; `sync_jobs` insert only by the service role.

### Performance & SEO
Load the video lazily (poster first, player on click). Keep the sheet in a separate chunk. Private admin route: noindex.

### Guardrails
- Tell users sync runs in the background and they can close the sheet
- State exactly where the data will appear and the two ways to share it
- Never autoplay the video
- Keep one primary action (OK) in the sheet
- Show sync progress on the table row after the sheet closes
- Write fresh, generic copy and invented sample data; no real brands, logos, product names or people.
- Keep components small and typed (no `any`); surface every error visibly with a way to recover.

Acceptance criteria:
- Sheet appears after connecting and closes via OK, Esc and scrim
- Row badge progresses and flips to Synced with a toast
- Failure shows Retry on the row
- Video never autoplays and has captions
- Non-admins cannot open the connections page

Open the builderAll templatesThis palette on its own