LaunchYourVibe

Launch your accessible vibe.

AI doesn't catch everything. Reference cards for vibe coders who want to ship secure, accessible apps with great UX. Click a card to flip for more info.

Free download · v1.0.4

Use this deck while you vibe code

The cards teach the patterns. This kit helps your AI remember them when you're building.

  • Starter rules — 28 always-on Cursor rules for the stuff AI forgets first
  • Domain packs — optional rules for UX, accessibility, security, and privacy
  • Ship-check skill — run a full review before you ship a feature
  • Cheat sheet — all 119 cards in one searchable doc
Download ZIP
Spacing & Typography
Spacing & Typography T-01
Fluid Type:
rem + clamp()
Narrow
1.5rem
Mid
~2rem
Wide
3rem
clamp(1.5rem, 1rem + 2.5vw, 3rem)
LAUNCHYOURVIBE T-01
Px breakpoints snap; user settings get ignored. Set type in rem and scale smoothly with clamp(): a minimum rem, a viewport-relative middle term, and a maximum rem. One formula replaces separate mobile and desktop charts.
Spacing & Typography T-02
The 8pt Grid:
Spacing in rem
0.25rem icon gaps, badge offsets
0.5rem within components
1rem padding, row gaps
1.5rem section gaps
2rem page sections
3rem major layout gaps
LAUNCHYOURVIBE T-02
Arbitrary spacing makes screens feel unsteady. Snap component gaps and padding to rem (0.25rem steps on an 8pt grid). For page-level breathing room, use vw in clamp() so gutters grow with the viewport.
Spacing & Typography T-03
Line Length:
45–75 Characters
Too Wide
~120 chars
Just Right
~60 chars
LAUNCHYOURVIBE T-03
Long lines force the eye to hunt for the next line. Short columns increase jumps per paragraph. 45–75 chars is where reading becomes effortless.
Spacing & Typography T-04
Weight Does the
Hierarchy Work
Page Title
Section heading
Body text reads here at regular weight. The eye moves through hierarchy without friction.
Caption · secondary info
LAUNCHYOURVIBE T-04
Color and size aren't the only tools. Weight creates hierarchy even in a single color. Use 400 for body, 600 for labels, 700 for headings: avoid everything in between.
Spacing & Typography T-05
Line Height by
Text Role
Headings1.1–1.3
Subheadings1.25–1.4
Body text1.5–1.6
Captions1.35–1.5
Buttonspad + lh ≥1.2
LAUNCHYOURVIBE T-05
Tight headings look intentional. Tight body text looks like a bug. Body line-height starts at 1.5 (WCAG). Button height comes from padding, not cramping line-height to 1.0.
Spacing & Typography T-06
Padding vs Margin:
Inside vs Outside
MARGIN (outside)
PADDING (inside)
Content
LAUNCHYOURVIBE T-06
Padding changes the element's feel; margin changes its relationship to neighbors. Use padding to make a button feel spacious. Use margin to create breathing room in a layout.
Spacing & Typography T-07
Visual Hierarchy:
3 Levels Maximum
5 Levels
3 Levels
LAUNCHYOURVIBE T-07
Every level you add competes with the others. Primary, secondary, and body. That's the hierarchy. Adding a fourth level usually means the third was doing too much.
Spacing & Typography T-08
Whitespace Is
a Design Element
Cramped
Breathes
LAUNCHYOURVIBE T-08
Space is not empty: it's structure. Generous spacing reduces cognitive load. The gaps between elements tell users which things belong together and what's a separate thought.
Spacing & Typography T-09
Left-Align Body Text.
Center Sparingly.
LEFT: body text, labels, lists
CENTER: short headlines, CTAs
CENTER: multi-line body copy
LAUNCHYOURVIBE T-09
Centered multi-line text is the hallmark of amateur design. The ragged left edge forces the eye to hunt for the start of each new line. Left-align everything longer than a headline.
Spacing & Typography T-10
Two Font Families.
That's the Budget.
Clear roles
Headings in Serif Family
Body in sans serif family
Code in monospace
FONT COLLECTION
Georgia Futura Garamond Helvetica Courier
LAUNCHYOURVIBE T-10
Example font families in clear roles feel like a system. Bold and regular are the same family, not a second one. Mixing families without roles creates noise. Three or more feel like you couldn't decide.
Spacing & Typography T-12
Letter Spacing:
Where It Helps
LABELS & TAGS+0.08 - 0.15em
Large Headlines−0.01 - 0.02em
Body paragraph text0 (default)
Code / mono+0.03 - 0.05em
LAUNCHYOURVIBE T-12
Tight letter spacing on big type is a design move. Tight spacing on small type is illegible. The smaller the text, the more spacing it needs: not less. Never tighten body text.
Spacing & Typography T-13
Proximity Creates
Visual Grouping
Equal gaps
Label
Label
Labels close
Label
Label
LAUNCHYOURVIBE T-13
A label 8px from its field looks owned. A label 16px away looks like a heading. The gap between things signals their relationship: closer means "these belong together."
Spacing & Typography T-14
Safe Zones:
Respect the Hardware
env(safe-area-inset-top)
env(safe-area-inset-bottom)
LAUNCHYOURVIBE T-14
UI placed in the notch or behind the home indicator isn't just ugly: it's unusable. Use CSS env() safe-area variables so your layout always respects the device's hardware edges.
Spacing & Typography T-15
Color + Type:
Two Signals Are Enough
Success: color + icon confirm it
Error: color + icon signal failure
Warning: color + icon shows caution
Info: color + icon for context
LAUNCHYOURVIBE T-15
Color alone fails for colorblind users. Pair every color-coded state with a second signal: an icon, label, or shape. This isn't accessibility extra credit; it's baseline UX.
Interaction
Interaction I-01
Every Button Needs
4 States.
Default
Save
Hover
Save
Active
Save
Disabled
Save
LAUNCHYOURVIBE I-01
Missing a state isn't neutral. No disabled state feels broken when nothing happens. Each state signals what's possible right now.
Interaction I-02
Error Messages:
Say What + Why + Fix
"Couldn't save changes."
Your session timed out after 30 min of inactivity.
Sign in again to continue →
"An error occurred."
...no help at all
LAUNCHYOURVIBE I-02
What happened. Why. What to do. Three sentences max. Plain language. No stack traces. Never blame the user.
Interaction I-03
Loading: Match the
Wait to the Pattern
Skeleton: page/card load
Progress: known duration
Spinner: quick actions
LAUNCHYOURVIBE I-03
Blank screens feel broken; spinners feel slow. Use skeleton loaders for content-heavy loads. Spinners for <2s actions. Progress bars when the user needs to know how long.
Interaction I-04
Destructive Actions
Need Friction:
On Purpose
Delete "Project Alpha"?
This will permanently remove all files and comments. This cannot be undone.
Cancel
Delete Forever
LAUNCHYOURVIBE I-04
Make the danger legible. Red button, explicit label, and a cost statement. "Are you sure?" without consequences doesn't create real friction: specifics do.
Interaction I-05
Success Is a
Moment. Mark It.
Payment Sent
$240.00 to Sarah Johnson
arrives in 1–2 business days
View Receipt →
LAUNCHYOURVIBE I-05
Silence after a successful action breeds doubt. Confirm what happened, to whom, and what comes next. The user's mental model needs closure.
Interaction I-06
Toast = Info.
Dialog = Decision.
Toast: ephemeral, non-blocking
File saved · Undo
Dialog: requires a choice
Unsaved Changes
Save before closing?
Discard
Save
LAUNCHYOURVIBE I-06
Dialogs steal focus because they have to. If the user can ignore it, use a toast. If they must choose, use a dialog. Never use a dialog to say something they don't need to act on.
Interaction I-07
Validate on Blur,
Not on Keystroke
Email address
sarah@company.com
Looks good
Password
••••••
Must be 8+ chars with a number
LAUNCHYOURVIBE I-07
Showing errors while someone is mid-thought is hostile. Wait for blur (field exit) to validate. Only re-validate on keystroke after the first error appears. Never on every character.
Interaction I-08
Optimistic UI:
Show Success First
Optimistic
UI updates instantly
Server syncs in background
Rollback only if server fails
Pessimistic
User waits for server confirmation
LAUNCHYOURVIBE I-08
Most requests succeed. Assume success, update the UI immediately, sync in the background. Roll back only on actual failure. The app feels instant even when it isn't.
Interaction I-09
Undo Beats
Confirm Dialogs
Act, then offer undo
Message deleted ·Undo (5s)
Interrupt with confirm
Delete this message?
[Cancel] [Delete]
LAUNCHYOURVIBE I-09
Confirms interrupt flow. Undo restores agency. Let users act immediately, then give them a short window to reverse it. They feel more in control, not less.
Interaction I-10
Every Tap Needs
Immediate Feedback
Feedback Types
Visual: color shift, scale, ripple
Haptic: light tap on iOS/Android
Audio: subtle chime (optional)
No feedback → broken?
< 100ms → feels instant
LAUNCHYOURVIBE I-10
Without feedback, users tap twice. Response within 100ms feels instantaneous. 100–300ms feels fast. Beyond 300ms, users start to doubt. Give visual feedback first, everything else second.
Interaction I-11
Progress: Show
Where They Are
Steps: clear location
1
2
3
4
Upload: % with estimate
42%~18s left
LAUNCHYOURVIBE I-11
Progress without context is just anxiety. Show step number, percentage, or time estimate. Giving users a frame of reference reduces perceived wait time by 40%.
Interaction I-12
Hover Actions
Don't Exist on Mobile
Mobile-first patterns
Long press reveals context menu
Swipe gesture shows actions
Always-visible action icons
Desktop pattern on mobile
"Hover to see options": oops
LAUNCHYOURVIBE I-12
Touch has no cursor. Any interaction hidden behind hover is invisible on mobile. If your content needs additional actions, make them visible, not discoverable via pointer proximity.
Interaction I-13
Disabled Means
"Not Yet": Explain Why
Contextual disabled
Submit
Complete all required fields to continue
Silent disabled
Submit
...why can't I click?
LAUNCHYOURVIBE I-13
A grayed button with no explanation creates confusion. Tell users what they're missing. The block becomes a guide, and prevents them from abandoning the form in frustration.
Interaction I-14
Swipe Actions Need
Visual Teaching
Message from Sarah
← swipe left / swipe right →
Show hint on first load
Reveal partially, then snap
Use consistent direction
LAUNCHYOURVIBE I-14
Gestures are invisible until taught. On first use, animate a partial swipe. Use destructive actions only on one side: left for danger is a convention users already know.
Interaction I-15
Right Keyboard
for Every Input
Phone numbertel
Email addressemail
URL / web addressurl
Whole numbersnumeric
Decimals / pricesdecimal
Search fieldsearch
LAUNCHYOURVIBE I-15
The wrong keyboard is a tiny betrayal of trust. A number pad for phone numbers, @ key for emails: set inputmode or type correctly and the keyboard is already optimized.
Components
Components C-01
Modal → Desktop
Bottom Sheet → Mobile
Desktop
Mobile
LAUNCHYOURVIBE C-01
Modals trap thumbs. On mobile, a centered dialog requires two-handed use. A bottom sheet rises from where thumbs already live. Same intent. Opposite ergonomics.
Components C-02
Tab Bar → Mobile
Sidebar → Desktop
Mobile
Home
Search
Profile
Desktop
LAUNCHYOURVIBE C-02
Thumb reach dictates nav placement. Bottom tabs stay in the natural grip zone on mobile. Sidebars use the screen width that desktop has to spare. Never swap them.
Components C-03
Forms Are Always
Single Column on Mobile
Two Column
cramped on small screen
Single Column
LAUNCHYOURVIBE C-03
Two columns on mobile means two columns of tiny inputs. Users skip fields accidentally and make more errors. Single column, full width. One field, one decision at a time.
Components C-04
Toggle = Immediate.
Checkbox = On Submit.
Toggle: takes effect now
Dark Mode
Checkbox: applied when saved
Marketing emails
Security alerts
LAUNCHYOURVIBE C-04
Toggles are instant actions. Checkboxes are selection within a form. If the setting takes effect the moment you flip it (like dark mode), use a toggle. If it's part of a group submitted together, use checkboxes.
Components C-05
Cards for Browse.
Lists for Scan.
Cards
Lists
LAUNCHYOURVIBE C-05
Cards invite exploration; lists support comparison. Use cards when each item has rich media or requires its own visual weight. Use lists when users are scanning for a specific item quickly.
Components C-06
Dropdowns on Mobile:
Use Native or Bottom Sheet
Native select / action sheet
Native <select> for short lists
Bottom sheet for long/visual lists
Tiny custom dropdown
LAUNCHYOURVIBE C-06
Custom dropdowns fight the OS. Native selects trigger the platform's built-in scroll picker: optimized for touch. Only build custom when the native control genuinely fails the need.
Components C-07
FAB = One Primary
Action. One.
One action, unmistakably primary
+
FAB Abuse
+
now nothing is primary
LAUNCHYOURVIBE C-07
The FAB is the most prominent tap target on screen. It implies "this is the thing you do most." If you can't name that one action, the FAB isn't the right pattern.
Components C-08
Chips: Filter or Select,
Not Both at Once
Filter chips: current filters
Design
Remote
+ Engineering
+ Product
Input chips: entered values
sarah@co.com
mike@co.com
Add...
LAUNCHYOURVIBE C-08
Chips have two distinct jobs: filtering and input. Don't mix them on the same surface. Filter chips are toggles. Input chips represent values the user has added. Styling should signal the difference.
Components C-09
Accordions Hide Content.
Use Them Intentionally.
Shipping information
Arrives in 3–5 business days. Free on orders over $50.
Returns policy
Size guide
Use for: secondary info, long FAQ, optional detail
Avoid for: primary content, critical steps, comparisons
LAUNCHYOURVIBE C-09
Accordions create extra work for the user. Every collapsed section is a barrier. Use them when the content is genuinely optional: not to make a page feel shorter while hiding required reading.
Components C-10
Date Pickers:
Match the Date Type
BirthdayMonth/Year scroll
Appointment timeCalendar + time
Date rangeTwo-cal inline
Relative date"In 3 days" chip
Year onlyYear scroll / input
LAUNCHYOURVIBE C-10
There is no universal date picker. Picking a birthday is a different task than scheduling a meeting. The interface should match the cognitive model: not force a calendar view on every date type.
Components C-11
4 Alert Levels.
Don't Cry Wolf.
Info: context, not urgent
Success: action completed
Warning: may need attention
Error: action failed or blocked
LAUNCHYOURVIBE C-11
Every alert in red trains users to ignore red. Reserve error alerts for actual errors. Info banners for context. If everything is urgent, nothing is. Overused alerts become wallpaper.
Components C-12
Search Placement
Signals Its Importance
Primary use case → top of page
Search products...
Secondary use → header icon / tab
(nav bar icon)
LAUNCHYOURVIBE C-12
If search is how most users navigate, it belongs at the top: always visible. If it's a power-user feature, tuck it in nav. Never make it a modal activation or a tiny corner icon on search-first apps.
Components C-13
Steppers for Small Ranges.
Input for Large.
Stepper: range of 1–10
3
+
Stepper: quantity of 500
... 497, 498, 499, 500 ← painful
→ Use a text input instead
LAUNCHYOURVIBE C-13
Steppers work for small, bounded quantities. If someone might want 500 of something, don't make them tap 499 times. Offer a direct input. Steppers should cover ranges users reach in under 10 taps.
Components C-14
Tooltips Are for
Desktop Power Users
Good tooltip use
K Search
Keyboard shortcut hints
Tooltip as documentation
Required to understand the UI
Critical info hidden in hover
Only touch-accessible on long press
LAUNCHYOURVIBE C-14
If users need a tooltip to use a feature, the feature needs better labeling. Tooltips are bonus context for experienced users: not a substitute for clear UI copy. And they don't exist on touch screens.
Components C-15
Infinite Scroll for Browse.
Pagination for Find.
Infinite scroll
Social feeds
Photo galleries
Content discovery
News streams
Pagination
Search results
Data tables
E-commerce lists
Audit logs
LAUNCHYOURVIBE C-15
Infinite scroll removes the user's sense of location. If they need to return to a specific item or share a result, pagination gives them an address. Endless scroll is for consuming, not finding.
Accessibility
Accessibility A-01
Contrast Ratios:
AA vs AAA
Body Text
4.5:1 minimum
Large Text
3:1 minimum
Enhanced
7:1 AAA
This fails
2.9:1
Large text = 18pt normal or 14pt bold
LAUNCHYOURVIBE A-01
AA is the legal baseline; AAA is the gold standard. Body text needs 4.5:1. Large text (18pt+ or 14pt+ bold) needs 3:1. UI components and icons need 3:1 against adjacent colors. Test with a real contrast checker: eyeballing fails.
Accessibility A-02
Touch Target
Minimum Sizes
22px
Too small
~
36px
Marginal
44pt iOS
48dp Android
LAUNCHYOURVIBE A-02
A visually small element can still have a large hit area. iOS requires 44×44pt, Android recommends 48×48dp. Use padding to expand the tap zone without changing visual size. Crowded targets need 8pt spacing between them.
Accessibility A-03
Focus Indicators Must
Be Visible
Button
outline: none
Button
2px solid
Button
offset ring
LAUNCHYOURVIBE A-03
Keyboard users navigate entirely by focus ring. Never suppress it with outline: none without a custom replacement. Focus must meet 3:1 contrast against adjacent colors. Use :focus-visible to show it only for keyboard, not mouse.
Accessibility A-04
Every Interactive Element
Needs a Label
Screen reader hears: "Delete item"
×
aria-label="Delete item"
Screen reader hears: "Button"
×
LAUNCHYOURVIBE A-04
Icon buttons are invisible to screen readers without labels. Add aria-label to every icon-only button. Use aria-labelledby when a visible label exists nearby. The label should describe the action, not the icon.
Accessibility A-05
Semantic HTML:
Structure Is Meaning
Semantic
<header>
<nav>
<button>
Div soup
<div class="hd">
<div class="nav">
<div class="btn">
h1 → h2 → h3. Never skip levels.
LAUNCHYOURVIBE A-05
HTML elements carry meaning that assistive tech relies on. Use <button> for actions, <a> for navigation, and heading tags in sequential order. Screen readers use landmark elements (main, nav, aside) to let users jump between page sections.
Accessibility A-06
Color Alone Is Not
Enough
Color + icon
!
Color only
1 in 12 men have color vision deficiency
LAUNCHYOURVIBE A-06
Red/green distinctions are invisible to 8% of users. Always pair color with a second signal: an icon, a label, a pattern, or a shape. This applies to charts, status indicators, form errors, and any state communicated purely through hue.
Accessibility A-07
Support Text Resize
Up to 200%
100%
The quick brown fox jumps.
200%
The quick…
No horizontal scroll. No clipped content.
LAUNCHYOURVIBE A-07
Low-vision users regularly set system font size to 150–200%. Use relative units (rem, em): never px for font sizes. Test by bumping browser font size to 200% and checking for content loss, overflow, or broken layouts. Mobile: respect system dynamic type settings.
Accessibility A-08
Respect Reduced
Motion Preferences
@media (prefers-reduced-motion: reduce) {
* { animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important; }
}
Vestibular disorders affect 35% of adults 40+
LAUNCHYOURVIBE A-08
Parallax, auto-playing carousels, and screen-wide transitions can trigger vestibular disorders. Check prefers-reduced-motion and remove or minimize non-essential animation. Keep functional transitions (loading, focus)...eliminate decorative ones.
Accessibility A-09
Labels Always Visible:
Never Placeholder-Only
Persistent label
Email address
user@example.com
Placeholder label
Email address
Disappears on type
LAUNCHYOURVIBE A-09
Placeholders vanish when users start typing. This breaks cognitive load for anyone who forgets what a field was, and breaks screen readers entirely. Use a persistent <label> element for every input. Placeholder text is fine for examples: not for labels.
Accessibility A-10
Link Errors to Their
Fields Programmatically
aria-describedby linked
<input aria-describedby="err1">
<span id="err1" role="alert">
Visually associated only
Email
badmail
Invalid email address
LAUNCHYOURVIBE A-10
Screen readers don't infer visual proximity. Use aria-describedby to link the error message to its input, and role="alert" so it's announced immediately when it appears. aria-invalid="true" also signals the field state.
Accessibility A-11
Skip Navigation Links
Save Keyboard Users
Visible on :focus-visible only
Hidden from sighted users
First element in DOM
Without skip link: Tab × 40+ to reach content
LAUNCHYOURVIBE A-11
Keyboard users Tab through every nav item on every page load. A skip link lets them jump directly to main content. Place it as the very first focusable element. Visually hide it until focused: don't remove it from the DOM or tab order.
Accessibility A-12
Alt Text: Describe
the Purpose, Not the Pixels
Describes purpose
"Customer using the dashboard to track weekly goals"
Describes pixels
"Image of a person smiling at a laptop with plants in the background"
Decorative images
alt="": intentionally empty
LAUNCHYOURVIBE A-12
Alt text should convey what the image communicates in context. If the image is pure decoration, use an empty alt attribute (alt="") so screen readers skip it. If it's a chart, describe the key insight: not the visual style.
Accessibility A-13
DOM Order = Reading
Order
Logical DOM
DOM: Header
DOM: Main
DOM: Footer

Matches visual order
CSS-reordered
DOM: Footer
DOM: Main
DOM: Header

CSS order: 3 1 2
LAUNCHYOURVIBE A-13
Screen readers follow the DOM: not what's visible on screen. Using CSS order, float, or absolute positioning to rearrange visuals without reordering HTML creates a disjointed reading experience for keyboard and screen reader users.
Accessibility A-14
Icon Buttons Need
Accessible Names
Three ways to name an icon button
aria-label="Search"
aria-labelledby="visible-text-id"
<span class="sr-only">Search</span>
title="" alone doesn't count: it's not announced reliably
LAUNCHYOURVIBE A-14
The accessible name is what screen readers announce. For icon-only buttons the visual label is the icon: which is meaningless to AT. Pick the strategy that fits: aria-label for standalone icons, visually-hidden text when you need translatable strings, aria-labelledby when a visible label exists nearby.
Accessibility A-15
WCAG Levels: A, AA,
and AAA in Practice
Level A
Minimum. Alt text, keyboard access, no seizure-inducing content.
Level AA
Legal standard. 4.5:1 contrast, captions, visible focus, consistent nav.
Level AAA
Gold standard. 7:1 contrast, sign language, extended audio desc.
LAUNCHYOURVIBE A-15
AA is the target for most products, and what most accessibility laws require. AAA is aspirational and not required for entire sites. Start with AA conformance, document your approach, and layer in AAA where it meaningfully serves your users.
Data
Data D-01
Bar = Compare.
Line = Change Over Time.
BAR: Compare
LINE: Trend
Scatter: correlation · Area: volume over time
LAUNCHYOURVIBE D-01
The wrong chart type doesn't just look off: it misleads. Use bars when comparing discrete values across categories. Use lines when showing how a single value changes continuously over time. Connecting discrete categories with a line implies continuity that doesn't exist.
Data D-02
Pie Charts: Part-to-Whole
Only. Max 5 Slices.
Desktop 45%
Mobile 35%
Tablet 20%
Never compare across pies
LAUNCHYOURVIBE D-02
Pie charts only answer one question: what share of the whole? They require slices to sum to 100%. Beyond 5 slices, human perception breaks down: angles are harder to compare than lengths. Use a bar chart if you want comparison; a pie if you want composition.
Data D-03
Empty Chart States
Are Not Optional
Helpful empty state
No data yet for this period.
Start tracking to see trends here.
Broken empty state
undefined
LAUNCHYOURVIBE D-03
An empty chart with no explanation looks broken. Design the zero state: explain why there's no data, tell users what action produces data, and consider showing a ghost/preview of what the chart will look like. Every chart needs a zero state, a loading state, and an error state.
Data D-04
Axis Labels and Units
Must Always Be Visible
Labeled
$K Month
No context
Month
Values 0–? Unknown
LAUNCHYOURVIBE D-04
A chart without axis labels is a Rorschach test. Every axis needs a label and a unit. "Revenue" without "$" or "K" forces users to guess the scale. Never rely on tooltips alone: they're invisible on mobile and require interaction to reveal basic context.
Data D-05
Small Multiples Beat
One Crowded Chart
Small multiples
Overloaded
LAUNCHYOURVIBE D-05
When one chart gets more than 4–5 series, everything competes. Small multiples repeat the same chart structure for each category, letting users see patterns across dimensions at a glance. Same scale, same axes: shape differences become immediately readable.
Data D-06
Use Accessible Palettes
in Data Visualization
Colorblind-safe
Red/green only
Indistinct to 8% of users
Also vary shape + pattern for print
LAUNCHYOURVIBE D-06
Never rely on red vs. green to distinguish data series. Use palettes designed for colorblind users (IBM Carbon, ColorBrewer, Tableau colorblind). Pair color differences with shape, texture, or direct labeling so the chart works without color at all.
Data D-07
Tables for Lookup.
Charts for Patterns.
Use TABLE when…
Exact values matter
Users scan rows
Multiple attributes per item
Use CHART when…
Shape / trend matters
Comparing categories
Relative size is the point
LAUNCHYOURVIBE D-07
Charts reveal patterns; tables reveal values. If a user needs to look up a specific number, a table serves them better than a chart. If they need to understand a trend, distribution, or comparison across categories, a chart does what a table can't.
Data D-08
Sparklines: Trend
at a Glance
Revenue
$48.2K
Users
1,204
Churn
3.1%
LAUNCHYOURVIBE D-08
Sparklines pack trend context into a single row. They're not for precise reading: they're for direction and shape at a glance. Pair them with a KPI value. Omit axis labels; the shape is the message. Perfect for dashboards with many metrics in limited space.
Data D-09
Reduce Data Density
on Mobile
Mobile: simplified
Q1 Q2 Q3
Desktop: full
J F M A M J
LAUNCHYOURVIBE D-09
Mobile screens are too narrow for complex chart layouts. Reduce the number of data points, consolidate time periods (months → quarters), increase label size, and favor horizontal bar charts over vertical ones where space is constrained. Link to a fuller view if detail matters.
Data D-10
Chart Tooltips: Detail
on Demand
Apr 2024 $24,100
Hover/tap → precise value
Tooltips don't exist on mobile without tap
LAUNCHYOURVIBE D-10
Tooltips layer precise values onto a chart without cluttering it. Don't rely on them as the only access to important data: mobile users must tap to trigger them, and they're invisible until interaction. Design for the chart to communicate its core message without tooltip dependency.
Data D-11
Bar Charts Start
at Zero. Always.
Zero baseline
102 0 Honest scale
Truncated y-axis
102 98 Looks dramatic
LAUNCHYOURVIBE D-11
Truncating a bar chart's y-axis turns minor differences into apparent crises. Bar height encodes quantity: cutting the baseline misrepresents proportions. Line charts can use non-zero baselines to show variance; bar charts cannot. If differences are small, consider a line chart instead.
Data D-12
Donut Charts: Add a
Summary KPI in the Center
58% Complete
Done 58%
Remaining 42%
Center = the whole story at a glance
LAUNCHYOURVIBE D-12
The donut chart's hole is prime real estate. Use it for the single most important number: total, percentage complete, or a key KPI. Without a center value, a donut chart is just a pie with a hole: the center makes it meaningfully different.
Data D-13
Stacked Bars Mislead
Middle Segments
Q1 Q2 Q3 Top Mid Bot
Middle segments float: hard to compare across bars
LAUNCHYOURVIBE D-13
Stacked bars only allow accurate comparison of the bottom segment and the total. Middle segments float on different baselines, making comparison nearly impossible. If comparing sub-categories matters, use grouped bars. Use stacked bars only when total and bottom segment are the story.
Data D-14
Layer Data: Summary
First, Detail on Demand
$48K
Monthly Revenue
↑ 12% vs last month
Tap → breakdown by product / region / channel
Product A
$22K
Product B
$18K
Other
$8K
LAUNCHYOURVIBE D-14
Most users want the headline; a few want the footnotes. Lead with the single most important number and its trend. Let users drill into breakdown views only if they choose. Showing everything at once creates dashboards that exhaust instead of inform.
Data D-15
Chart Titles State the
Insight, Not the Subject
Insight title: reader gets it instantly
West Region Outpaced All Others Q3
Revenue by region, Jan–Sep 2024
Subject title: reader works harder
Monthly Revenue by Region
What am I supposed to see here?
LAUNCHYOURVIBE D-15
A subject title labels the chart. An insight title does the analysis for the reader. Move the descriptive label to a subtitle. The title should complete the sentence: "The main thing this chart shows is ___." Users shouldn't have to read and interpret: they should arrive at the conclusion immediately.
Security
Security S-01
Filter by User ID.
Always.
Scoped to session
WHERE user_id = $session
Only your rows return
No filter
SELECT * FROM notes
User B's data visible to User A
LAUNCHYOURVIBE S-01
Every user-specific fetch must filter by the authenticated user's ID. Test it by logging in as User A and manually requesting User B's data. If you can see it, you have a problem. This isn't a platform feature you toggle on — it's a check you write and verify.
Security S-02
Use Supabase, Clerk,
or Auth0.
Managed provider
Supabase Clerk Auth0
OAuth, MFA, refresh — handled
DIY auth stack
Custom session store
Hand-rolled password reset
You maintain the patches
LAUNCHYOURVIBE S-02
Rolling your own session management is where breaches are born. Use Supabase Auth, Clerk, or Auth0. They handle tokens, refresh, MFA, and OAuth so you don't have to — and they stay patched when new vulnerabilities emerge.
Security S-03
Hiding a Button
Is Not Security.
UI only
Admin Panel
Button hidden in React
Server check
403 Forbidden
Session verified on API
LAUNCHYOURVIBE S-03
Every protected action checks the session on the server before returning data. UI-only access control is theater — a crafted request bypasses it in seconds. Hiding a button is not access control.
Security S-04
Client Code Is
Public Code.
Exposed in bundle
const API_KEY = "sk_live_...";
const isAdmin = true;
View Source · DevTools · Network tab = all public
LAUNCHYOURVIBE S-04
Anything shipped to the client is public. API keys, service role keys, admin flags — none of it belongs in frontend code. If it's in your bundle, assume everyone can read it.
Security S-05
.env in Gitignore.
Rotate if Exposed.
Env vars only
.gitignore → .env
Rotate keys if ever committed
Committed to git
DATABASE_URL=postgres://...
Still in history after delete
LAUNCHYOURVIBE S-05
Committed secrets live in history forever even after deletion. Gitignore .env and rotate anything that ever shipped. A deleted line in today's code doesn't erase yesterday's commit.
Security S-06
Parameterize
Every Query.
Prepared statement
WHERE id = $1
Input treated as data, not code
String concat
"... WHERE id = '" + input
'; DROP TABLE users;--
LAUNCHYOURVIBE S-06
Raw string concatenation in queries is how SQL injection happens. Parameterized queries are non-negotiable — let the database engine separate data from instructions.
Security S-07
localStorage =
Readable by Any Script.
httpOnly cookie
Set-Cookie: token=…; HttpOnly
JavaScript cannot access
localStorage
localStorage.setItem("jwt", token)
Any script can read it
LAUNCHYOURVIBE S-07
JWTs stored in localStorage are readable by any script on the page. httpOnly cookies are not. One XSS vulnerability with localStorage tokens = full account takeover.
Security S-08
Lock Out After
5–10 Failures.
Login attempts
Attempt 6 → account locked 15 min
LAUNCHYOURVIBE S-08
Unlimited login attempts are a brute force welcome mat. Throttle or lock after 5–10 failures. Add exponential backoff and alert on suspicious patterns.
Security S-09
Never Trust
the Client.
Server validates
schema.parse(body) → 400
Type, length, allowed values
Client only
if (email.includes("@")) ✓
Bypassed via API directly
LAUNCHYOURVIBE S-09
Everything reaching the database is checked for type, length, and allowed values. Client-side validation is UX convenience, not security — it can be bypassed with a single curl command.
Security S-10
User Content
Is Untrusted HTML.
Escaped output
&lt;script&gt;…
Rendered as text, not code
innerHTML
el.innerHTML = userInput
<script>steal()</script>
LAUNCHYOURVIBE S-10
User-generated content rendered directly to the DOM is an XSS vector. Escape or sanitize everything that came from a user before it touches the page.
Security S-11
Including Staging.
No Exceptions.
HTTP
http://staging.app
Credentials in plaintext
HTTPS
https://staging.app
Encrypted in transit
LAUNCHYOURVIBE S-11
HTTPS everywhere, always — no exceptions, including staging. Let's Encrypt makes this free. There is no excuse — credentials and tokens travel in plaintext without it.
Security S-12
Search for key,
secret, token.
grep -ri "secret\|token\|password\|api_key" .
Run before every deploy
Check .env.example too
Review matches, don't ignore
LAUNCHYOURVIBE S-12
Search your codebase for key, secret, token, password before every deploy. One command, five minutes, no surprises. Make it part of your ship checklist.
Security S-13
Old Commits
Keep Secrets Forever.
Git history
commit abc123API_KEY found
commit def456clean
commit ghi789password found
Scan before open-sourcing
LAUNCHYOURVIBE S-13
Before going public, run a secret scanner on your commit history. You'd be surprised what's buried in old commits — deleted files don't delete the history.
Security S-14
npm audit
Before Launch.
npm audit
critical2
high5
moderate12
Fix critical & high before ship
LAUNCHYOURVIBE S-14
Run npm audit or equivalent before launch. Known vulnerabilities in packages you didn't write are still your problem — transitive dependencies included.
Security S-15
Rotate First.
Investigate Second.
Suspected key exposure
1. Rotate key
2. Investigate
Old key stops working immediately
LAUNCHYOURVIBE S-15
The moment you suspect exposure, rotate first, investigate second. Stop the bleeding before you figure out the wound. A compromised key still works until you revoke it.
Privacy
Privacy P-01
Every Field Needs
a Reason.
Minimum viable
email — login
name — display
Each field documented
Kitchen sink schema
birthday
middle_name
favorite_color
No documented purpose
LAUNCHYOURVIBE P-01
Data you never collected can't leak. Every field in your schema should have a documented reason to exist. If you can't explain why you need it, don't collect it.
Privacy P-02
Policy = What You
Actually Collect.
Policy says
"We don't track location"
Code does
geo.getCurrentPosition()
LAUNCHYOURVIBE P-02
Your privacy policy must match the code, not your intentions. It describes what you actually collect, not what you intended to. A lying policy is legally worse than none.
Privacy P-03
Pre-Checked
Isn't Consent.
Explicit opt-in
Yes, send me updates
User must actively choose
Pre-checked
Send me marketing emails
Opt-out ≠ opt-in
LAUNCHYOURVIBE P-03
Email requires explicit opt-in. Pre-checked boxes aren't consent. CAN-SPAM and GDPR both have teeth and neither cares that you're small.
Privacy P-04
Know Where Every
Piece Lives.
User data map
PostgreSQLusers, posts
S3 bucketavatars/
Stripebilling
Mailchimpemail list
Delete request → purge all four
LAUNCHYOURVIBE P-04
Users can delete their data — you need to know where it all is first. Know where every piece of user data lives before someone asks you to remove it. "I'm not sure" is not an answer.
Privacy P-05
Logs Are
a Liability Too.
Need-to-know only
request_id, status,
duration_ms
Over-logging
IP, UA, body, cookies,
auth headers…
LAUNCHYOURVIBE P-05
Don't log what you don't need. Full user-agents, IP addresses, raw request bodies — if you're not actively using it, don't keep it. Logs are a liability too.
Privacy P-06
Know What You've
Invited In.
Third-party scripts
GA4 Intercom Hotjar
Full DOM access
Audit tags quarterly · remove unused
LAUNCHYOURVIBE P-06
Third-party scripts see everything on your page. Every analytics tag, chat widget, and ad pixel has access to your DOM and potentially your users' data. Know what you've invited in.
Privacy P-07
Stolen Credentials
Shouldn't Last Forever.
Never expires
Session: ∞
Stolen token = permanent access
Timeout enforced
Expires: 24h idle
Window closes automatically
LAUNCHYOURVIBE P-07
Sessions that never expire are stolen credentials that work forever. Set a reasonable timeout and enforce it. Refresh tokens rotate; idle sessions die.
Privacy P-08
Never Plain Text
in a Column.
Hashed at rest
$2b$12$K8x…9mZ
Plain text column
password: "hunter2"
LAUNCHYOURVIBE P-08
Sensitive fields get encrypted or hashed at rest. Passwords, tokens, anything personally identifiable — hashed or encrypted at rest. Never plain text in a column.
Privacy P-09
A Backup You've
Never Restored Is a Guess.
Verified restore
Last restore test: Mar 2024
RTO: 2h · RPO: 24h
Backup exists… maybe
Automated daily snapshot
Never tested a restore
LAUNCHYOURVIBE P-09
Backups exist and are tested. Know where your backups are and verify one actually works. A backup you've never restored is a guess.
Privacy P-10
Treat Every Repo
As Public Tomorrow.
🔒 Private repo Public tomorrow?
No secrets in source code
LAUNCHYOURVIBE P-10
Private repos aren't security. Treat every repo as if it could go public tomorrow. Private today doesn't mean private forever — misconfigured permissions, acquired companies, and leaked tokens happen.
Privacy P-11
No DROP or ALTER
for Your App User.
Scoped app role
SELECT, INSERT, UPDATE
on app.* only
Superuser app role
DROP TABLE
ALTER SCHEMA
GRANT ALL
LAUNCHYOURVIBE P-11
Least privilege on database users. Your app's database user shouldn't have DROP or ALTER permissions. Give it only what it needs to function — SELECT, INSERT, UPDATE, DELETE on specific tables.
Privacy P-12
Drop Unused Fields
Before Launch.
Ship with cruft
18 columns, 6 unused
Breached → all exposed
Trim pre-launch
12 columns, all used
Smaller blast radius
LAUNCHYOURVIBE P-12
Store the least data you can. Drop unused fields before launch, not after a breach. Data minimization is a design decision, not a cleanup task.
Privacy P-13
Third Parties Belong
in Your Policy.
We share data with:
Stripepayment info
Postmarkemail address
Google Analyticsusage data
Named · purpose stated · linked in policy
LAUNCHYOURVIBE P-13
Disclose what you share. If data touches a third party — analytics, payment processor, email provider — your privacy policy says so explicitly. Name them, name the data, name the purpose.
Privacy P-14
Export, Correct,
and Delete.
Account settings
Export
Correct
Delete
LAUNCHYOURVIBE P-14
Give users control over their data. Export, correction, and deletion aren't just legal requirements in some jurisdictions. They're what trustworthy products do.
Privacy P-15
Know Who to Notify
Before It Happens.
Incident response order
1 Contain & rotate keys
2 Notify legal counsel
3 Notify affected users (72h)
4 Regulators if required
Written before launch · rehearsed annually
LAUNCHYOURVIBE P-15
Breach plan before you need one. Know who you'd notify, in what order, within what timeframe. Figuring it out during an incident is too late.