# Global UI Components & Content Standards

**Project:** Bangladesh Saree E-Commerce Website  
**File Role (For AI Agent):** **Single source of truth for all SHARED UI rules** — breakpoints, buttons, badges, image ratios, the responsive product slider, filter taxonomy, price formatting, form/feedback states, empty states, purchase-action behavior, and floating-element layering.  
**Precedence Rule:** If any page plan conflicts with this file on a shared rule, **this file wins**. Token values come from `global_color_typography_design_plan.md`.  
**Styling Rule:** Only use the 12 variables (`--bg-main`, `--bg-surface`, `--brand-primary`, `--brand-accent`, `--text-primary`, `--text-muted`, `--text-light`, `--border-subtle`, `--state-success`, `--state-error`, `--font-heading`, `--font-body`). Zero hardcoded hex codes or font names.

---

## 1. Breakpoints, Containers & Spacing (Mobile-First)

| Device | Range | Side Padding | Section Spacing (top/bottom) |
| :--- | :--- | :--- | :--- |
| **Mobile** *(design first)* | `320px – 767px` | `16px` | `40px` |
| **Tablet** | `768px – 1024px` | `24px` | `52px` |
| **Desktop** | `1025px+` | `24px` | `64px` |

* **Content Container:** `max-width: 1280px`, centered. Checkout: `1140px`. Reading pages (policies): `760px`.
* **Touch Targets:** Every tappable element on mobile is at least `44px × 44px`.
* **No Horizontal Overflow:** Only sliders/galleries/pill rows scroll horizontally — never the page.
* **Devices with touch (mobile + tablet)** use touch behaviors (tap/swipe). Devices with a mouse use hover behaviors.

---

## 2. Button System

| Button Type | Style | Height | Used For |
| :--- | :--- | :--- | :--- |
| **Primary** | Bg `--brand-accent`, text `--text-primary` → hover/tap: bg `--brand-primary`, text `--text-light` | `48px` | `ORDER NOW`, `QUICK VIEW`, `PROCEED TO CHECKOUT →`, `EXPLORE SAREES →`, gateway CTAs |
| **Primary Large** | Same as Primary | `52px` | `CONFIRM ORDER — BDT X,XXX` only |
| **Secondary (Outlined)** | Bg `--bg-main`, `1.5px` border `--brand-primary`, text `--brand-primary` → hover/tap: bg `--bg-surface` | `48px` | `ADD TO CART`, `APPLY`, `WRITE A REVIEW`, `SHOW MORE REVIEWS` |
| **Compact** (Primary or Secondary style) | Same colors | `44px` | Mobile sticky order bar, cart drawer actions |
| **Disabled / Sold Out** | Bg `--bg-surface`, `1px` border `--border-subtle`, text `--text-muted` | Same as replaced button | `SOLD OUT`, processing states |
| **Icon Button (Circle)** | Bg `--bg-surface`, icon `--text-primary` → hover/tap: bg `--brand-primary`, icon `--text-light` | `36px` desktop / `44px` mobile | Close `✕`, slider arrows, share icons |
| **Text Link** | Text `--brand-primary`, underline/arrow `--brand-accent` on hover | — | `View All →`, `Edit Bag`, `View Full Product Details →` |

* All button labels: `--font-body`, Semi-Bold `600`, `14px` desktop / `13px` mobile, UPPERCASE, letter-spacing `0.8px`.
* **Processing State:** Button shows label "Please wait..." (or context label like "Confirming Order...") and becomes disabled to prevent double taps.

---

## 3. Badge & Label Standards

### A. Product Image Badges (Top-Left of Product Images)
| Badge | Format | Style |
| :--- | :--- | :--- |
| Discount | `-15%` | Bg `--brand-accent`, text `--text-primary` |
| New | `NEW` | Bg `--brand-accent`, text `--text-primary` |
| Sold Out | `SOLD OUT` | Bg `--bg-surface`, `1px` border `--border-subtle`, text `--text-muted` |

* **One badge only per image.** Priority: `SOLD OUT` > `-15%` > `NEW`.
* **`NEW` rule:** Shown automatically for **14 days** after the product's `createdAt` date.
* **Discount %:** `floor((oldPrice − price) ÷ oldPrice × 100)` — always rounded **down** to a whole number.

### B. Price-Row Savings Pill (Quick View & PDP only)
* Format: **`SAVE 15%`** (percentage only — never "SAVE BDT 700").
* Style: Bg `--brand-accent`, text `--text-primary`.

### C. Other Standard Labels
| Context | Exact Label |
| :--- | :--- |
| Out-of-stock button (Quick View, PDP, sticky bar) | `SOLD OUT` |
| Checkout payment badge | `PAY ON DELIVERY` |
| Stock line (in stock) | `● In Stock — Ready to Ship` (dot in `--state-success`, text `--text-primary`) |
| Low stock (stock ≤ 3) | `Only 2 left in stock` (`--state-error`, `13px`, Semi-Bold) shown under the stock line |
| Verified review | `✓ Verified Buyer` (check icon `--state-success`, text `--text-muted`) |

---

## 4. Image & Photography Standards

| Image Type | Aspect Ratio | Recommended Upload Size | Notes |
| :--- | :--- | :--- | :--- |
| **All Product Images** (cards, Quick View, PDP, cart, checkout thumbnails) | **`3:4` portrait (only)** | `1200 × 1600px` | Never `4:5` for products — one ratio keeps every grid aligned |
| Hero — Desktop | `4:3` | `1600 × 1200px` | Saree drape composed so full length is visible |
| Hero — Mobile | `4:5` | `1080 × 1350px` | Separate upload; no text over the saree |
| Category Cover (Shop by Weave) | `3:4` | `900 × 1200px` | |
| Spotlight Banner | `3:4` (×2 collage) | `900 × 1200px` each | |
| Customer Testimonial Photo | `4:5` | `1080 × 1350px` | Customer wearing the saree |
| Facebook / WhatsApp Share Image | `1.91:1` | `1200 × 630px` | See `reviews_chat_and_social_sharing_plan.md` |

### Product Photo Order (Every Saree)
1. **Image 1:** Front drape on model (default card image)
2. **Image 2:** Aanchal / Pallu close-up (card hover / 1st tap)
3. **Image 3:** Border (Paar) & weave texture macro
4. **Image 4:** Blouse piece (if included)
5. **Image 5:** Back / full-length view
6. **Image 6 (optional):** Styling / lifestyle shot

* Minimum 2 images per product (if only 1, the card uses a gentle `1.04×` zoom on hover/tap instead of sliding).
* **Format & Loading:** WebP preferred, lazy-load all below-the-fold images, show the warm shimmer placeholder while loading.
* **Broken Image Fallback:** `--bg-surface` box with the brand logo text in `--text-muted`.
* **Alt Text:** `"[Product Title] — [Angle name]"` (e.g., "Crimson Dhakai Jamdani Saree — Aanchal close-up").

---

## 5. Responsive Product Slider Standard (Mobile-First)

Used everywhere a horizontal product row appears: "All Sarees" hub rows, Homepage New Arrivals & Most Loved, PDP Similar Sarees & Recently Viewed.

| Device | Visible Cards | Navigation | Indicator |
| :--- | :--- | :--- | :--- |
| **Mobile** `320–767px` | **2 full cards + ~10% peek of the next card** | Finger swipe with snap-to-card | **Slim progress bar** |
| **Tablet** `768–1024px` | **3 full cards + small peek** | Finger swipe with snap | **Slim progress bar** |
| **Desktop** `1025px+` | **4 cards** | Left/right arrow buttons + mouse drag | **3 dots** (Dot 1 = 1–4, Dot 2 = 5–8, Dot 3 = 9–12) |

### Why Mobile Uses a Progress Bar Instead of Dots
With 2 cards per view, 12 products would need 6 dots (or confusing 2-swipes-per-dot logic). A progress bar works for any product count and is the standard pattern on mobile fashion apps.

### Indicator Specs
* **Desktop Dots:** Centered below the row. Active = elongated pill (`24px × 8px`) in `--brand-primary`; inactive = `8px` circle in `--brand-accent`. Clicking a dot slides to that group. Dot count = `ceil(products ÷ 4)`; hidden if ≤ 4 products.
* **Desktop Arrows:** Circular icon buttons (`40px`) at the left/right edges of the row, vertically centered on the images. Hidden at the start/end of the row.
* **Touch Progress Bar:** Centered below the row, `120px` wide (mobile) / `160px` (tablet), `3px` tall. Track `--border-subtle`, moving thumb `--brand-primary`. Thumb width = visible ÷ total; position follows the scroll. Hidden if all products fit on screen.

### Mobile & Tablet "View All" End Card
* After the last product, a final card of the same size appears: `--bg-surface` background, `1px` `--border-subtle` border, centered text **"View All [Category Name] →"** in `--font-heading` H4 (`--brand-primary`) and a small count (`48 Sarees`, `--text-muted`).
* Tapping it opens the full listing page. *(Desktop uses the header "View All →" link only.)*

### Data Rule
* Maximum **12 products** per slider (newest in-stock first unless the section defines another order). Sold-out products never appear in sliders.

---

## 6. Standard Filter Taxonomy & Sorting (Single Source)

Used by Single Category pages, Collection pages, Quick View/PDP spec labels, and product data.

| Filter | Options (exact labels) |
| :--- | :--- |
| **Saree Type (Sub-Category)** | Jamdani · Muslin · Katan · Silk · Cotton · Tangail *(future: Georgette, Bridal)* |
| **Color Family** (with swatch dot) | Red · Maroon · Pink / Pastel · Yellow / Mustard · Green · Blue · White / Off-White · Black · Gold / Champagne · Multi-Color |
| **Price Range** | Under BDT 2,500 · BDT 2,500 – 4,999 · BDT 5,000 – 9,999 · BDT 10,000 & Above |
| **Blouse Piece** | With Blouse Piece · Without Blouse Piece |
| **Work / Pattern** | Handloom / Tant · Zari Work · Embroidered · Karchupi · Printed · Plain / Solid |
| **Occasion** | Casual / Daily · Office Wear · Festive / Eid · Party Wear · Bridal / Wedding |
| **Availability** | `In Stock Only` toggle |

**Price Bracket Logic (no overlap):** `< 2500` · `2500–4999` · `5000–9999` · `≥ 10000`.

**Sort Options:** Newest Arrivals *(default)* · Price: Low to High · Price: High to Low · Best Selling.

**Filter URL Rule:** Active filters & sort are stored in the page URL (e.g., `?price=2500-4999&color=red&sort=price-asc`) so filtered pages can be shared, bookmarked, and restored with the Back button.

**Zero-Result Protection:** Filter options with 0 matching products are hidden (or shown disabled) so shoppers never hit an empty grid by accident.

---

## 7. Price & Number Formatting
* Always: **`BDT 4,500`** — "BDT" + space + comma-separated whole number. No decimals, no "Tk", no "৳".
* Old price shown only when `oldPrice > price`, always with strikethrough.
* Discount shown as `− BDT 500` in cost breakdowns (in `--state-success`).
* Mobile numbers displayed as `01712-345678` style or plain `01712345678` (be consistent per page).

---

## 8. Purchase Action Rules (Site-Wide)

### A. `ADD TO CART` (anywhere)
1. Adds the item (selected quantity) to the bag. If already in the bag, increases its quantity (never above stock).
2. Closes the Quick View Modal if open.
3. **Opens the Right Slide-Out Cart Drawer** so the shopper sees confirmation and the path to checkout.
4. Updates the header cart counter badge.

### B. `ORDER NOW` — "Express Buy" (Minimal & User-Friendly)
1. Opens `/checkout` with **only this saree** (selected quantity). One tap → checkout, nothing else to decide.
2. **The shopping bag is NOT changed.** Items already in the bag stay saved.
3. **If the bag has other items**, the Order Summary shows a small info strip:
   * *"You also have 2 other sarees in your bag."* + text button **`+ Add them to this order`**.
   * Tapping it merges the bag items into this checkout in one tap (and the strip disappears).
4. If this same saree is already in the bag, Express Buy uses the quantity selected on the product, without duplicating it.
5. After a successful Express Buy order, only the ordered items are removed from the bag; untouched bag items remain.
6. The express item is remembered for the browser session so refreshing the checkout page doesn't lose it.

### C. `PROCEED TO CHECKOUT →` (from Cart Drawer)
* Opens `/checkout` with **all bag items**. After a successful order, the bag is emptied.

### D. Quantity Rules
* Minimum `1`, maximum = available stock. The `+` button disables at the stock limit, with helper text "Maximum available quantity reached" (`--text-muted`).

---

## 9. Form & Feedback States

### A. Input States
| State | Style |
| :--- | :--- |
| Default | Bg `--bg-main`, `1px` border `--border-subtle`, text `--text-primary`, placeholder `--text-muted`, height `48px` |
| Focus | `1.5px` border `--brand-primary` |
| Error | `1.5px` border `--state-error` + message below in `--state-error` (`13px`), e.g., "Please enter a valid 11-digit mobile number" |
| Valid (optional) | Small ✓ icon inside the right edge in `--state-success` |
| Disabled | Bg `--bg-surface`, text `--text-muted` |

* On submit with errors: smooth-scroll to the first error field and focus it.
* Labels always visible above inputs (never placeholder-only labels).

### B. Toast Notifications
* Position: bottom-center on mobile (above any sticky bar), top-right on desktop.
* Style: Bg `--bg-main`, `1px` border `--border-subtle`, `3px` left border in `--state-success` or `--state-error`, text `--text-primary`, auto-dismiss after `3s`.
* Used for: "Link copied ✓", "Review submitted ✓", network errors. *(Add to Cart uses the Cart Drawer, not a toast.)*

---

## 10. Empty, Loading & Error States
| Situation | What the Shopper Sees |
| :--- | :--- |
| **Empty bag** | "Your shopping bag is empty" (`--text-muted`) + Primary button `EXPLORE SAREES →` |
| **Filters return 0 results** | "No sarees match these filters." + Secondary button `CLEAR ALL FILTERS` |
| **Content loading** | Warm shimmer skeleton (`--bg-surface` base with a moving `--border-subtle` / `--bg-main` wave). Never grey, never spinners for content. |
| **Next batch fails to load** | "Couldn't load more sarees. Check your connection." + Secondary button `TRY AGAIN` |
| **Product page not found / removed** | 404 variant: "This saree is no longer available" + Similar Sarees slider |
| **Collection or category empty** | Its nav link, pill, and homepage card are hidden automatically |

---

## 11. Floating Elements & Layering Order

### A. Bottom-Right Floating Stack (never overlapping)
1. **Floating Chat Button** (WhatsApp/Messenger) — bottom-most position: `16px` from the bottom/right edges on mobile, `24px` on desktop.
2. **Back-to-Top Button** (listing pages only) — stacked **above** the chat button with a `12px` gap.
3. **When the PDP Mobile Sticky Order Bar is visible**, the whole stack moves up by the bar height (`64px`) + `12px`.

### B. Visibility Rules
* Floating chat & back-to-top **hide** while any modal, drawer, bottom sheet, or lightbox is open.
* Floating chat is **hidden on `/checkout` and the Order Received page** (help line shown inside checkout instead).

### C. Layer Order (lowest → highest)
Page content → Sticky header → Floating buttons → Mobile sticky order bar → Overlay backdrop → Modals / drawers / bottom sheets → Lightbox → Toasts.

---

## 12. Motion & Accessibility Basics
* Transitions: `200–300ms`, ease-out. Drawers/bottom sheets slide; modals fade + scale slightly.
* Respect the device "reduce motion" setting (disable auto-rotating hero & slide animations).
* Visible keyboard focus ring: `2px` outline in `--brand-primary`, `2px` offset.
* All icon-only buttons have text labels for screen readers (e.g., "Close", "Open menu", "Shopping bag, 2 items").
* `ESC` closes any overlay; focus returns to the element that opened it. Page scroll is locked while overlays are open.

