sluggish-cafe

byMohamed

Build a complete, production-quality website for **Sluggish**, a specialty café in Kuwait. Reference: https://www.instagram.com/p/CxaKKDws_l_/ — match the café's real look, colors and mood from their Instagram. ## Brand & concept - Name: Sluggish. Theme: "slow down." The site celebrates taking your time, slow-brewed coffee and unhurried mornings. It should feel calm, warm, premium and a little playful (a sloth/snail-pace wink is fine, but keep it tasteful, not cartoony). - Palette: [pull from their Instagram — e.g., warm cream, espresso brown, muted sage]. Use CSS variables so it is easy to change. - Typography: one characterful display serif for headings + one clean sans for body. Arabic support with a matching Arabic font (e.g., IBM Plex Sans Arabic or Tajawal). - Bilingual: English + Arabic with a language toggle and full RTL layout for Arabic (mirrored layout, not just translated text). ## Pages / sections 1. **Hero**: full-bleed hero image or short muted looping video of coffee being poured, tagline "[e.g., Good things take time]", primary CTA "View Menu", secondary "Find Us". 2. **Our story**: short, warm copy about the slow-coffee philosophy, with an image. 3. **Menu**: filterable categories (Coffee, Cold Drinks, Tea, Desserts, Breakfast). Each item: name, short description, price in KWD (3 decimals, e.g., 1.750 KWD), optional photo, tags (iced, vegan, signature). Menu data lives in one JSON/array so it's easy to edit. Items: [paste their menu]. 4. **Signature drinks**: horizontal scroll or carousel of 4–6 hero items with large photography. 5. **Gallery**: Instagram-style masonry grid with a lightbox, plus a link to @[their handle]. 6. **Visit us**: address [area, block, street], embedded Google Map, opening hours [hours], with an "Open now / Closed" badge using Kuwait time (Asia/Kuwait). 7. **Contact**: WhatsApp click-to-chat button [number], phone, Instagram, and delivery links (Talabat / Deliveroo / Jahez: [links]). 8. **Footer**: logo, hours, socials, language toggle. ## Motion & smoothness (top priority) - Buttery smooth scrolling (Lenis or native smooth scroll), with scroll-triggered reveals: fade/slide-up, staggered menu items, subtle parallax on hero and gallery images. - Animate only `transform` and `opacity`. Never animate layout properties. Hold a steady 60fps, including on mid-range phones. - Micro-interactions: magnetic/hover-lift buttons, soft image zoom on hover, smooth menu-filter transitions (FLIP/layout animation), page-section transitions that feel slow and luxurious (ease-out, 400–800ms) but never block interaction. - A small, delightful touch tied to the brand (e.g., a slowly drifting steam animation over the hero cup, or a loader that "takes its time" but completes in under 1s). - Respect `prefers-reduced-motion`: disable parallax and large motion when it is set. ## Performance (must hit) - Lighthouse 95+ on Performance, Accessibility, Best Practices and SEO, on mobile. - LCP < 2.0s, CLS < 0.05, INP < 200ms. - Images: AVIF/WebP, responsive `srcset`, lazy-loaded below the fold, explicit width/height, blur-up placeholders. Preload the hero image. - Fonts: self-hosted, subset, `font-display: swap`, preload the display font. - Minimal JS. Code-split, no heavy libraries for things CSS can do. Static/SSG output. ## Quality - Mobile-first, fully responsive (360px → 1920px). Most visitors are on phones in Kuwait. - Accessible: semantic HTML, keyboard navigable, visible focus states, AA contrast, alt text on every image. - SEO: meta tags, Open Graph image, LocalBusiness / CafeOrCoffeeShop JSON-LD schema with address, hours and geo, sitemap, and EN/AR hreflang. - Sticky, minimal header that hides on scroll down and shows on scroll up; mobile slide-in menu. - Clean, organized, componentized code. Content (menu, hours, contact) kept in one editable data file. ## Tech [Let 8080 choose, or specify: e.g., Next.js / Astro + Tailwind + Framer Motion or GSAP + Lenis.] Deliver the full working site, not a mockup. Use high-quality placeholder coffee photography where I haven't supplied images, and clearly mark every placeholder so I can swap in real photos.

Hero
Hero

Comments (0)

No comments yet. Be the first!

System Requirements

System Requirements Document for sluggish-cafe

1. Introduction

sluggish-cafe is the production website for Sluggish, a specialty café in Kuwait. The site's purpose is to make a prospective customer feel the café's "slow down" philosophy before they ever walk in — calm, warm, premium, and quietly playful — and then give them everything they need to act: browse the menu, meet the signature drinks, see the room, check whether the café is open right now in Kuwait time, and reach the café by WhatsApp, phone, Instagram, or a delivery app.

The site is bilingual English/Arabic with a real mirrored RTL layout, mobile-first (most visitors are on phones in Kuwait), and built to a hard performance and accessibility bar. It is a complete, working, statically generated site — not a mockup — with all café content (menu, hours, contact) held in one editable data file and every placeholder photograph clearly marked for later replacement.

The visual language is warm cream and muted sage with a deep ink-green primary — no brown — and the motion language is fluid and super slick: an animated slug character (drawn from the user's supplied slug reference image) and cinematic, camera-like scroll choreography inspired by the 8080 3D-camera-portfolio reference, all still delivered as layered 2D DOM/SVG/CSS motion that protects the mobile Lighthouse targets.

The audience is phone-first, bilingual, design-literate Kuwaiti café-goers willing to pay a premium for a calm, unhurried experience, plus Arabic readers who expect the same information and actions in their own language and reading direction.

Page 1 of 33

2. System Overview

Sluggish is delivered as a statically generated, bilingual marketing site with no customer accounts, no ordering, and no transactional state. Every visitor is anonymous and public. The site presents eight source-named sections — Hero, Our story, Menu, Signature drinks, Gallery, Visit us, Contact, and Footer — composed into a single scrolling page experience with a sticky minimal header and a mobile slide-in menu.

All café content (menu items, categories, hours, address, contact numbers, social and delivery links, gallery images, signature drinks) lives in one editable data file consumed at build time. The site is rendered to static HTML/CSS/JS (SSG) and served as static assets. A shared FastAPI backend process and a MariaDB database are provisioned in the scaffold; they are available for application APIs and domain modules but are not required by any accepted customer-facing behavior in this release, because the site is static and read-only for visitors. No authentication, no accounts, and no persistent visitor data are introduced.

Two accepted human personas use the site: the Café visitor (English-first browsing) and the Arabic-speaking visitor (switches to Arabic and expects a fully mirrored RTL experience). Both are anonymous public visitors with identical access to all eight sections.

Page 2 of 33

Removed from scope

  • Customer accounts, login, and profiles (no source requirement; site is public and anonymous).
  • Online ordering, cart, checkout, and payment (ordering is handled by external delivery providers via outbound links).
  • A sloth or snail cartoon mascot, emoji-led copy, or sticker clutter (explicitly excluded by the brand brief and creative direction). The user-requested animated slug is a refined, non-cartoony motion character (see FR-29) and is not a mascot illustration, emoji, or sticker.
  • Brown as a brand colour (also: espresso brown, #4A2E1E, brown palette) — removed per the user's explicit feedback that they do not like the brown colour; the palette is revised to cream, sage, and deep ink-green.
Page 3 of 33

2a. Product Interpretation and Delivery Boundary

Delivery ownership. The site is a first-party, statically generated public website. All eight sections are first-party pages owned by the application and reachable anonymously with no access requirement. There is no protected area, no identity establishment, and no session continuity requirement, because no accepted behavior creates durable visitor-specific state, a commitment, an entitlement, or a value transfer that must remain bound to a visitor.

Provider and external ownership. Several actions leave the site and are owned by external providers, not by Sluggish:

  • WhatsApp click-to-chat opens WhatsApp (provider surface) with a pre-filled chat to the café's number.
  • Phone uses the device telephony handler (external).
  • Instagram links open Instagram (external destination).
  • Delivery links (Talabat, Deliveroo, Jahez) open those providers' surfaces (external destinations), where ordering is completed under the provider's ownership.
  • Embedded Google Map is a provider-embedded surface showing the café location.

Current vs. future. Everything in this document is current. The scaffold's FastAPI backend and MariaDB database are provisioned infrastructure available for future application APIs and domain modules; they do not add product behavior in this release. No future features are committed here.

Page 4 of 33

Placeholder boundary. Where the café has not supplied real photography, high-quality placeholder coffee photography is used and every placeholder is clearly marked (a data-placeholder attribute plus a visible caption) so real photos can be swapped in. The Instagram reference is authoritative for look, colour, and mood, but its pixels were unretrievable; the user's stated warm cream / muted sage palette is the operative brief and is reproduced, not replaced. The user's later feedback explicitly rejects brown, so the espresso-brown member of that palette is superseded by a deep ink-green primary while the warm, calm, premium mood is preserved.

Motion reference boundary. The 8080 3D-camera-portfolio reference is inspiration_only: it informs the quality and fluidity of motion (cinematic camera-like depth, seamless section transitions, scroll-driven flow) and nothing else — none of its content, copy, or imagery is imported. The slug reference image is authoritative for the animated slug character's visual basis only; it is not a content source.

2c. Page Content and Component Coverage

All eight pages are anonymous public surfaces with no access requirement. Each is a section of the single scrolling site, reachable via the sticky header, the mobile slide-in menu, and in-page anchors. All content is bilingual and mirrors under RTL.

Page 5 of 33

Hero

  • Information/state: Full-bleed coffee-pour photograph (or short muted looping video of coffee being poured); oversized tagline "Good things take time."; a small sage "Open now / Closed" capsule reflecting Kuwait time; brand wordmark context; the animated slug character travelling along the hero's lower edge.
  • Primary action: "View Menu" pill (ink-green-filled) → scrolls to Menu.
  • Supporting action: "Find Us" pill (sage-outlined) → scrolls to Visit us.
  • Domain entities: hero media (marked placeholder), tagline copy (EN/AR), open-status derived from hours data, animated slug character state (position along its path, reduced-motion static pose).
  • Component responsibilities: hero media frame with organic capsule/arch mask and subtle parallax; cream text block with curved edge overlapping the image; steam wisps (three low-opacity sage wisps, ~8s loop); CTA pills with magnetic hover-lift; open-status capsule; SlugCharacter (inline SVG slug with a fluid, squash-and-stretch crawl loop and a soft sage trail) layered over the hero's lower edge, never over readable text or controls.
  • States: loading (hero image preloaded; capsule loader fills ~700ms before paint); empty (n/a — static content); success (image + tagline + CTAs + slug render); error (if hero media fails, cream block and tagline remain readable with a marked placeholder fallback; the slug still renders because it is inline SVG); recovery (placeholder caption indicates swap-in point). Reduced motion: parallax, steam, and slug crawl removed; slug shown as a single static pose; static frame.
Page 6 of 33

Our story

  • Information/state: Short, warm slow-coffee philosophy copy (EN/AR) with an accompanying image.
  • Primary action: none required; scroll continuation to Menu.
  • Supporting action: in-page scroll reveals.
  • Domain entities: story copy, story image (marked placeholder).
  • Component responsibilities: editorial text block; image frame with soft hover zoom; curved boundary into the next section; scroll-linked depth reveal (image and copy translate on separate transform layers for a camera-like parallax).
  • States: loading (lazy-loaded below fold with blur-up); empty (n/a); success (copy + image); error (image fallback placeholder with caption); recovery (caption marks swap-in). Reduced motion: no parallax, single static frame.
Page 7 of 33

Menu

  • Information/state: Filterable categories — Coffee, Cold Drinks, Tea, Desserts, Breakfast. Each item shows name, short description, price in KWD with 3 decimals (e.g., 1.750 KWD), optional photo, and tags (iced, vegan, signature). Filter pills sticky beneath the header.
  • Primary action: select a category filter pill → list filters with a FLIP transition.
  • Supporting action: scroll through ruled rows; hover-lift/zoom on item photos.
  • Domain entities: menu item (name, description, price KWD 3dp, optional photo, tags, category); category.
  • Component responsibilities: filter pill group (ink-green/cream with sage active state); ruled-row list (single column mobile, two-column asymmetric at 768px, 12-column at 1280px); tabular right-aligned KWD prices; staggered row reveals (40ms apart) with a fluid FLIP re-flow on filter change.
  • States: loading (staggered reveal on scroll); empty (a category with no items shows a calm empty message); success (filtered list); error (if data file malformed at build, build fails rather than shipping broken menu); recovery (edit the single data file and rebuild). Reduced motion: no stagger/FLIP animation; instant filter with static layout.
Page 8 of 33

Signature drinks

  • Information/state: 4–6 signature hero items with large photography, name set in display serif over a cream caption bar.
  • Primary action: horizontally scroll/snap through the capsule-cropped cards.
  • Supporting action: soft image zoom on hover.
  • Domain entities: signature drink (name, large photo, caption).
  • Component responsibilities: horizontal snap-scroll row of capsule-cropped photos; caption bars; scroll-snap points; scroll-velocity-driven skew/scale on the cards for a fluid, camera-like glide.
  • States: loading (lazy images with blur-up); empty (if fewer than 4 items configured, render available items); success (scrollable row); error (image fallback placeholder with caption); recovery (caption marks swap-in). Reduced motion: items wrap into rows or remain horizontally scrollable so each is fully viewable.
Page 9 of 33

Gallery

  • Information/state: Instagram-style masonry grid (CSS columns) of café photography, plus a link to the café's Instagram handle.
  • Primary action: select an image → opens lightbox.
  • Supporting action: close lightbox; follow Instagram link (external).
  • Domain entities: gallery image (marked placeholder, alt text); Instagram handle/link.
  • Component responsibilities: masonry grid; lightbox overlay (keyboard-navigable, focus-trapped, Esc to close) with a fluid shared-element zoom from the tapped thumbnail; Instagram link.
  • States: loading (lazy images with blur-up); empty (if no images configured, show a calm message and the Instagram link); success (grid + lightbox); error (image fallback placeholder with caption); recovery (caption marks swap-in). Reduced motion: no parallax on gallery images; lightbox still works.
Page 10 of 33

Visit us

  • Information/state: Address (area, block, street), embedded Google Map, opening hours, and an "Open now / Closed" badge computed using Kuwait time (Asia/Kuwait).
  • Primary action: read address/hours and open-status.
  • Supporting action: interact with embedded map (provider surface).
  • Domain entities: address fields; opening hours; geo coordinates; open-status (derived).
  • Component responsibilities: address block; map embed; hours table; open-status badge (sage when open, muted when closed) computed against Asia/Kuwait.
  • States: loading (map embed lazy); empty (n/a); success (address + hours + correct badge); error (if map embed fails, address and hours remain readable with a link to maps); recovery (badge recomputes on load; hours editable in data file). Reduced motion: static.
Page 11 of 33

Contact

  • Information/state: WhatsApp click-to-chat button, phone number, Instagram link, and delivery links (Talabat / Deliveroo / Jahez).
  • Primary action: WhatsApp click-to-chat (provider surface).
  • Supporting action: tap-to-call phone; open Instagram; open a delivery provider.
  • Domain entities: WhatsApp number, phone number, Instagram handle, delivery provider links.
  • Component responsibilities: contact action buttons/links with hover-lift; external-link affordances.
  • States: loading (n/a); empty (if a link is unconfigured, hide that action rather than show a dead link); success (actions open correct destinations); error (provider unavailable — user can fall back to phone/WhatsApp); recovery (edit data file). Reduced motion: static.

Footer

  • Information/state: Logo, hours, socials, and language toggle.
  • Primary action: language toggle (EN ↔ AR).
  • Supporting action: social links (external); hours reference.
  • Domain entities: logo, hours, social links, language state.
  • Component responsibilities: footer layout mirroring under RTL; language toggle control; social links; a small static slug mark echoing the hero character.
  • States: loading (n/a); empty (n/a); success (footer renders, toggle switches language and direction); error (n/a); recovery (n/a). Reduced motion: static.
Page 12 of 33

3. Functional Requirements

Each story carries provenance: explicit (source-stated), basic_default (accepted default), or required_inference (indispensable inferred mechanics).

FR-1 — Complete working site (explicit) As a Café visitor I should land on a complete, production-quality, fully working Sluggish website (not a mockup) so that I can learn about the café and act on it.

  • Trigger: visit the site URL. Result: statically generated site renders all eight sections. Failure/recovery: if a section's media fails, text and controls remain usable with marked placeholders. Continuation: navigate via header/menu.

FR-2 — Slow-down brand theme (explicit) As a Café visitor I should feel a calm, warm, premium, quietly playful "slow down" mood — with a tasteful sloth/snail-pace wink, never cartoony — so that the café's philosophy is communicated.

  • Result: brand tone applied across copy, palette, type, and motion. Constraint: no cartoon mascots, emoji-led copy, or sticker clutter.
Page 13 of 33

FR-3 — Instagram-derived palette via CSS variables, revised away from brown (explicit) As a Café visitor I should see a warm cream / muted sage palette with a deep ink-green primary — drawn from the café's Instagram mood and revised away from brown per the user's feedback — implemented with CSS variables so it is easy to change.

  • Result: palette tokens on :root; café can swap real Instagram hexes in one place.
  • Constraint: no brown anywhere in the palette, surfaces, imagery grading, or copy accents; the warm, calm, premium mood is preserved through cream, sage, and ink-green instead.

FR-4 — Typography with Arabic support (explicit) As a Café visitor I should see one characterful display serif for headings and one clean sans for body, with Arabic support via a matching Arabic font (e.g., IBM Plex Sans Arabic or Tajawal).

  • Result: display serif headings, sans body, Arabic font for Arabic text.

FR-5 — Bilingual with mirrored RTL (explicit) As an Arabic-speaking visitor I should switch to Arabic via a language toggle and get a fully mirrored RTL layout (not just translated text) so that the experience matches my reading direction.

  • Trigger: toggle language. Result: dir="rtl", logical properties mirror the grid, all copy in Arabic. Failure/recovery: toggle remains reachable in header and footer. Continuation: browse all sections in Arabic.
Page 14 of 33

FR-6 — Hero (explicit) As a Café visitor I should see a full-bleed hero image or short muted looping video of coffee being poured, a tagline (e.g., "Good things take time"), a primary CTA "View Menu" and a secondary CTA "Find Us" so that I immediately understand the café and can navigate.

  • Result: hero renders; "View Menu" scrolls to Menu; "Find Us" scrolls to Visit us.

FR-7 — Our story (explicit) As a Café visitor I should read short, warm copy about the slow-coffee philosophy with an image so that I connect with the café's values.

FR-8 — Filterable menu (explicit) As a Café visitor I should filter the menu by Coffee, Cold Drinks, Tea, Desserts, and Breakfast, and see each item's name, short description, price in KWD with 3 decimals (e.g., 1.750 KWD), optional photo, and tags (iced, vegan, signature) so that I can decide what to order.

  • Trigger: select a category pill. Result: list filters with a FLIP transition. Failure/recovery: empty category shows a calm message. Continuation: scroll items.

FR-9 — Single editable menu data source (explicit) As the café owner I should have menu data live in one JSON/array so that it is easy to edit.

  • Result: menu items and categories defined in one data file consumed at build.

FR-10 — Signature drinks carousel (explicit) As a Café visitor I should browse a horizontal scroll or carousel of 4–6 signature hero items with large photography so that I can see the café's signature drinks.

Page 15 of 33

FR-11 — Gallery with lightbox and Instagram link (explicit) As a Café visitor I should browse an Instagram-style masonry grid with a lightbox and a link to the café's Instagram handle so that I can see the café's visual world and follow it.

  • Trigger: select an image. Result: lightbox opens (keyboard-navigable, Esc closes). Supporting action: Instagram link opens external destination.

FR-12 — Visit us with Kuwait-time open badge (explicit) As a Café visitor I should see the address (area, block, street), an embedded Google Map, opening hours, and an "Open now / Closed" badge computed using Kuwait time (Asia/Kuwait) so that I know where the café is and whether it is open now.

  • Result: address, map, hours, and correct badge. Failure/recovery: if map fails, address/hours remain readable with a maps link.

FR-13 — Contact and delivery links (explicit) As a Café visitor I should reach the café via a WhatsApp click-to-chat button, phone, Instagram, and delivery links (Talabat / Deliveroo / Jahez) so that I can contact or order.

  • Result: each action opens its correct destination (provider/external). Failure/recovery: unconfigured links are hidden; provider outage falls back to phone/WhatsApp.

FR-14 — Footer (explicit) As a Café visitor I should see a footer with logo, hours, socials, and a language toggle so that I can re-orient and switch language at the end of the page.

Page 16 of 33

FR-15 — Buttery smooth scrolling and reveals (explicit) As a Café visitor I should experience buttery smooth scrolling (Lenis or native smooth scroll) with scroll-triggered fade/slide-up reveals, staggered menu items, and subtle parallax on hero and gallery images so that the site feels slow and luxurious.

  • Constraint: animate only transform and opacity; never animate layout properties; hold steady 60fps including mid-range phones.

FR-16 — Micro-interactions (explicit) As a Café visitor I should get magnetic/hover-lift buttons, soft image zoom on hover, smooth menu-filter transitions (FLIP/layout animation), and slow luxurious page-section transitions (ease-out, 400–800ms) that never block interaction.

FR-17 — Brand delight touch (explicit) As a Café visitor I should encounter a small delightful brand touch — a slowly drifting steam animation over the hero cup, or a loader that "takes its time" but completes in under 1s.

  • Result: steam wisps over the hero cup (~8s loop) and a capsule loader that resolves in under 800ms.

FR-18 — Reduced motion (explicit) As a motion-sensitive visitor I should have parallax and large motion disabled when prefers-reduced-motion is set, so that the site remains comfortable and usable.

FR-19 — Performance targets (explicit) As a Café visitor on a phone I should get Lighthouse 95+ on Performance, Accessibility, Best Practices, and SEO on mobile, with LCP < 2.0s, CLS < 0.05, and INP < 200ms.

Page 17 of 33

FR-20 — Image optimization (explicit) As a Café visitor I should receive AVIF/WebP images with responsive srcset, lazy loading below the fold, explicit width/height, blur-up placeholders, and a preloaded hero image so that the page loads fast without layout shift.

FR-21 — Font optimization (explicit) As a Café visitor I should receive self-hosted, subset fonts with font-display: swap and a preloaded display font so that text renders quickly.

FR-22 — Minimal JS, static output (explicit) As a Café visitor I should get minimal, code-split JS with no heavy libraries for things CSS can do, delivered as static/SSG output.

FR-23 — Mobile-first responsive (explicit) As a Café visitor on a phone I should get a mobile-first, fully responsive layout from 360px to 1920px.

FR-24 — Accessibility (explicit) As a visitor using assistive technology I should get semantic HTML, keyboard navigability, visible focus states, AA contrast, and alt text on every image.

FR-25 — SEO (explicit) As a search engine or social platform I should receive meta tags, an Open Graph image, LocalBusiness / CafeOrCoffeeShop JSON-LD schema with address, hours, and geo, a sitemap, and EN/AR hreflang so that the café is discoverable and correctly indexed.

FR-26 — Sticky header and mobile menu (explicit) As a Café visitor I should get a sticky, minimal header that hides on scroll down and shows on scroll up, with a mobile slide-in menu.

Page 18 of 33

FR-27 — Clean componentized code and single content file (explicit) As the café owner I should have clean, organized, componentized code with content (menu, hours, contact) kept in one editable data file so that updates are easy.

FR-28 — Placeholder photography marked (explicit) As the café owner I should have high-quality placeholder coffee photography where images were not supplied, with every placeholder clearly marked so that I can swap in real photos.

FR-29 — Animated slug character (explicit) As a Café visitor I should meet a fluid, animated slug character based on the user's supplied slug reference image so that the "slow down" theme becomes a living, tactile brand gesture rather than a static logo.

  • Result: an inline SVG slug (no raster mascot art, no emoji) with a continuous crawl loop — squash-and-stretch body, rippling foot, soft sage trail — rendered over the hero's lower edge and echoed as a small static mark in the footer.
  • Constraint: tasteful and refined, never cartoony, never sticker-like, never emoji-led; it must never cover readable text or controls at 375px, 768px, or 1280px.
  • Constraint: animate only transform and opacity; the loop must hold 60fps on mid-range phones and must not block the hero CTAs.
  • Failure/recovery: if the animation cannot run, the slug renders as a single static pose.
  • Reduced motion: the crawl loop is removed entirely and the static pose is shown.
Page 19 of 33

FR-30 — Super-slick fluid motion language (explicit) As a Café visitor I should experience motion with the fluidity and cinematic quality of the 8080 3D-camera-portfolio reference — without copying its content — so that the site feels expensive, seamless, and unhurried.

  • Result: scroll-driven camera-like depth (layered parallax on hero, story, and gallery), velocity-aware easing on scroll-linked transforms, fluid shared-element transitions into the Gallery lightbox, scroll-velocity skew/scale on the Signature drinks row, and seamless curved-boundary section transitions.
  • Constraint: implemented as layered 2D DOM/SVG/CSS motion (Motion for React or GSAP + Lenis); no WebGL/Canvas/Three.js, because the mobile Lighthouse 95+ target is a hard constraint.
  • Constraint: animate only transform and opacity; never animate layout properties; hold steady 60fps including mid-range phones; transitions never block interaction.
  • Reduced motion: all scroll-linked and velocity-driven motion is removed; sections render as static frames and horizontal rows wrap or remain scrollable so every item is fully viewable.

4. User Personas

Page 20 of 33

Café visitor

  • Product context: A prospective customer in Kuwait, most likely on a phone, browsing to decide whether to visit Sluggish or order from it.
  • Primary goal: Understand the café's slow-coffee story, find something appealing on the menu, and confirm the café is open and reachable right now.
  • Distinct responsibilities: Browse Hero and Our story; filter the Menu by category and read item details with KWD prices and tags; explore Signature drinks and the Gallery (including the lightbox); check Visit us for address, map, hours, and the Kuwait-time open badge; act via Contact (WhatsApp, phone, Instagram, delivery links).
  • Inputs/decisions: Which category to filter; whether the café is open now; which contact or delivery channel to use.
  • Interactions with other participants: Shares the same public site with the Arabic-speaking visitor; hands off to external providers (WhatsApp, phone, Instagram, Talabat/Deliveroo/Jahez, Google Maps) for contact and ordering.
  • Observable success: Finds the menu item, confirms open status, and reaches the café or a delivery provider.
Page 21 of 33

Arabic-speaking visitor

  • Product context: An Arabic-reading customer who prefers the site in Arabic and expects a genuinely mirrored layout, not a translated overlay.
  • Primary goal: Read the story, menu, hours, and contact details in Arabic with a fully RTL experience, and take the same actions as the English experience.
  • Distinct responsibilities: Switch language via the toggle (header or footer); verify the layout mirrors (grid, alignment, direction); read menu items and prices in Arabic; use Visit us and Contact in Arabic.
  • Inputs/decisions: When to toggle language; which channel to use to reach the café.
  • Interactions with other participants: Same public site and same external providers as the Café visitor.
  • Observable success: The Arabic experience presents the same information and actions, correctly mirrored, with Arabic typography.
Page 22 of 33

5. Core User Flows

Flow A — Café visitor discovers the café and decides to visit (English)

  1. Visitor opens the site; the capsule loader fills (~700ms) and the Hero paints with the preloaded coffee-pour image, tagline "Good things take time.", and the sage open-status capsule. (Hero)
  2. Visitor reads the tagline and taps View Menu. (Hero → Menu)
  3. On Menu, visitor selects the Coffee filter pill; the list transitions with a FLIP animation and staggered rows reveal. (Menu)
  4. Visitor reads item names, descriptions, 3-decimal KWD prices, and tags (iced, vegan, signature). (Menu)
  5. Visitor scrolls to Signature drinks and swipes through the capsule-cropped cards. (Signature drinks)
  6. Visitor opens Gallery, taps an image, and views it in the lightbox; closes with Esc or the close control. (Gallery)
  7. Visitor scrolls to Visit us, reads the address and hours, and confirms the Open now badge (computed in Asia/Kuwait). (Visit us)
  8. Visitor taps Find Us (or scrolls) to the map, then uses Contact to open WhatsApp click-to-chat or a delivery link. (Contact → external provider)
  9. External provider (WhatsApp / Talabat / Deliveroo / Jahez) completes the contact or order under its own ownership. (provider surface)
  • Failure/recovery: If the map embed fails, address and hours remain readable with a maps link. If a delivery provider is unavailable, the visitor falls back to phone or WhatsApp. If hero media fails, the cream block and tagline remain readable with a marked placeholder.
Page 23 of 33

Flow B — Arabic-speaking visitor reads the site in Arabic

  1. Visitor opens the site in English and taps the language toggle in the header (or footer). (Header/Footer)
  2. The site switches to Arabic: dir="rtl", the grid mirrors via logical properties, and all copy renders in Arabic with the Arabic font. (all sections)
  3. Visitor reads the Hero tagline, Our story, and Menu in Arabic; filters categories and reads KWD prices. (Hero, Our story, Menu)
  4. Visitor checks Visit us for address, hours, and the open badge in Arabic. (Visit us)
  5. Visitor uses Contact to reach the café via WhatsApp, phone, Instagram, or a delivery link. (Contact → external provider)
  6. Visitor can toggle back to English at any time from header or footer. (Header/Footer)
  • Failure/recovery: If a link is unconfigured, that action is hidden rather than shown dead. Toggle remains reachable throughout.

Flow C — Café owner updates content

  1. Owner edits the single data file (menu items, categories, hours, address, contact numbers, social/delivery links, gallery, signature drinks). (data file)
  2. Owner rebuilds the static site; the build fails loudly if the data is malformed rather than shipping a broken menu. (build)
  3. Owner swaps marked placeholder images for real photos, guided by the data-placeholder attribute and captions. (assets)
  4. Updated site deploys as static assets. (deployment)
Page 24 of 33

6. Visuals Colors and Theme

The creative direction (sensual slow minimalism after Karim Rashid) is authoritative for this section. The user's warm cream / espresso brown / muted sage palette brief is reproduced, not replaced.

Muse and headline: Karim Rashid — sensual pop minimalism; headline gesture: "Good things take time." set oversized in italic display serif.

Colour tokens (light mode, CSS custom properties on :root):

  • --bg: #F3EBDD — warm cream page ground (largest area).
  • --surface: #FBF6EC — lighter cream for cards, menu rows, mobile slide-in panel.
  • --text: #1E2A24 — deep ink-green body ink on cream (readable contrast).
  • --primary: #24382E — deep ink-green; headings, wordmark, filled buttons, dark section grounds (cream text passes AA at body size). Replaces the rejected espresso brown.
  • --accent: #7E8F6A — muted sage; single hot accent (~8% of surface): open-now badge, signature tags, active filter pill, hover underline, steam wisps, slug trail.
  • --muted: #6F7A6C — muted sage-grey; secondary copy, rules, hairlines only (never body text on cream without darkening).
  • No brown token exists. The palette is cream + sage + deep ink-green; any brown hex from the earlier brief is removed from :root and from all component styles.
Page 25 of 33

Typography:

  • Headings: Fraunces, weight 300–400, soft "wonk" and optical-size axis on; tight leading 0.95–1.02; "Sluggish" and the hero tagline in italic Fraunces.
  • Body: Karla, 15–18px, line-height 1.6.
  • Arabic headings: Tajawal (or IBM Plex Sans Arabic) at weight 500 — never faux-serif, never Latin serif substituted.
  • Arabic body: Tajawal / IBM Plex Sans Arabic at 16–18px, line-height 1.75.
  • Scale: 1.333 modular, mobile-first — 40/30/22/17/15 at 360px scaling to 128/88/56/30/18 at 1280px via clamp(); display sizes as ranges, e.g. clamp(2.5rem, 9vw, 8rem).

Shape language: Rashid's organic capsule and blob vocabulary, restrained — pill-shaped buttons and filter chips, 28–40px soft radii on image frames and menu cards, curved section boundaries where cream meets ink-green, one recurring "slow" capsule motif as section divider and loader, and the animated slug's soft, rounded silhouette as the living expression of the same vocabulary. Glossy surfaces implied by a single soft top highlight on ink-green blocks and buttons — no glassmorphism, no gradients behind text.

Layout: Mobile-first asymmetric editorial grid; hero full-bleed pour photograph with an oversized flush-left tagline on a cream block breaking the image edge; sections alternate cream and deep ink-green grounds with curved boundaries; Menu single-column ruled rows on mobile → two-column asymmetric at 768px → 12-column at 1280px with sticky filter pills; Signature drinks horizontal snap-scroll of capsule-cropped photos; Gallery true masonry (CSS columns) with lightbox; Arabic mirrors via dir="rtl" and logical properties.

Imagery style: High-quality placeholder coffee photography, clearly marked — full-bleed pour shots, macro crema and latte-art, warm-lit café interiors with cream and wood, sage-toned ceramics; organic crops (capsule and arch masks, bled off edge, rotated 1–2°) but never over readable text.

Page 26 of 33

7. Signature Design Concept

The public entry is not a centred SaaS hero. It is a full-bleed, slightly warm-graded photograph of coffee being poured into a cream ceramic cup, occupying the right 60% of the viewport at 1280px (full width on mobile). Overlapping it from the left, a solid cream #F3EBDD block with a curved right edge carries the oversized Fraunces italic tagline "Good things take time." at clamp(2.5rem, 9vw, 8rem), flush-left and stacked over three lines, with the two CTAs — deep ink-green-filled View Menu pill and sage-outlined Find Us pill — pinned beneath it. A small sage Open now capsule sits top-right of the image. Three barely-there sage steam wisps drift up over the cup. Along the hero's lower edge, the animated slug crawls slowly across a sage trail, its body rippling with squash-and-stretch — the brand's slow-down wink, rendered as refined inline SVG, never cartoony and never over readable text. At 375px the block becomes a full-width band beneath the image with the same type-scale floor; no text ever sits under the photograph's busy area. The type, not the photo, is the hero.

8. Interaction Model & Motion Direction

Interaction Model: Animated Motion Tempo: expressive Hero Dimensionality: layered_2d

Page 27 of 33

Landing Hero Motion Brief

  • Focal subject: the coffee being poured into the cream ceramic cup in the full-bleed hero photograph, with the animated slug crawling along the hero's lower edge as the secondary focal gesture.
  • Input → transformation → outcome thesis: as the visitor scrolls or the page settles, the hero image drifts subtly on a depth layer (parallax) while the cream tagline block holds steady, the three sage steam wisps rise and fade on an ~8s loop, and the slug crawls forward with a fluid squash-and-stretch ripple — the outcome is a calm, tactile, expensive-feeling "slow down" first impression that never blocks the CTAs.
  • Motion vocabulary: Lenis (or native smooth scroll) with velocity-aware easing; Motion for React (motion/react) or GSAP for scroll-linked transforms; IntersectionObserver reveals with 600–800ms ease-out fade/slide-up; staggered menu rows (40ms apart); FLIP-style filter transitions; magnetic hover-lift on buttons; soft 1.05 image hover scale; steam wisps; slug crawl loop; capsule loader filling ~700ms; camera-like layered depth on hero, story, and gallery; shared-element zoom into the Gallery lightbox; scroll-velocity skew/scale on the Signature drinks row.
  • Composed first frame: full-bleed pour photo right, cream curved block left with oversized italic tagline and two pills (ink-green filled + sage outlined), sage open-status capsule top-right, faint steam wisps over the cup, slug resting at the start of its trail along the lower edge.
  • Optional interaction: hovering or focusing the slug pauses its crawl and lifts it slightly; the hero CTAs remain fully interactive at all times.
  • Responsive behavior: at 375px the slug scales down and stays inside the cream band beneath the image; at 768px and 1280px it travels the hero's lower edge without crossing the tagline block or the CTAs.
  • Reduced-motion state: parallax, steam, and slug crawl removed entirely; the slug renders as a single static pose; all motion reduced to a single static frame; loader resolves immediately; horizontal rows wrap or remain scrollable so every item is fully viewable.
Page 28 of 33

9. Non-Functional Requirements

  • Performance (explicit): Lighthouse 95+ on Performance, Accessibility, Best Practices, and SEO on mobile; LCP < 2.0s, CLS < 0.05, INP < 200ms. Rationale: phone-first Kuwaiti audience and user hard constraint.
  • Motion performance (explicit): animate only transform and opacity; never animate layout properties; hold steady 60fps including mid-range phones; section transitions never block interaction.
  • Motion quality (explicit): fluid, super-slick, cinematic motion in the spirit of the 8080 3D-camera-portfolio reference (layered depth, velocity-aware easing, seamless transitions), delivered as layered 2D DOM/SVG/CSS motion with no WebGL/Canvas/Three.js so the mobile Lighthouse 95+ target is protected.
  • Animated slug (explicit): inline SVG slug based on the user's reference image; tasteful, never cartoony; never covers readable text or controls; degrades to a static pose.
  • Reduced motion (explicit): respect prefers-reduced-motion; disable parallax, steam, slug crawl, and large motion.
  • Images (explicit): AVIF/WebP, responsive srcset, lazy-load below fold, explicit width/height, blur-up placeholders, preload hero image.
  • Fonts (explicit): self-hosted, subset, font-display: swap, preload display font.
  • JS (explicit): minimal, code-split, no heavy libraries for things CSS can do; static/SSG output.
  • Responsive (explicit): mobile-first, fully responsive 360px → 1920px.
  • Accessibility (explicit): semantic HTML, keyboard navigable, visible focus states, AA contrast, alt text on every image.
  • SEO (explicit): meta tags, Open Graph image, LocalBusiness / CafeOrCoffeeShop JSON-LD with address, hours, geo, sitemap, EN/AR hreflang.
Page 29 of 33
  • Bilingual/RTL (explicit): full mirrored RTL via dir="rtl" and logical properties, not text-only translation.
  • Data integrity (explicit): menu, hours, contact in one editable data file; build fails on malformed data rather than shipping broken content.
  • Placeholder marking (explicit): every placeholder image marked (data-placeholder + caption) for swap-in.

10. Tech Stack

  • Frontend: React application UI, statically generated (SSG) with minimal, code-split JS. Styling via CSS custom properties and utility/component CSS; motion via Lenis (or native smooth scroll) plus Motion for React (motion/react) or GSAP for scroll-linked, velocity-aware transforms, with lightweight IntersectionObserver/FLIP techniques — no heavy animation library where CSS suffices, and no WebGL/Canvas/Three.js.
  • Backend: shared FastAPI process for application APIs and domain modules (provisioned; not required by current customer-facing behavior).
  • Database: MariaDB for application-owned persistent data (provisioned; no visitor data or accounts in this release).
  • Deployment: static assets served for the site; Docker/docker-compose for the provisioned services. Kubernetes only if deployment requires it.
Page 30 of 33

11. Assumptions and Constraints

  • Assumption: The café's real menu items, hours, address, phone/WhatsApp numbers, Instagram handle, and delivery links will be supplied in the single editable data file; where the source left them as placeholders ([paste their menu], [hours], [number], [links], [area, block, street]), the build uses clearly marked placeholder values.
  • Assumption: The Instagram reference's exact pixels were unretrievable; the user's stated warm cream / muted sage palette (with brown removed per the user's feedback and replaced by a deep ink-green primary) is the operative brief and is implemented as CSS variables for later swap-in of real hexes.
  • Assumption: The slug reference image is used only as the visual basis for the animated slug character; its exact pixels are not shipped as raster art — the character is redrawn as inline SVG so it stays crisp, lightweight, and animatable.
  • Assumption: The 8080 3D-camera-portfolio reference is inspiration-only for motion quality; none of its content, copy, or imagery is imported.
  • Constraint: Deliver the full working site, not a mockup.
  • Constraint: Animate only transform and opacity; never animate layout properties.
  • Constraint: Hold a steady 60fps, including on mid-range phones.
  • Constraint: Section transitions must never block interaction.
  • Constraint: Respect prefers-reduced-motion: disable parallax and large motion when set.
  • Constraint: Lighthouse 95+ on Performance, Accessibility, Best Practices, and SEO on mobile.
  • Constraint: LCP < 2.0s, CLS < 0.05, INP < 200ms.
  • Constraint: Lazy-load images below the fold; preload the hero image and the display font.
Page 31 of 33
  • Constraint: Minimal JS, code-split, no heavy libraries for things CSS can do; static/SSG output.
  • Constraint: Mobile-first, fully responsive from 360px to 1920px.
  • Constraint: Semantic HTML, keyboard navigable, visible focus states, AA contrast, alt text on every image.
  • Constraint: Arabic layout must be mirrored RTL, not just translated text.
  • Constraint: Menu prices in KWD with 3 decimals.
  • Constraint: The "Open now / Closed" badge must use Kuwait time (Asia/Kuwait).
  • Constraint: Menu data must live in one JSON/array; content (menu, hours, contact) must be kept in one editable data file.
  • Constraint: Clearly mark every placeholder image so real photos can be swapped in.
  • Constraint: Keep the sloth/snail-pace wink tasteful, not cartoony; the animated slug must read as refined brand motion, not a mascot illustration, emoji, or sticker.
  • Constraint: No brown in the palette, surfaces, imagery grading, or copy accents; the palette is cream + muted sage + deep ink-green.
  • Constraint: Motion must feel fluid and super slick (cinematic layered depth, velocity-aware easing, seamless transitions) while remaining layered 2D DOM/SVG/CSS — no WebGL/Canvas/Three.js.
  • Constraint: The animated slug must never cover readable text or controls at 375px, 768px, or 1280px.
  • Constraint: Readable text and controls stay whole at every viewport (375px, 768px, 1280px); imagery and decoration may crop, bleed, rotate, or overlap, but never cover readable text or controls.
Page 32 of 33

12. Glossary

  • Sluggish: The specialty café in Kuwait and the name of this website.
  • Slow down: The café's brand theme celebrating unhurried mornings and slow-brewed coffee.
  • KWD: Kuwaiti Dinar; menu prices shown with 3 decimals (e.g., 1.750 KWD).
  • Asia/Kuwait: The timezone used to compute the "Open now / Closed" badge.
  • RTL: Right-to-left layout direction for Arabic, mirrored via dir="rtl" and logical properties.
  • FLIP: First-Last-Invert-Play animation technique used for smooth menu-filter transitions.
  • Lenis: Smooth-scroll library (or native smooth scroll) used for buttery scrolling.
  • Slug character: The animated inline-SVG slug based on the user's supplied reference image; the site's living "slow down" gesture.
  • Ink-green: The deep green primary (#24382E) that replaces the rejected espresso brown across headings, wordmark, filled buttons, and dark section grounds.
  • SSG: Static Site Generation; the site is pre-rendered to static HTML/CSS/JS.
  • Placeholder: A clearly marked stand-in coffee photograph (data-placeholder + caption) to be swapped for real café photos.
  • JSON-LD: Structured data (LocalBusiness / CafeOrCoffeeShop) for SEO with address, hours, and geo.
Page 33 of 33
Live
Hero design preview
Hero: View English entry
Footer: Toggle to Arabic
Hero: Read Arabic tagline with animated slug
Our story: Read Arabic story
Menu: Filter categories in Arabic
Menu: Read Arabic prices and tags
Visit us: Read Arabic address and hours
Visit us: Confirm open badge
Contact: Open WhatsApp or delivery
Footer: Toggle back to English
Live
Hero design preview
Hero: View English entry
Footer: Toggle to Arabic
Hero: Read Arabic tagline with animated slug
Our story: Read Arabic story
Menu: Filter categories in Arabic
Menu: Read Arabic prices and tags
Visit us: Read Arabic address and hours
Visit us: Confirm open badge
Contact: Open WhatsApp or delivery
Footer: Toggle back to English