Skip to main content
vibld

Template

Plotwick

An export dialog in a collaborative mapping tool. Users choose a layout, toggle view, legend, scale, branding and output options, and see a live print-style preview of the map with title, legend, projection, scale bar and locator inset before exporting as an image or PDF.

Map export modal with live print-layout preview · App screen: import export · Small tools and apps · front-end app (local state)

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 modal title; 18px map title in preview
  • InterBody: Inter 400 16px/1.5 in settings

Patterns

  • large modal over dimmed app
  • left settings column with accordion options
  • live WYSIWYG preview pane
  • print layout with title, legend, scale bar, north arrow and inset map
  • layout preset select
  • cancel / primary export pair

States it is designed for

  • default preview
  • rendering preview (spinner overlay on map frame)
  • exporting (progress toast)
  • export failed (retry)
  • legend empty (no visible layers → message)
  • logo upload invalid type
  • very long title (wraps to two lines, then truncates with tooltip)

Who it is for

  • urban planners
  • GIS analysts
  • environmental consultants

Layout

  1. dimmed app behind (scrim)
  2. modal (~90vw × 90vh, max 1200px): left column (~300px) and right preview pane
  3. left: title, description, Layout select, 'Options' header strip, accordion rows (View, Legend, Scale, Branding, Export), bottom Cancel (outlined) and Export (blue) buttons
  4. right: small 'Preview' label, framed page with title bar, map area, right legend column (swatches + labels), projection text, scale bar, north arrow, inset locator map
  5. mobile: modal becomes full screen with Options above a collapsible preview

Palette

Precise and cartographic; neutral chrome lets the map colours lead.

  • modal surface#ffffff
  • preview pane#f1f3f5
  • primary text#1a1d21
  • secondary text#5a6270
  • primary button#1463ff
  • options strip#eef0f3
  • input border#8a919c
  • overlay: high class#d9546a
  • overlay: mid class#e5c193
  • scrim#0f1115
  • page frame#1a1d21

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text16.91:14.5:1
Aamuted text6.15:14.5:1
Aaexport button label4.93:14.5:1
Aaoptions label on strip5.38:14.5:1
input border3.18:13:1
focus ring4.93:13:1
page frame on pane15.20: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 modal title; 18px map title in preview
Body
Inter 400 16px/1.5 in settings

Preview legend text 12px (minimum) scaled with the page; 'Preview' and 'Options' labels 12px uppercase 600 with 0.08em tracking.

Spacing and imagery

Modal radius 12px, padding 24px; accordion rows 44px with 1px dividers; preview page has 1.5px frame and 12px inner padding; legend column 180px.

Satellite-style basemap with semi-transparent thematic overlay classes; small north arrow glyph; inset locator map with a highlighted extent box. Use generic or self-generated basemap tiles.

Components

  • ExportModal
  • LayoutSelect (standard, landscape, portrait, poster)
  • OptionsAccordion (View, Legend, Scale, Branding, Export)
  • PreviewPane
  • PrintPage (TitleBar, MapFrame, LegendPanel, ProjectionNote, ScaleBar, NorthArrow, InsetMap)
  • ExportFormatSelect (PNG, PDF, SVG) + DPI
  • ProgressToast

Interactions

  • every option updates the preview within 200ms
  • clicking the preview title edits it inline
  • Legend accordion toggles layers and reorders legend items
  • Branding adds a logo upload and footer text
  • Export renders server-side or in a worker and downloads; Cancel or Escape closes
  • preview zoom-to-fit and 100% toggle

Data

  • ExportSettings{layout (standard|landscape|portrait|poster), title, show_legend, legend_order string[], show_scale, units (metric|imperial), show_north, show_inset, branding {logo_url, footer}, format (png|pdf|svg), dpi (150|300)}
  • MapLayer{id, name, visible, style {fill, opacity}, classes {label, color}[]}

Guardrails

Experience

  • Make the preview a faithful WYSIWYG of the exported file (same fonts, proportions).
  • Keep the options collapsed by default with sensible defaults so one click exports.
  • Place Export bottom-left under the options where the eye finishes, with Cancel beside it.
  • Scale legend text with the page but never below 12px at 100%.
  • Remember the last used settings per map.

Accessibility

  • Modal is a dialog with labelled title and description, focus trapped, Escape closes.
  • Accordion uses buttons with aria-expanded and controls.
  • Legend swatches are paired with text labels; map classes are distinguishable by pattern option for colour-blind users.
  • Preview has a text summary (title, layers, scale) for screen readers.
  • Scrim behind the modal is 60% dark; modal content is on solid white.

Security

  • Validate uploaded logo (PNG/SVG under 500 kB); sanitise SVG before rendering.
  • Escape user-entered title and footer text.
  • Generate exports client-side or via a signed request; never expose tile provider keys in exported metadata.

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 **Plotwick**, the map export dialog of a web mapping tool. The dialog pairs a compact options column with a live print-layout preview (title, map, legend, projection, scale bar, north arrow, inset) and exports PNG, PDF or SVG entirely in the browser.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Dialog, Accordion, Select, Switch, Input), lucide-react, react-hook-form + zod for settings, Motion for the modal. Use an open-source web map renderer with an open basemap style, and a client-side PDF/canvas export utility.

### Pages & layout
1. **Map view** (mock) with a Share/Export button that opens the modal.
2. **Export modal**: options column + preview pane.
3. Mobile: full-screen sheet, options first, preview collapsible.

### Design system
- Colors: `--surface: #ffffff` (modal surface), `--pane: #f1f3f5` (preview pane), `--fg: #1a1d21` (primary text), `--muted: #5a6270` (secondary text), `--primary: #1463ff` (primary button), `--strip: #eef0f3` (options strip), `--input-border: #8a919c` (input border), `--map-high: #d9546a` (overlay: high class), `--map-mid: #e5c193` (overlay: mid class), `--scrim: #0f1115` (scrim), `--frame: #1a1d21` (page frame).
- Fonts: Inter 600, 20px modal title; 18px map title in preview for headings; Inter 400 16px/1.5 in settings for body. Preview legend text 12px (minimum) scaled with the page; 'Preview' and 'Options' labels 12px uppercase 600 with 0.08em tracking.
- Spacing: Modal radius 12px, padding 24px; accordion rows 44px with 1px dividers; preview page has 1.5px frame and 12px inner padding; legend column 180px.
- Radius: 12px modal, 6px inputs and buttons, 0 for the print page (it is paper).
- Shadows: modal 0 24px 48px rgba(0,0,0,0.25).
- Scrim: #0f1115 at 60% opacity.
- Motion: modal 200ms scale-fade; preview updates cross-fade 150ms; off under reduced motion.

### Components & interactions
ExportModal, LayoutSelect, OptionsAccordion, PreviewPane, PrintPage, TitleBar, MapFrame, LegendPanel, ScaleBar, NorthArrow, InsetMap, ExportFormatSelect, ProgressToast.

Interactions: every option updates the preview within 200ms; clicking the preview title edits it inline; Legend accordion toggles layers and reorders legend items; Branding adds a logo upload and footer text; Export renders server-side or in a worker and downloads; Cancel or Escape closes; preview zoom-to-fit and 100% toggle.

States to build: default preview; rendering preview (spinner overlay on map frame); exporting (progress toast); export failed (retry); legend empty (no visible layers → message); logo upload invalid type; very long title (wraps to two lines, then truncates with tooltip).

### Data & state
All state is local: settings in a react-hook-form store, persisted per map id in localStorage (try/catch). Seed a map 'Soil types, riverside district' with one building layer and six soil classes with invented labels.

Model: `ExportSettings{layout (standard|landscape|portrait|poster), title, show_legend, legend_order string[], show_scale, units (metric|imperial), show_north, show_inset, branding {logo_url, footer}, format (png|pdf|svg), dpi (150|300)}`; `MapLayer{id, name, visible, style {fill, opacity}, classes {label, color}[]}`.

### Accessibility
Modal is a dialog with labelled title and description, focus trapped, Escape closes. Accordion uses buttons with aria-expanded and controls. Legend swatches are paired with text labels; map classes are distinguishable by pattern option for colour-blind users. Preview has a text summary (title, layers, scale) for screen readers. Scrim behind the modal is 60% dark; modal content is on solid white.
Verified contrast: body text: #1a1d21 on #ffffff = 16.91:1; muted text: #5a6270 on #ffffff = 6.15:1; export button label: #ffffff on #1463ff = 4.93:1; options label on strip: #5a6270 on #eef0f3 = 5.38:1; input border: #8a919c on #ffffff = 3.18:1; focus ring: #1463ff on #ffffff = 4.93:1; page frame on pane: #1a1d21 on #f1f3f5 = 15.2:1.

### Security
Validate uploaded logo (PNG/SVG under 500 kB); sanitise SVG before rendering. Escape user-entered title and footer text. Generate exports client-side or via a signed request; never expose tile provider keys in exported metadata. No backend. Sanitise uploaded SVG logos (strip scripts and external references) and escape all text before drawing to canvas.

### Performance & SEO
Debounce preview re-render 150ms; render exports in a Web Worker/OffscreenCanvas where available; cap DPI at 300. App route noindex.

### Guardrails
- Make the preview a faithful WYSIWYG of the exported file (same fonts, proportions).
- Keep the options collapsed by default with sensible defaults so one click exports.
- Place Export bottom-left under the options where the eye finishes, with Cancel beside it.
- Scale legend text with the page but never below 12px at 100%.
- Remember the last used settings per map.
- 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:
  - [ ] Changing layout or options updates the preview
  - [ ] Legend reflects visible layers and order
  - [ ] PNG and PDF exports match the preview
  - [ ] Keyboard users can open, operate and close the modal
  - [ ] Settings persist per map

Open the builderAll templatesThis palette on its own