diff --git a/package.json b/package.json
index 095a4e0..31a0293 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,8 @@
"annotate": "node docs/annotate-all.mjs",
"images:populate": "bash scripts/populate-site-images.sh",
"images:fish": "bash scripts/update-fish-images.sh",
- "images:brand": "bash -c '.venv-images/bin/python scripts/process-all-site-images.py 2>/dev/null || python3 scripts/process-all-site-images.py'"
+ "images:brand": "bash -c '.venv-images/bin/python scripts/process-all-site-images.py 2>/dev/null || python3 scripts/process-all-site-images.py'",
+ "images:optimize": "bash -c '.venv-images/bin/python scripts/optimize-site-images.py 2>/dev/null || python3 scripts/optimize-site-images.py'"
},
"dependencies": {
"clsx": "^2.1.0",
diff --git a/public/images/site/_originals/about.jpg b/public/images/site/_originals/about.jpg
new file mode 100644
index 0000000..00cbc70
Binary files /dev/null and b/public/images/site/_originals/about.jpg differ
diff --git a/public/images/site/_originals/beef-boneless.jpg b/public/images/site/_originals/beef-boneless.jpg
new file mode 100644
index 0000000..7286687
Binary files /dev/null and b/public/images/site/_originals/beef-boneless.jpg differ
diff --git a/public/images/site/_originals/beef-mince.jpg b/public/images/site/_originals/beef-mince.jpg
new file mode 100644
index 0000000..68a15cf
Binary files /dev/null and b/public/images/site/_originals/beef-mince.jpg differ
diff --git a/public/images/site/_originals/beef-nihari-2.jpg b/public/images/site/_originals/beef-nihari-2.jpg
new file mode 100644
index 0000000..72b4ea9
Binary files /dev/null and b/public/images/site/_originals/beef-nihari-2.jpg differ
diff --git a/public/images/site/_originals/beef-nihari.jpg b/public/images/site/_originals/beef-nihari.jpg
new file mode 100644
index 0000000..72b4ea9
Binary files /dev/null and b/public/images/site/_originals/beef-nihari.jpg differ
diff --git a/public/images/site/_originals/beef-steak-2.jpg b/public/images/site/_originals/beef-steak-2.jpg
new file mode 100644
index 0000000..b1f2c21
Binary files /dev/null and b/public/images/site/_originals/beef-steak-2.jpg differ
diff --git a/public/images/site/_originals/beef-steak.jpg b/public/images/site/_originals/beef-steak.jpg
new file mode 100644
index 0000000..b1f2c21
Binary files /dev/null and b/public/images/site/_originals/beef-steak.jpg differ
diff --git a/public/images/site/_originals/category-beef.jpg b/public/images/site/_originals/category-beef.jpg
new file mode 100644
index 0000000..7286687
Binary files /dev/null and b/public/images/site/_originals/category-beef.jpg differ
diff --git a/public/images/site/_originals/category-chicken.jpg b/public/images/site/_originals/category-chicken.jpg
new file mode 100644
index 0000000..3119be2
Binary files /dev/null and b/public/images/site/_originals/category-chicken.jpg differ
diff --git a/public/images/site/_originals/category-fish.jpg b/public/images/site/_originals/category-fish.jpg
new file mode 100644
index 0000000..80ec1f3
Binary files /dev/null and b/public/images/site/_originals/category-fish.jpg differ
diff --git a/public/images/site/_originals/category-lamb.jpg b/public/images/site/_originals/category-lamb.jpg
new file mode 100644
index 0000000..7ebfbf7
Binary files /dev/null and b/public/images/site/_originals/category-lamb.jpg differ
diff --git a/public/images/site/_originals/chicken-breast copy.jpg b/public/images/site/_originals/chicken-breast copy.jpg
new file mode 100644
index 0000000..c4110ee
Binary files /dev/null and b/public/images/site/_originals/chicken-breast copy.jpg differ
diff --git a/public/images/site/_originals/chicken-breast-2.jpg b/public/images/site/_originals/chicken-breast-2.jpg
new file mode 100644
index 0000000..e63fa49
Binary files /dev/null and b/public/images/site/_originals/chicken-breast-2.jpg differ
diff --git a/public/images/site/_originals/chicken-breast.jpg b/public/images/site/_originals/chicken-breast.jpg
new file mode 100644
index 0000000..e63fa49
Binary files /dev/null and b/public/images/site/_originals/chicken-breast.jpg differ
diff --git a/public/images/site/_originals/chicken-thighs.jpg b/public/images/site/_originals/chicken-thighs.jpg
new file mode 100644
index 0000000..74cae3b
Binary files /dev/null and b/public/images/site/_originals/chicken-thighs.jpg differ
diff --git a/public/images/site/_originals/chicken-whole-1.jpg b/public/images/site/_originals/chicken-whole-1.jpg
new file mode 100644
index 0000000..1309d47
Binary files /dev/null and b/public/images/site/_originals/chicken-whole-1.jpg differ
diff --git a/public/images/site/_originals/chicken-whole-2.jpg b/public/images/site/_originals/chicken-whole-2.jpg
new file mode 100644
index 0000000..1309d47
Binary files /dev/null and b/public/images/site/_originals/chicken-whole-2.jpg differ
diff --git a/public/images/site/_originals/chicken-whole.jpg b/public/images/site/_originals/chicken-whole.jpg
new file mode 100644
index 0000000..1309d47
Binary files /dev/null and b/public/images/site/_originals/chicken-whole.jpg differ
diff --git a/public/images/site/_originals/chicken-wings.jpg b/public/images/site/_originals/chicken-wings.jpg
new file mode 100644
index 0000000..8429377
Binary files /dev/null and b/public/images/site/_originals/chicken-wings.jpg differ
diff --git a/public/images/site/_originals/fish-basa.jpg b/public/images/site/_originals/fish-basa.jpg
new file mode 100644
index 0000000..d6a301d
Binary files /dev/null and b/public/images/site/_originals/fish-basa.jpg differ
diff --git a/public/images/site/_originals/fish-prawns.jpg b/public/images/site/_originals/fish-prawns.jpg
new file mode 100644
index 0000000..779efbb
Binary files /dev/null and b/public/images/site/_originals/fish-prawns.jpg differ
diff --git a/public/images/site/_originals/fish-rohu.jpg b/public/images/site/_originals/fish-rohu.jpg
new file mode 100644
index 0000000..3371998
Binary files /dev/null and b/public/images/site/_originals/fish-rohu.jpg differ
diff --git a/public/images/site/_originals/fish-salmon-2.jpg b/public/images/site/_originals/fish-salmon-2.jpg
new file mode 100644
index 0000000..97edff6
Binary files /dev/null and b/public/images/site/_originals/fish-salmon-2.jpg differ
diff --git a/public/images/site/_originals/fish-salmon.jpg b/public/images/site/_originals/fish-salmon.jpg
new file mode 100644
index 0000000..41585ad
Binary files /dev/null and b/public/images/site/_originals/fish-salmon.jpg differ
diff --git a/public/images/site/_originals/hero.jpg b/public/images/site/_originals/hero.jpg
new file mode 100644
index 0000000..392e164
Binary files /dev/null and b/public/images/site/_originals/hero.jpg differ
diff --git a/public/images/site/_originals/lamb-chops.jpg b/public/images/site/_originals/lamb-chops.jpg
new file mode 100644
index 0000000..6e5910b
Binary files /dev/null and b/public/images/site/_originals/lamb-chops.jpg differ
diff --git a/public/images/site/_originals/lamb-leg copy.jpg b/public/images/site/_originals/lamb-leg copy.jpg
new file mode 100644
index 0000000..41fda1f
Binary files /dev/null and b/public/images/site/_originals/lamb-leg copy.jpg differ
diff --git a/public/images/site/_originals/lamb-leg.jpg b/public/images/site/_originals/lamb-leg.jpg
new file mode 100644
index 0000000..41fda1f
Binary files /dev/null and b/public/images/site/_originals/lamb-leg.jpg differ
diff --git a/public/images/site/_originals/lamb-mince.jpg b/public/images/site/_originals/lamb-mince.jpg
new file mode 100644
index 0000000..68a15cf
Binary files /dev/null and b/public/images/site/_originals/lamb-mince.jpg differ
diff --git a/public/images/site/_originals/lamb-shoulder-2.jpg b/public/images/site/_originals/lamb-shoulder-2.jpg
new file mode 100644
index 0000000..7ebfbf7
Binary files /dev/null and b/public/images/site/_originals/lamb-shoulder-2.jpg differ
diff --git a/public/images/site/_originals/lamb-shoulder.jpg b/public/images/site/_originals/lamb-shoulder.jpg
new file mode 100644
index 0000000..7ebfbf7
Binary files /dev/null and b/public/images/site/_originals/lamb-shoulder.jpg differ
diff --git a/public/images/site/_originals/weekly-offers.jpg b/public/images/site/_originals/weekly-offers.jpg
new file mode 100644
index 0000000..392e164
Binary files /dev/null and b/public/images/site/_originals/weekly-offers.jpg differ
diff --git a/public/images/site/about.jpg b/public/images/site/about.jpg
index 00cbc70..a0246fb 100644
Binary files a/public/images/site/about.jpg and b/public/images/site/about.jpg differ
diff --git a/public/images/site/beef-boneless.jpg b/public/images/site/beef-boneless.jpg
index 7286687..6403650 100644
Binary files a/public/images/site/beef-boneless.jpg and b/public/images/site/beef-boneless.jpg differ
diff --git a/public/images/site/beef-mince.jpg b/public/images/site/beef-mince.jpg
index 68a15cf..9fa7d10 100644
Binary files a/public/images/site/beef-mince.jpg and b/public/images/site/beef-mince.jpg differ
diff --git a/public/images/site/beef-nihari-2.jpg b/public/images/site/beef-nihari-2.jpg
index 72b4ea9..b833eae 100644
Binary files a/public/images/site/beef-nihari-2.jpg and b/public/images/site/beef-nihari-2.jpg differ
diff --git a/public/images/site/beef-nihari.jpg b/public/images/site/beef-nihari.jpg
index 72b4ea9..b833eae 100644
Binary files a/public/images/site/beef-nihari.jpg and b/public/images/site/beef-nihari.jpg differ
diff --git a/public/images/site/beef-steak-2.jpg b/public/images/site/beef-steak-2.jpg
index b1f2c21..739cbce 100644
Binary files a/public/images/site/beef-steak-2.jpg and b/public/images/site/beef-steak-2.jpg differ
diff --git a/public/images/site/beef-steak.jpg b/public/images/site/beef-steak.jpg
index b1f2c21..739cbce 100644
Binary files a/public/images/site/beef-steak.jpg and b/public/images/site/beef-steak.jpg differ
diff --git a/public/images/site/category-beef.jpg b/public/images/site/category-beef.jpg
index 7286687..6403650 100644
Binary files a/public/images/site/category-beef.jpg and b/public/images/site/category-beef.jpg differ
diff --git a/public/images/site/category-chicken.jpg b/public/images/site/category-chicken.jpg
index 3119be2..55579ce 100644
Binary files a/public/images/site/category-chicken.jpg and b/public/images/site/category-chicken.jpg differ
diff --git a/public/images/site/category-fish.jpg b/public/images/site/category-fish.jpg
index 80ec1f3..4281564 100644
Binary files a/public/images/site/category-fish.jpg and b/public/images/site/category-fish.jpg differ
diff --git a/public/images/site/category-lamb.jpg b/public/images/site/category-lamb.jpg
index 7ebfbf7..2aef5c2 100644
Binary files a/public/images/site/category-lamb.jpg and b/public/images/site/category-lamb.jpg differ
diff --git a/public/images/site/chicken-breast-2.jpg b/public/images/site/chicken-breast-2.jpg
index e63fa49..5df2269 100644
Binary files a/public/images/site/chicken-breast-2.jpg and b/public/images/site/chicken-breast-2.jpg differ
diff --git a/public/images/site/chicken-breast.jpg b/public/images/site/chicken-breast.jpg
index e63fa49..5df2269 100644
Binary files a/public/images/site/chicken-breast.jpg and b/public/images/site/chicken-breast.jpg differ
diff --git a/public/images/site/chicken-thighs.jpg b/public/images/site/chicken-thighs.jpg
index 74cae3b..d6c64d6 100644
Binary files a/public/images/site/chicken-thighs.jpg and b/public/images/site/chicken-thighs.jpg differ
diff --git a/public/images/site/chicken-whole-2.jpg b/public/images/site/chicken-whole-2.jpg
index 1309d47..f2168fa 100644
Binary files a/public/images/site/chicken-whole-2.jpg and b/public/images/site/chicken-whole-2.jpg differ
diff --git a/public/images/site/chicken-whole.jpg b/public/images/site/chicken-whole.jpg
index 1309d47..f2168fa 100644
Binary files a/public/images/site/chicken-whole.jpg and b/public/images/site/chicken-whole.jpg differ
diff --git a/public/images/site/chicken-wings.jpg b/public/images/site/chicken-wings.jpg
index 8429377..2befd78 100644
Binary files a/public/images/site/chicken-wings.jpg and b/public/images/site/chicken-wings.jpg differ
diff --git a/public/images/site/fish-basa.jpg b/public/images/site/fish-basa.jpg
index d6a301d..8ee5ddd 100644
Binary files a/public/images/site/fish-basa.jpg and b/public/images/site/fish-basa.jpg differ
diff --git a/public/images/site/fish-prawns.jpg b/public/images/site/fish-prawns.jpg
index 779efbb..dd499c1 100644
Binary files a/public/images/site/fish-prawns.jpg and b/public/images/site/fish-prawns.jpg differ
diff --git a/public/images/site/fish-rohu.jpg b/public/images/site/fish-rohu.jpg
index 3371998..d886f50 100644
Binary files a/public/images/site/fish-rohu.jpg and b/public/images/site/fish-rohu.jpg differ
diff --git a/public/images/site/fish-salmon-2.jpg b/public/images/site/fish-salmon-2.jpg
index 97edff6..29906a6 100644
Binary files a/public/images/site/fish-salmon-2.jpg and b/public/images/site/fish-salmon-2.jpg differ
diff --git a/public/images/site/fish-salmon.jpg b/public/images/site/fish-salmon.jpg
index 41585ad..a97e136 100644
Binary files a/public/images/site/fish-salmon.jpg and b/public/images/site/fish-salmon.jpg differ
diff --git a/public/images/site/hero.jpg b/public/images/site/hero.jpg
index 392e164..61b283c 100644
Binary files a/public/images/site/hero.jpg and b/public/images/site/hero.jpg differ
diff --git a/public/images/site/lamb-chops.jpg b/public/images/site/lamb-chops.jpg
index 6e5910b..4ea6e57 100644
Binary files a/public/images/site/lamb-chops.jpg and b/public/images/site/lamb-chops.jpg differ
diff --git a/public/images/site/lamb-leg.jpg b/public/images/site/lamb-leg.jpg
index 41fda1f..f7de4be 100644
Binary files a/public/images/site/lamb-leg.jpg and b/public/images/site/lamb-leg.jpg differ
diff --git a/public/images/site/lamb-mince.jpg b/public/images/site/lamb-mince.jpg
index 68a15cf..9fa7d10 100644
Binary files a/public/images/site/lamb-mince.jpg and b/public/images/site/lamb-mince.jpg differ
diff --git a/public/images/site/lamb-shoulder-2.jpg b/public/images/site/lamb-shoulder-2.jpg
index 7ebfbf7..2aef5c2 100644
Binary files a/public/images/site/lamb-shoulder-2.jpg and b/public/images/site/lamb-shoulder-2.jpg differ
diff --git a/public/images/site/lamb-shoulder.jpg b/public/images/site/lamb-shoulder.jpg
index 7ebfbf7..2aef5c2 100644
Binary files a/public/images/site/lamb-shoulder.jpg and b/public/images/site/lamb-shoulder.jpg differ
diff --git a/public/images/site/weekly-offers.jpg b/public/images/site/weekly-offers.jpg
index 392e164..61b283c 100644
Binary files a/public/images/site/weekly-offers.jpg and b/public/images/site/weekly-offers.jpg differ
diff --git a/scripts/optimize-site-images.py b/scripts/optimize-site-images.py
new file mode 100644
index 0000000..2a09c70
--- /dev/null
+++ b/scripts/optimize-site-images.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python3
+"""Compress site images to <= 100 KB while preserving original colors."""
+
+from __future__ import annotations
+
+import argparse
+import io
+import shutil
+from pathlib import Path
+
+from PIL import Image
+
+ROOT = Path(__file__).resolve().parents[1]
+SITE = ROOT / "public" / "images" / "site"
+BACKUP = SITE / "_originals"
+SKIP = {"logo.jpeg", "README.txt"}
+SKIP_PATTERNS = (" copy", "-1.jpg")
+
+
+def should_skip(path: Path) -> bool:
+ if path.name in SKIP or path.name.startswith("_"):
+ return True
+ return any(p in path.name for p in SKIP_PATTERNS)
+
+
+def encode_jpeg(img: Image.Image, quality: int) -> bytes:
+ buf = io.BytesIO()
+ img.save(buf, format="JPEG", quality=quality, optimize=True, subsampling=2)
+ return buf.getvalue()
+
+
+def compress_to_target(img: Image.Image, max_bytes: int) -> tuple[Image.Image, int]:
+ working = img.convert("RGB")
+ scale = 1.0
+
+ while scale >= 0.35:
+ if scale < 1.0:
+ w, h = working.size
+ nw, nh = max(1, int(w * scale)), max(1, int(h * scale))
+ candidate = working.resize((nw, nh), Image.Resampling.LANCZOS)
+ else:
+ candidate = working
+
+ lo, hi = 20, 92
+ best_q = lo
+ best_data = encode_jpeg(candidate, lo)
+
+ while lo <= hi:
+ mid = (lo + hi) // 2
+ data = encode_jpeg(candidate, mid)
+ if len(data) <= max_bytes:
+ best_q = mid
+ best_data = data
+ lo = mid + 1
+ else:
+ hi = mid - 1
+
+ if len(best_data) <= max_bytes:
+ return Image.open(io.BytesIO(best_data)).convert("RGB"), best_q
+
+ scale *= 0.88
+
+ data = encode_jpeg(candidate, 20)
+ return Image.open(io.BytesIO(data)).convert("RGB"), 20
+
+
+def optimize_file(path: Path, max_bytes: int, dry_run: bool) -> tuple[int, int]:
+ before = path.stat().st_size
+ if before <= max_bytes:
+ return before, before
+
+ with Image.open(path) as img:
+ out, quality = compress_to_target(img, max_bytes)
+
+ if dry_run:
+ buf = io.BytesIO()
+ out.save(buf, format="JPEG", quality=quality, optimize=True, subsampling=2)
+ return before, len(buf.getvalue())
+
+ out.save(path, format="JPEG", quality=quality, optimize=True, subsampling=2)
+ return before, path.stat().st_size
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser(description="Optimize site images to <= 100 KB")
+ parser.add_argument("--max-kb", type=int, default=100)
+ parser.add_argument("--dry-run", action="store_true")
+ args = parser.parse_args()
+
+ max_bytes = args.max_kb * 1024
+ BACKUP.mkdir(exist_ok=True)
+
+ files = sorted(SITE.glob("*.jpg")) + sorted(SITE.glob("*.jpeg"))
+ changed = 0
+
+ for path in files:
+ if should_skip(path):
+ continue
+
+ backup = BACKUP / path.name
+ if not backup.exists() and not args.dry_run:
+ shutil.copy2(path, backup)
+
+ before, after = optimize_file(path, max_bytes, args.dry_run)
+ if after < before or before > max_bytes:
+ changed += 1
+ print(
+ f"{'~' if args.dry_run else '✓'} {path.name}: "
+ f"{before // 1024} KB → {after // 1024} KB"
+ )
+ else:
+ print(f"○ {path.name}: {before // 1024} KB (ok)")
+
+ print(f"\nDone — {changed} optimized, originals in {BACKUP}")
+
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx
index 28970f8..9f4fb98 100644
--- a/src/app/about/page.tsx
+++ b/src/app/about/page.tsx
@@ -1,6 +1,7 @@
'use client';
import Link from 'next/link';
+import AboutIntro from '@/components/about/AboutIntro';
import { ShieldCheck, Leaf, Award, Truck, Phone, Mail, MapPin } from 'lucide-react';
import { useTranslation } from '@/hooks/useTranslation';
import {
@@ -25,6 +26,8 @@ export default function AboutPage() {
+
{t('aboutPreview.p2')}
{t('aboutPreview.p3')}
-- {t('contact.addressLabel')} -
-{SITE_ADDRESS}
-- {t('contact.phoneLabel')} -
- - {SITE_PHONE_DISPLAY} - -- {t('contact.hoursLabel')} -
-- {t('contact.hoursValue', { hours: SITE_HOURS })} -
-+ {t('contact.addressLabel')} +
+{SITE_ADDRESS}
+ {t('contact.phoneLabel')} +
+ + {SITE_PHONE_DISPLAY} + ++ {t('contact.hoursLabel')} +
++ {t('contact.hoursValue', { hours: SITE_HOURS })} +
+{t('site.name')}
-{SITE_ADDRESS}
-+ {t('social.label')} +
++ {badge.description} +
+{badge.description}
- +