# Changelog

## 3.0.0 — 2026-10-29 · Phase 1: Starlit Dunes design, own photography, wedding wording

- **Night-sky homepage.** The hero shows the owner's Milky Way photo blended into a night sky, with the dusk caravan
  photo rising from the bottom and golden dune lines. The headline "Listen to the *dunes*." (9 languages) has a
  faint echo and an Amazigh "Azul" (ⴰⵣⵓⵍ) greeting.
- **Constellation navigation.** The four sections (Tours, Desert Activities, Events & Celebrations, Camp) are four
  stars joined by a dotted line. Each is a real link with a live count (tours, activities). On phones they stack
  as a list under the buttons.
- **"Choose your star".** Four arched photo cards hang from a star line, on a gradient from night to sand that
  leads into the trip finder.
- **Night-sky mobile menu** on every page: a starry gradient, star dots, counts under each section, gold Plan Your
  Trip button and language pills.
- **No more 01–04 numbering** in the navigation, mobile menu, chapter labels, tour categories, activities list,
  starting points, camp highlights or wedding steps. Small glowing star dots replace it. Itinerary day numbers stay.
- **Own photography.** 39 of the owner's photos prepared and graded consistently (`tools/grade.py`); 29 now
  illustrate the homepage, 9 activities, the camp, the wedding page and 9 tours (`apply_own_photos`), 10 are kept
  for Phase 2. 54 third-party/Instagram
  files with unclear permission were not published (list in OWNER-ACTIONS.md).
- **Weddings reworded:** customizable and subject to confirmation, accommodation subject to availability,
  transfers on request, no promised facilities, vendors or inclusions ("What we can arrange").
- `tools/apply_updates.py` applies the wedding text and own photos to an existing database (replaces
  `apply_wedding.py`). `tools/prune_images.py` now keeps the owner's photos and anything the database uses; 3 unused
  stock photos removed.
- 36 automated tests (new: constellation links and arches in 3 languages, no section numbers on any page, wedding
  wording). Asset version `?v=4`.

## 2.3.0 — 2026-10-28 · Organic image styling and motion

- Soft rounded frames for all contained photos (cards and plan card 20–28 px, thumbnails 12–14 px; slightly
  smaller on phones); full-width hero photographs stay edge to edge.
- Moroccan-arch frames (round top, soft base) for the founder portrait, the camp collage and the activities photo
  stage.
- Entrance motion: photo frames and cards fade in and rise as they scroll into view, cards in a row arrive one after
  another; photos still downloading fade in when ready. Uses the CSS `translate` property so it never conflicts
  with hover effects.
- Hover (mouse devices only): frames lift 6 px with a warmer, deeper shadow while the photo zooms slowly to 106 %.
- Reduced-motion preference disables all of it. Asset version bumped (`?v=3`) so browsers load the new styles.

## 2.2.0 — 2026-10-28 · Weddings in the Merzouga Desert

- New published service, confirmed by the owner: **Weddings in the Merzouga Desert**, fully written in 9 languages
  (ceremony setting in the dunes, dinner and catering, live music, guest stay at Dune Echo Desert Camp with transfers).
- Dedicated event page layout (night palette): story, "What we organize", photo row, "How it works" in three steps,
  enquiry form with number of guests, WhatsApp, Service structured data without prices.
- Events page leads with weddings; homepage chapter 03 and the Events intro updated (no longer "in preparation").
- Private Romantic Dinner now uses the night-swing photo so the lantern path leads the wedding page.
- `tools/apply_wedding.py` publishes the wedding in an existing database; new installs get it from `init-db`.
- 35 automated tests (new: wedding page in 4 languages, enquiry with guest count, other 8 services still hidden).

## 2.1.0 — 2026-10-28 · Homepage closer to the selected reference

- Solid light header with the WhatsApp contact button, as in the reference design.
- New sunset-toned hero with a real Merzouga caravan photo (Andrea Cappiello, Unsplash License) and an
  "Explore the tours" call to action.
- Floating **trip finder** (destination · experience type · duration) that really works: `/<lang>/find/`
  lists matching published tours, activities or the camp. Unpublished items are never included.
- "Our most-loved journeys": four experience cards with photo, chip, place, length or group, and Request a Quote.
- Reassurance strip with four line icons (local team, private and tailor-made, personal reply, nothing to pay to
  ask — only facts the site already stated) beside a warm "Plan Your Trip" card with WhatsApp.
- The four numbered chapters, starting points, host story and reviews follow below.
- New interface strings in all 9 languages; one more test (34 in total).

## 2.0.0 — 2026-10-28 · Redesign and application rebuild

### What the audit found in the previous project (morocco-platform-step2.zip)
- A **static HTML site** generated by `tools/build.py`. There was no Flask application, no SQLite database, no admin
  dashboard, no server-side inquiry storage and no automated tests, contrary to the earlier report.
- 15 tour pages, 10 activity pages, 9 journal articles, a cancellation policy, homepage packages, 5 reviews.
- Interface text in 9 languages switched by JavaScript on the same URL (search engines saw English only); tour and
  activity bodies in English/French/Spanish only.
- 113 photos hot-linked from images.unsplash.com; Google Fonts loaded from Google.
- The quote form only opened WhatsApp; nothing was recorded.
- Some homepage and camp text advertised services that are on the unconfirmed list (romantic/honeymoon setups).

### Architecture (why the change)
The brief requires publishing states, an admin, persistent inquiries, backups and per-language URLs. None of these
can exist on a static site, so the site was rebuilt as a small Flask + SQLite application. **All existing content was
preserved** by importing it from the old pages (`tools/import_legacy.py` → `data/seed/legacy.json`), and every old
URL redirects (301) to its new address.

### Design
- New art direction: ivory sand and deep desert brown with a restrained terracotta; Cormorant Garamond display type
  with Jost text; recurring chapter numerals (01–04) and a hand-drawn dune-contour line as the visual signature.
- Each section has its own layout: cinematic homepage with four chapters; tours as an editorial "route ledger" per
  category; activities as an index whose large photo follows the list; activity pages as split heroes; events on a
  dark night palette; the camp as a collage with its own story; the planner as a three-step form beside a photograph.
- The existing logo was recoloured (ink and sand versions, favicon).
- Mobile designed separately: full-screen menu with language list, stacked layouts, 48 px touch targets.

### Content and business rules
- The 18 confirmed desert activities, in three groups, each with its own page in 9 languages. 8 are new.
- The 9 proposed event services are stored unpublished (*Pending Verification*), never public.
- Publishing workflow Draft → Pending Verification → Confirmed → Published, enforced on every public query, the
  sitemap, search, structured data and the API.
- No public prices: price fields, "price on request / per person" lines and a dollar fee in the policy were removed;
  internal price notes stay in the admin.
- Camp and homepage lines referring to unconfirmed services were removed or held.

### Features
- Localized routes for 9 languages, language switcher that keeps the current page, hreflang + x-default, canonical
  URLs, localized sitemap, robots.txt, JSON-LD (TravelAgency, TouristTrip, TouristAttraction, Campground, Article,
  BreadcrumbList; no offers, prices or ratings).
- Inquiry forms (Plan Your Trip, every tour, activity, camp, celebrations): server validation in the visitor's
  language, CSRF, honeypot, rate limit, duplicate detection, storage, thank-you page with optional prefilled WhatsApp
  hand-off that states clearly that nothing is sent until the visitor presses send.
- WhatsApp links prefilled per page and language with the verified number +212 620 777 564.
- Admin: dashboard, content editor per language, publishing, archive, previews, categories, destinations, starting
  points, journal, image library with upload and licence fields, interface translation overrides, reviews, inquiries
  (status, notes, CSV export, deletion), users and roles, backups/restore, activity log.
- Security: hashed passwords, login rate limiting, session invalidation on password change, CSP and security
  headers, no-store on admin pages, hashed IPs only, upload validation, path checks on media and backups.
- Performance: self-hosted fonts and photos, responsive WebP (480/960/1600), lazy loading, fixed image dimensions,
  long cache on static files, no third-party requests.
- 33 automated tests.
