diff --git a/app/routes/app.bookings._index.tsx b/app/routes/app.bookings._index.tsx
index 3b67da3..7bf8341 100644
--- a/app/routes/app.bookings._index.tsx
+++ b/app/routes/app.bookings._index.tsx
@@ -43,7 +43,7 @@ export default function Bookings() {
Export CSV
- 1}>
+
Order
Date
@@ -113,7 +113,7 @@ export default function Bookings() {
{page > 1 && Previous}
- {total} bookings · page {page}
+ {total} booking{total === 1 ? "" : "s"}{total > 50 ? ` · page ${page}` : ""}
{page * 50 < total && Next}
diff --git a/brand/LISTING.md b/brand/LISTING.md
new file mode 100644
index 0000000..811bba1
--- /dev/null
+++ b/brand/LISTING.md
@@ -0,0 +1,74 @@
+# Datewise: App Store listing content
+
+Paste these into Partner Dashboard → Apps → Datewise: Delivery & Pickup → Distribution → App Store listing (English).
+Lengths are within Shopify's limits; check the counter in the form after pasting.
+
+## Basics
+
+- **App name:** Datewise: Delivery & Pickup *(must match `name` in shopify.app.toml)*
+- **App icon:** `brand/shopify/app-icon-1200x1200.png`
+- **App card subtitle:** Delivery and pickup dates and times, with slot limits
+- **Primary category:** Orders and shipping → Delivery and pickup
+- **Tags (suggested):** Delivery date, Store pickup, Local delivery, Time slots, Order scheduling
+
+## App introduction (≤100 characters)
+
+Let customers choose store pickup, local delivery or shipping, then a date and time, in the cart.
+
+## App details (≤500 characters)
+
+Datewise adds a scheduler to your cart. Customers pick a method, a location, a date and a time slot, and the place is held while they check out. You set opening hours, preparation time, cutoffs, holidays and orders per slot for each location. Rush days get their own limits, earlier cutoffs and a waitlist. Checkout requires a valid time on every Shopify plan, and the chosen time is shown on the order, in reminders and on the driver run sheet.
+
+## Feature list (each ≤80 characters)
+
+1. Store pickup, local delivery and shipping, each with its own hours and rules
+2. Time slots with order limits, held while the customer checks out
+3. Preparation time, same-day cutoffs, holidays and special opening hours
+4. Rush-day limits, earlier cutoffs and a waitlist for festivals and holidays
+5. Checkout requires a valid time on every plan, including Buy it now
+6. Customers reschedule from their order page; email, SMS and WhatsApp reminders
+7. Bookings list, daily capacity view, driver run sheets and CSV export
+
+## Search terms (5)
+
+1. delivery date
+2. store pickup
+3. delivery time slot
+4. local delivery scheduler
+5. order pickup date
+
+## Pricing (Billing API plans, shown in the app)
+
+- **Starter:** Free. 1 location, 50 scheduled orders a month.
+- **Growth:** $19/month, 14-day free trial. Up to 3 locations, unlimited orders, rush control and waitlist, fresh-stock windows, run sheets.
+- **Pro:** $49/month, 14-day free trial. Up to 50 locations, SMS and WhatsApp reminders, driving-distance zones.
+
+## Media
+
+- **Feature image (1600×900):** `brand/shopify/feature-image-1600x900.png`
+- **Screenshots (1600×900):** `brand/screenshots/listing/*.png`. Alt text for each is in `brand/screenshots/listing/alt-text.txt`.
+- **Screencast:** Unlisted YouTube URL *(record per the launch skill, Phase 9)*
+
+## URLs and contact
+
+- **Privacy policy:** https://datewise.metatronlabz.com/privacy
+- **Website:** https://datewise.metatronlabz.com
+- **Support email:** info@metatroncubesolutions.com
+- **Emergency contact:** set on the Partner account (Settings → Account)
+
+## App testing information (for the reviewer)
+
+No separate login: Datewise uses Shopify authentication.
+
+1. **Install** the app and open it from the store's Apps menu. The **Today** page shows a 3-step setup guide.
+2. **Locations & hours:** open a location, switch on **Taking bookings**, check the pickup hours and slots, and click **Save location**. For pickup at checkout, the setup guide links to Shopify's Local pickup settings for that location.
+3. **Theme:** in the setup guide, click **Add block to cart page** (opens the theme editor with the Delivery date & time block added), then **Save**. Click **Turn on app embed**, then **Save**.
+4. **Settings:** turn on the **Checkout guard**, **Show the chosen date and time at checkout**, and **Hide pay-in-person methods for shipped orders**.
+5. **Storefront:** add a product to the cart, open the cart, choose **Store pickup**, a highlighted date and a time. The confirmation shows the place is held for 10 minutes.
+6. **Checkout:** choose **Pickup**; the pickup option shows the chosen date and time. Try checking out without choosing a time: the checkout guard blocks it with a message. Complete a test order.
+7. **Admin:** **Bookings** lists the order with its date and time. The order in Shopify has the date and time attributes, the pickup line with the time, and Datewise tags.
+8. **Paid features:** Settings → Plan → choose Growth (test charge) to unlock Rush control and the waitlist.
+9. **Uninstall:** pending reminders stop; store data is deleted 48 hours later via shop/redact.
+
+- **Demo store URL:** https://veloxautomotive.myshopify.com
+- **Storefront password:** *(enter in the form yourself)*
diff --git a/brand/make_screenshots.py b/brand/make_screenshots.py
new file mode 100644
index 0000000..9e6a1b7
--- /dev/null
+++ b/brand/make_screenshots.py
@@ -0,0 +1,106 @@
+"""Turns raw screenshots into 1600x900 Shopify App Store listing images in the Datewise brand.
+
+Usage: python -I brand/make_screenshots.py
+Input: brand/screenshots/raw/-.(png|jpg) (browser screenshots; CROP below trims each one)
+Output: brand/screenshots/listing/-.png + alt-text.txt
+Rules (Shopify): 1600x900, no pricing, reviews or outcome claims on the image.
+"""
+from pathlib import Path
+
+from PIL import Image, ImageDraw, ImageFilter, ImageFont
+
+ROOT = Path(__file__).resolve().parent
+RAW = ROOT / "screenshots" / "raw"
+OUT = ROOT / "screenshots" / "listing"
+W, H = 1600, 900
+
+TEAL_DEEP = (4, 90, 81) # #045A51
+TEAL = (13, 107, 93) # #0D6B5D
+SAGE = (232, 242, 237) # #E8F2ED
+WASH = (20, 125, 110)
+
+# n: (title, subtitle, alt text)
+SHOTS = {
+ 1: ("Customers choose a time in the cart",
+ "Store pickup, local delivery or shipping, then a date and a time slot",
+ "Shopify cart page with the Datewise scheduler: store pickup selected, a calendar, time slots and a confirmation showing the time held"),
+ 2: ("Today's bookings at a glance",
+ "Bookings, capacity for the next 14 days and upcoming festival dates",
+ "Datewise Today page in the Shopify admin with booking counts and a 14-day capacity chart for a pickup location"),
+ 3: ("Hours, slots and limits for each location",
+ "Preparation time, cutoffs, bookable days and orders per slot",
+ "Location settings with pickup on, slot length, preparation time, same-day cutoff and orders per slot"),
+ 4: ("Every booking in one list",
+ "Filter by date, method and location, move a booking or export CSV",
+ "Bookings list with filters and a confirmed store pickup booking"),
+ 5: ("A valid time is required at checkout",
+ "Works on every Shopify plan, including Buy it now and express checkouts",
+ "Datewise settings with the checkout guard on, the date and time shown at checkout, and payment rules"),
+ 6: ("The chosen time stays with the order",
+ "Shown on the delivery line, in the order details and as order tags",
+ "Shopify order showing the pickup line with the chosen date and time, booking details and Datewise tags"),
+}
+
+FONT = Path.home() / "AppData/Local/Microsoft/Windows/Fonts/Inter-VariableFont_slnt,wght.ttf"
+
+
+def font(size, weight=400):
+ try:
+ f = ImageFont.truetype(str(FONT), size)
+ try:
+ axes = f.get_variation_axes()
+ f.set_variation_by_axes([weight] + [0] * (len(axes) - 1))
+ except Exception:
+ pass
+ return f
+ except OSError:
+ return ImageFont.truetype("C:/Windows/Fonts/segoeuib.ttf" if weight >= 600 else "C:/Windows/Fonts/segoeui.ttf", size)
+
+
+def background():
+ bg = Image.new("RGB", (W, H), TEAL_DEEP)
+ glow = Image.new("L", (W, H), 0)
+ ImageDraw.Draw(glow).ellipse((-520, -620, 900, 520), fill=80)
+ glow = glow.filter(ImageFilter.GaussianBlur(170))
+ return Image.composite(Image.new("RGB", (W, H), WASH), bg, glow)
+
+
+def compose(raw_path, title, subtitle):
+ bg = background()
+ d = ImageDraw.Draw(bg)
+ d.text((80, 60), title, font=font(52, 700), fill=(255, 255, 255))
+ d.text((82, 132), subtitle, font=font(27, 450), fill=SAGE)
+
+ shot = Image.open(raw_path).convert("RGB")
+ max_w, max_h = W - 160, H - 230
+ scale = min(max_w / shot.width, max_h / shot.height)
+ shot = shot.resize((round(shot.width * scale), round(shot.height * scale)), Image.LANCZOS)
+ x, y = (W - shot.width) // 2, 200
+ # shadow + rounded frame
+ shadow = Image.new("L", (W, H), 0)
+ ImageDraw.Draw(shadow).rounded_rectangle((x + 6, y + 18, x + shot.width + 6, y + shot.height + 18), 18, fill=120)
+ shadow = shadow.filter(ImageFilter.GaussianBlur(24))
+ bg = Image.composite(Image.new("RGB", (W, H), (2, 40, 36)), bg, shadow)
+ mask = Image.new("L", shot.size, 0)
+ ImageDraw.Draw(mask).rounded_rectangle((0, 0, shot.width - 1, shot.height - 1), 16, fill=255)
+ bg.paste(shot, (x, y), mask)
+ return bg
+
+
+def main():
+ OUT.mkdir(parents=True, exist_ok=True)
+ alt_lines = []
+ for raw in sorted(RAW.glob("*.*")):
+ n = int(raw.name.split("-", 1)[0])
+ if n not in SHOTS:
+ continue
+ title, subtitle, alt = SHOTS[n]
+ out = OUT / (raw.stem + ".png")
+ compose(raw, title, subtitle).save(out, optimize=True)
+ alt_lines.append(f"{out.name}: {alt}")
+ print("wrote", out.name)
+ (OUT / "alt-text.txt").write_text("\n".join(alt_lines) + "\n", encoding="utf-8")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/brand/screenshots/listing/1-cart.png b/brand/screenshots/listing/1-cart.png
new file mode 100644
index 0000000..0ef4a24
Binary files /dev/null and b/brand/screenshots/listing/1-cart.png differ
diff --git a/brand/screenshots/listing/2-today.png b/brand/screenshots/listing/2-today.png
new file mode 100644
index 0000000..48ce60f
Binary files /dev/null and b/brand/screenshots/listing/2-today.png differ
diff --git a/brand/screenshots/listing/3-location.png b/brand/screenshots/listing/3-location.png
new file mode 100644
index 0000000..4555f30
Binary files /dev/null and b/brand/screenshots/listing/3-location.png differ
diff --git a/brand/screenshots/listing/5-settings.png b/brand/screenshots/listing/5-settings.png
new file mode 100644
index 0000000..887c6e7
Binary files /dev/null and b/brand/screenshots/listing/5-settings.png differ
diff --git a/brand/screenshots/listing/alt-text.txt b/brand/screenshots/listing/alt-text.txt
new file mode 100644
index 0000000..c8c57fd
--- /dev/null
+++ b/brand/screenshots/listing/alt-text.txt
@@ -0,0 +1,4 @@
+1-cart.png: Shopify cart page with the Datewise scheduler: store pickup selected, a calendar, time slots and a confirmation showing the time held
+2-today.png: Datewise Today page in the Shopify admin with booking counts and a 14-day capacity chart for a pickup location
+3-location.png: Location settings with pickup on, slot length, preparation time, same-day cutoff and orders per slot
+5-settings.png: Datewise settings with the checkout guard on, the date and time shown at checkout, and payment rules
diff --git a/brand/screenshots/raw/1-cart.png b/brand/screenshots/raw/1-cart.png
new file mode 100644
index 0000000..29bfd7c
Binary files /dev/null and b/brand/screenshots/raw/1-cart.png differ
diff --git a/brand/screenshots/raw/2-today.png b/brand/screenshots/raw/2-today.png
new file mode 100644
index 0000000..ae95e3a
Binary files /dev/null and b/brand/screenshots/raw/2-today.png differ
diff --git a/brand/screenshots/raw/3-location.png b/brand/screenshots/raw/3-location.png
new file mode 100644
index 0000000..a85151d
Binary files /dev/null and b/brand/screenshots/raw/3-location.png differ
diff --git a/brand/screenshots/raw/5-settings.png b/brand/screenshots/raw/5-settings.png
new file mode 100644
index 0000000..00ab23d
Binary files /dev/null and b/brand/screenshots/raw/5-settings.png differ