Skip to content

UX strategy — mobile-first, Apple-grade

This page is the guide for every visual + interaction decision going forward. Not a launch checklist — a standing reference when you're about to add a button, a page, a modal.

Principles

  1. Thumb-first. Every interactive element a customer needs in under 3 steps must be reachable by the thumb of a one-handed grip.
  2. Every pixel justifies itself. If removing something doesn't hurt the flow, remove it.
  3. Server price is truth. The box builder's canonical price comes from POST /fruitplug/v1/box/price. Client-side state is a preview.
  4. Silent routes. Install-prompt, upsells, banners never appear on /p/*, /cart, /checkout, /build-your-box/*, /account — the buying path is sacred.
  5. Real content over stock. Use Instagram reels and real fruit photos. No generic food stock.

Palette (sampled from public/brand/logo.png)

Token Hex Use
--fp-magenta #fc1c80 Primary CTA, price, active tab, primary icon tint
--fp-magenta-600 #e5006a Hover/pressed state for magenta
--fp-magenta-400 #ff4da0 Lighter accents, focus rings
--fp-magenta-900 #b9165c Shadow / depth inside the glyph
--fp-leaf #03a143 "Fresh-picked", "In season", seasonal calendar hits
--fp-leaf-400 #1fb85a Hover on green accents
--fp-sticker #faaf3f Warmth — next-day badges, ripe-indicator, notifications
--fp-pith #f5f5f0 Fruit-flesh off-white — text on colored fills
--fp-white #ffffff Primary foreground on black
--fp-black #000000 Canvas

Rule of thirds: magenta is dominant, leaf is secondary accent, sticker is a rare highlight (under 5% of page surface).

Typography

  • Display — Grit (licensed, drop public/fonts/grit.woff2) → Caveat Brush (Google Fonts fallback) → system cursive. .fp-display on every hero, section heading, stat value.
  • Body — Montserrat. 16px base, 1.5 line-height. No overrides without reason.

Surfaces

Glass Header — .fp-glass

Macro/Vision Pro glass: backdrop-filter: blur(24px) saturate(180%) plus a gradient background that deepens as the user scrolls (CSS scroll-timeline, with graceful fallback). Two hairline insets: a bright 1px top highlight (light from above) and a 1px bottom divider. Passes the "premium glass" test from 2024 Apple design language.

Glass Tab Bar — .fp-glass-bottom

Mirror of the Header, inverted. Used on the fixed mobile bottom tab bar. 10px + env(safe-area-inset-bottom) padding so it clears the iOS home indicator.

Cards

rounded-2xl border border-border/60 bg-white/[0.02]. Never shadow-heavy. Hover adds border-primary/40 — no scale transform on primary lists (cheap, creates motion sickness).

Layout

  • Header height: 64px + env(safe-area-inset-top) + 10px extra top clearance for iOS status bar.
  • Tab bar height: 64px + 5px + env(safe-area-inset-bottom).
  • Body bottom padding: calc(35px + env(safe-area-inset-bottom)) on mobile only. Intentionally leaves the last ~30px of content "behind" the frosted tab bar so the glass reads as glass, iOS-Safari-style.
  • Max width: max-w-6xl (72rem) for content. max-w-md for forms.
  • Horizontal padding: px-4 sm:px-6. That's the whole rule.

Interaction

  • Tap targets: 40×40px minimum, 44×44px for primary actions. Bottom-tab items are 20% of viewport width each on a 5-tab grid.
  • Viewport: zoom locked (maximumScale: 1, userScalable: false, viewportFit: "cover") so form inputs don't trigger iOS auto-zoom and the native-app feel is preserved.
  • Motion: 300ms ease-out for drawers, 200ms for state changes, 150ms for hover. Never longer.
  • Haptics (future): trigger navigator.vibrate(10) on add-to-cart and box-composition changes.

Mobile (<md)

  • Top — glass Header with logo, account icon, cart pill, hamburger (opens drawer).
  • Bottom — 5-tab glass bar: Home · Shop · Build · Cart · Account. Active tab gets a 2px magenta line + magenta tint.
  • Drawer — slides in from the right on hamburger. Secondary links (Subscribe, Recipes, About, FAQ). Backdrop blur + click-outside to close + Escape to close.

Desktop (≥md)

  • Classic horizontal nav inside the Header. No tab bar.

Install prompt etiquette

  • Appears after 25 seconds of engagement OR 3+ page views (whichever first).
  • Never on: /p/*, /cart, /checkout, /build-your-box/*, /account.
  • Positioned bottom-[calc(64px+env(safe-area-inset-bottom))] so it sits ABOVE the tab bar, never hides the footer or tabs.
  • Dismissed: 14-day silence in localStorage.

Content hierarchy

Home

  1. Glass Header
  2. Hero — big display title, tagline, two buttons (Shop Boxes primary, Build Your Own secondary)
  3. TrustStrip — 3 icons in the three brand colors (green = fresh, amber = next-day, magenta = reviews)
  4. Social proof — stats band (clickable IG + TikTok stats link out)
  5. Watch the plug — featured reels grid (3 videos, IntersectionObserver-lazy, click-to-play)
  6. What's coming — 4 feature cards
  7. Footer

PDP

Above-the-fold on mobile must contain: gallery, name, price, Add-to-Cart. Anything else is below the fold. Description lives in a <details> only if it's >200 words; otherwise expanded inline.

Box builder

Sticky bottom summary on mobile. Server-validated price always displayed. Credits bar turns red on over-budget. "Save this box" redirects to /login?next=... on 401 — never silently fails.

/account

Hi-{firstname} greeting, logout pill, three QuickLinks (Shop again / Build / Subscribe), then the last 10 orders as cards.

SEO

Canonical host is https://fruitplug.co.uk regardless of where the bytes are served from. SEO_INDEXABLE=1 on production only — dev stays Disallow. Every commerce surface emits JSON-LD (Product, Organization, WebSite, BreadcrumbList, CollectionPage). See SEO & structured data.

What's explicitly NOT shipped

  • Page transitions / route animations. Deferred until perf budget confirmed.
  • Haptic feedback. Phase 2.
  • Skeleton loading states. Phase 2.
  • Review schema with individual Reviews. Phase 2.
  • Preparation Guide schema (FAQ/HowTo). Phase 2.
  • Offline-first catalog caching. Phase 2, behind the service worker.

Review cadence

Re-audit every 4 weeks on iPhone 14 viewport (390×844) and Pixel 7 (412×915). Capture: home, shop, PDP, cart, box builder, /account, /login. File findings against this doc — if a finding contradicts a principle here, either change the principle or fix the code.