{
  "formatVersion": "1.2",
  "currency": "EUR",
  "timezone": "Europe/Paris",
  "id": "demo-flanders-amsterdam",
  "name": "Flanders & Amsterdam — 4 days",
  "subtitle": "Lille, Bruges, Amsterdam · a family road trip by electric car",
  "start": "2026-10-23",
  "end": "2026-10-26",
  "cover": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8f/Rozenhoedkaai.jpg/960px-Rozenhoedkaai.jpg",
  "members": [
    { "id": "m1", "name": "Alex", "role": "owner", "kind": "adult", "dietary": ["vegetarian"] },
    { "id": "m2", "name": "Sam", "role": "editor", "kind": "adult" },
    { "id": "m3", "name": "Léo", "role": "viewer", "kind": "teen", "age": 13 },
    { "id": "m4", "name": "Mia", "role": "viewer", "kind": "child", "age": 9, "surpriseMode": "day" }
  ],
  "vehicles": [
    { "id": "v1", "name": "Family EV", "kind": "car", "energy": "electric", "note": "≈ 380 km real range · CCS fast charging" }
  ],
  "people": [
    {
      "id": "p1",
      "name": "Jonas",
      "role": "guide",
      "org": "Bruges by Foot",
      "languages": ["nl", "en", "fr"],
      "phone": "+32 470 00 00 00",
      "sign": "Blue umbrella, in front of the Belfry entrance",
      "note": "2-hour family walk — booked through the tourist office. Confirms the day before by WhatsApp."
    },
    {
      "id": "p2",
      "name": "Bike rental desk — MacBike Centraal",
      "role": "contact",
      "org": "MacBike",
      "languages": ["nl", "en"],
      "note": "Ask for a kids' bike (24\") and a bike seat is not needed. Bring ID."
    }
  ],
  "days": [
    {
      "id": "d1",
      "index": 1,
      "date": "2026-10-23",
      "title": "Paris → Lille",
      "intro": "Easy first leg on the A1. Afternoon up the belfry, waffles at Méert, and a stroll through Old Lille before dinner.",
      "stayBookingId": "b-lille",
      "route": { "km": 225, "drive": "2h30", "charge": "None needed — charge to 100 % at home the night before", "vehicleId": "v1" },
      "coords": { "lat": 50.6367, "lon": 3.0633, "label": "Lille" },
      "tip": "Park at Q-Park Grand-Place (underground, 200 m from the hotel) — cheaper with the hotel's evening code.",
      "planB": "Rainy day: La Piscine museum in Roubaix (art-deco swimming pool turned museum, 20 min by metro) instead of the belfry.",
      "items": [
        {
          "id": "d1i1", "time": "09:30", "title": "Leave Paris", "type": "drive", "status": "planned",
          "desc": "A1 northbound. Coffee stop halfway if needed (Aire d'Assevillers).",
          "transport": { "vehicleId": "v1", "from": { "name": "Paris" }, "to": { "name": "Lille", "coords": { "lat": 50.6367, "lon": 3.0633 } } }
        },
        {
          "id": "d1i2", "time": "12:30", "title": "Lunch — Old Lille", "type": "meal", "status": "planned",
          "place": "Rue de la Monnaie, Lille", "coords": { "lat": 50.6398, "lon": 3.0632 },
          "options": [
            { "id": "d1o1", "title": "T'Rijsel", "desc": "Flemish estaminet — welsh, carbonnade, kids' plates.", "place": "25 rue de Gand, Lille" },
            { "id": "d1o2", "title": "La Chicorée", "desc": "Brasserie open all afternoon, easy with children.", "place": "15 place Rihour, Lille" }
          ]
        },
        {
          "id": "d1i3", "time": "14:00", "title": "Check-in — Hotel L'Arbre Voyageur", "type": "checkin", "status": "planned",
          "bookingId": "b-lille", "place": "45 boulevard Carnot, Lille"
        },
        {
          "id": "d1i4", "time": "15:00", "endTime": "16:00", "title": "Climb the Lille Belfry", "type": "heritage", "stars": 2, "status": "planned",
          "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Beffroi_de_Lille.jpg/960px-Beffroi_de_Lille.jpg",
          "place": "Place Roger Salengro, Lille", "coords": { "lat": 50.6318, "lon": 3.0637 },
          "desc": "104 m, tallest belfry in France. Lift for the first 100 steps, then ~300 steps on foot. Great view over Flanders.",
          "price": 24, "priceEstimated": true, "outfit": ["sport"],
          "critical": "Last ascent 30 min before closing (17:30 in October).",
          "alternatives": [
            { "id": "d1a1", "trigger": "closure", "title": "Vieille Bourse courtyard", "desc": "Second-hand book market and chess players in the 17th-century exchange." }
          ]
        },
        {
          "id": "d1i5", "time": "16:30", "title": "Waffles at Méert", "type": "meal", "stars": 1, "status": "planned",
          "place": "27 rue Esquermoise, Lille", "coords": { "lat": 50.6389, "lon": 3.0620 },
          "desc": "Vanilla-cream waffle, an institution since 1761 — expect a queue, it moves fast.",
          "menuUrl": "https://www.meert.fr", "price": 18, "priceEstimated": true
        },
        {
          "id": "d1i6", "time": "17:00", "title": "Old Lille walk", "type": "activity", "status": "planned",
          "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/Vieille_Bourse_Lille.jpg/960px-Vieille_Bourse_Lille.jpg",
          "place": "Grand'Place, Lille", "coords": { "lat": 50.6367, "lon": 3.0633 },
          "desc": "Grand'Place → Vieille Bourse → rue de la Monnaie → Notre-Dame-de-la-Treille. Flemish façades, cobbles, chocolate shops.",
          "outfit": ["casual", "warm"]
        },
        {
          "id": "d1i7", "time": "19:30", "title": "Dinner", "type": "meal", "status": "planned",
          "options": [
            { "id": "d1o3", "title": "Estaminet Chez la Vieille", "desc": "Potjevleesch, carbonnade — book ahead.", "place": "60 rue de Gand, Lille", "menuUrl": "https://www.estaminetlille.fr" },
            { "id": "d1o4", "title": "Le Barbier qui Fume", "desc": "Smoked meats, big portions, relaxed.", "place": "69 rue de la Monnaie, Lille" }
          ]
        },
        { "id": "d1i8", "time": "21:30", "title": "Grand'Place by night", "type": "free", "status": "planned", "desc": "The illuminated Vieille Bourse and Column of the Goddess — 15 minutes, then bed." },
        { "id": "d1i9", "title": "Night in Lille", "type": "night", "status": "planned", "bookingId": "b-lille" }
      ]
    },
    {
      "id": "d2",
      "index": 2,
      "date": "2026-10-24",
      "title": "Lille → Bruges",
      "intro": "One hour and a half to Bruges. Canal cruise, chocolate, belfry and the Beguinage — the medieval city is best on foot and by boat.",
      "stayBookingId": "b-bruges",
      "route": { "km": 110, "drive": "1h30", "charge": "None — plenty of range left", "vehicleId": "v1" },
      "coords": { "lat": 51.2085, "lon": 3.2245, "label": "Bruges" },
      "tip": "The historic centre is car-free: park at Centrum 't Zand (underground, ~€3.50/24 h) — free shuttle to the Markt.",
      "planB": "Rain all day: Historium (immersive museum, Markt) + Choco-Story (chocolate museum) instead of the cruise and the belfry.",
      "items": [
        { "id": "d2i1", "time": "08:30", "title": "Breakfast at the hotel", "type": "meal", "status": "planned", "desc": "Included — buffet from 7:00." },
        {
          "id": "d2i2", "time": "10:00", "title": "Check-out & drive to Bruges", "type": "drive", "status": "planned",
          "bookingId": "b-lille",
          "transport": { "vehicleId": "v1", "from": { "name": "Lille" }, "to": { "name": "Bruges — Centrum 't Zand car park", "coords": { "lat": 51.2049, "lon": 3.2170 } } }
        },
        {
          "id": "d2i3", "time": "11:45", "title": "Drop the bags — Hotel Ter Brughe", "type": "checkin", "status": "planned",
          "bookingId": "b-bruges", "place": "Oost-Gistelhof 2, Brugge", "desc": "Rooms from 15:00; luggage storage at reception."
        },
        {
          "id": "d2i4", "time": "12:30", "title": "Lunch on the Markt", "type": "meal", "status": "planned",
          "place": "Markt, Brugge", "coords": { "lat": 51.2085, "lon": 3.2245 },
          "options": [
            { "id": "d2o1", "title": "Frituur Chez Vincent", "desc": "Proper Belgian fries, mussels, kids love it.", "place": "Sint-Salvatorskerkhof 1, Brugge" },
            { "id": "d2o2", "title": "De Halve Maan brewery", "desc": "Brasserie of the last family brewery in the centre; terrace.", "place": "Walplein 26, Brugge", "menuUrl": "https://www.halvemaan.be" }
          ]
        },
        {
          "id": "d2i5", "time": "14:00", "endTime": "14:30", "title": "Canal boat tour", "type": "boat", "stars": 3, "status": "planned",
          "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/99/Bruges_canal.jpg/960px-Bruges_canal.jpg",
          "place": "Huidenvettersplein, Brugge", "coords": { "lat": 51.2072, "lon": 3.2266 },
          "bookingId": "b-boat", "outfit": ["casual", "windproof"],
          "desc": "30 minutes on the Reien: Rozenhoedkaai, the Beguinage bridge, the Church of Our Lady from the water.",
          "critical": "Boats leave every 20 min until 18:00 — be at the jetty 10 min early.",
          "alternatives": [
            { "id": "d2a1", "trigger": "rain", "title": "Boat with covered deck", "desc": "Most boats have a retractable roof — cruise usually goes ahead." },
            { "id": "d2a2", "trigger": "wind", "windThreshold": 60, "title": "Groeninge Museum", "desc": "Flemish Primitives, 45 minutes indoors." }
          ]
        },
        {
          "id": "d2i6", "time": "15:00", "endTime": "17:00", "title": "Family walk with a local guide", "type": "activity", "stars": 2, "status": "planned",
          "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Belfry_of_Bruges.jpg/960px-Belfry_of_Bruges.jpg",
          "place": "Markt 7 (Belfry entrance), Brugge", "coords": { "lat": 51.2083, "lon": 3.2247 },
          "personIds": ["p1"], "bookingId": "b-walk",
          "desc": "Belfry, Burg square, the hidden courtyards, ends at the Beguinage. Kid-friendly stories, treasure-hunt questions for Mia."
        },
        {
          "id": "d2i7", "time": "17:15", "title": "Beguinage & Minnewater", "type": "nature", "stars": 1, "status": "planned",
          "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/af/Begijnhof_Brugge.jpg/960px-Begijnhof_Brugge.jpg",
          "place": "Begijnhof, Brugge", "coords": { "lat": 51.2020, "lon": 3.2225 },
          "desc": "UNESCO beguinage (silence inside), then the Lake of Love and its swans. Golden-hour photos."
        },
        {
          "id": "d2i8", "time": "18:15", "title": "Chocolate stop", "type": "shopping", "status": "planned",
          "options": [
            { "id": "d2o3", "title": "The Chocolate Line", "desc": "Dominique Persoone — wild flavours (bacon, cola…).", "place": "Simon Stevinplein 19, Brugge" },
            { "id": "d2o4", "title": "Chocolatier Dumon", "desc": "Tiny family shop, classic pralines.", "place": "Eiermarkt 6, Brugge" }
          ]
        },
        {
          "id": "d2i9", "time": "19:30", "title": "Dinner", "type": "meal", "status": "planned",
          "options": [
            { "id": "d2o5", "title": "De Bottelier", "desc": "Cosy, seasonal, vegetarian options — book.", "place": "Sint-Jakobsstraat 63, Brugge" },
            { "id": "d2o6", "title": "'t Zwart Huis", "desc": "Flemish stew in a 15th-century house.", "place": "Kuipersstraat 23, Brugge" }
          ]
        },
        {
          "id": "d2i10", "time": "21:15", "title": "Illuminated canals", "type": "viewpoint", "status": "planned",
          "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8f/Rozenhoedkaai.jpg/960px-Rozenhoedkaai.jpg",
          "place": "Rozenhoedkaai, Brugge", "coords": { "lat": 51.2077, "lon": 3.2270 },
          "desc": "Rozenhoedkaai → Groenerei → Burg. Bruges at night is the postcard.", "outfit": ["warm"]
        },
        { "id": "d2i11", "title": "Night in Bruges", "type": "night", "status": "planned", "bookingId": "b-bruges" }
      ]
    },
    {
      "id": "d3",
      "index": 3,
      "date": "2026-10-25",
      "title": "Bruges → Amsterdam",
      "intro": "Belfry at opening time, then the long leg to Amsterdam with a fast-charge lunch near Antwerp. Bikes and NEMO in the afternoon.",
      "stayBookingId": "b-ams",
      "route": { "km": 255, "drive": "2h50", "charge": "Fastned Antwerpen-Zuid — 20 min while eating (CCS 300 kW)", "vehicleId": "v1" },
      "coords": { "lat": 52.3731, "lon": 4.8926, "label": "Amsterdam" },
      "tip": "Amsterdam has a low-emission zone and very expensive street parking: go straight to the hotel's car park (Oosterdok) and leave the car there until Monday.",
      "planB": "If the belfry slot is missed: Historium (Markt 1) opens at 10:00 — 1 hour, no queue in autumn.",
      "items": [
        {
          "id": "d3i1", "time": "09:30", "endTime": "10:15", "title": "Climb the Belfry of Bruges", "type": "heritage", "stars": 3, "status": "planned",
          "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Belfry_of_Bruges.jpg/960px-Belfry_of_Bruges.jpg",
          "place": "Markt 7, Brugge", "coords": { "lat": 51.2083, "lon": 3.2247 }, "bookingId": "b-belfry",
          "desc": "366 steps, 83 m, the carillon room halfway. Timed tickets — first slot of the day is the calmest.",
          "outfit": ["sport"], "critical": "Timed entry: arrive 10 min before the slot printed on the ticket."
        },
        { "id": "d3i2", "time": "10:45", "title": "Check-out Ter Brughe", "type": "checkout", "status": "planned", "bookingId": "b-bruges" },
        {
          "id": "d3i3", "time": "11:15", "title": "Drive Bruges → Amsterdam", "type": "drive", "status": "planned",
          "desc": "E40 → Antwerp ring → A16/A4 via Breda. Rush-hour free on a Sunday.",
          "transport": { "vehicleId": "v1", "from": { "name": "Bruges" }, "to": { "name": "Amsterdam — Centrum Oosterdok car park", "coords": { "lat": 52.3768, "lon": 4.9081 } } }
        },
        {
          "id": "d3i4", "time": "12:30", "endTime": "13:15", "title": "Fast charge + lunch — Antwerpen-Zuid", "type": "charging", "status": "planned",
          "place": "Fastned Antwerpen-Zuid, E19", "coords": { "lat": 51.1620, "lon": 4.3810 },
          "desc": "20 min at 300 kW gets ~250 km back. Sandwiches from the station shop or the picnic bag.", "price": 28, "priceEstimated": true
        },
        {
          "id": "d3i5", "time": "14:45", "title": "Park & check-in — DoubleTree Centraal", "type": "checkin", "status": "planned",
          "bookingId": "b-ams", "place": "Oosterdoksstraat 4, Amsterdam", "coords": { "lat": 52.3767, "lon": 4.9078 },
          "desc": "Car park Centrum Oosterdok is under the hotel; the parking ticket is in Bookings."
        },
        {
          "id": "d3i6", "time": "15:30", "title": "Rent bikes — MacBike Centraal", "type": "bike", "status": "planned",
          "place": "Stationsplein 5, Amsterdam", "coords": { "lat": 52.3782, "lon": 4.9003 }, "personIds": ["p2"],
          "desc": "4 city bikes incl. one 24\" kids' bike, until tomorrow 13:00. Helmets optional in NL; we take them.",
          "price": 64, "priceEstimated": true, "outfit": ["sport", "windproof"],
          "alternatives": [
            { "id": "d3a1", "trigger": "rain", "title": "GVB day pass (tram + ferry)", "desc": "Trams 2/12 do the same loop; free ferries behind Centraal for the kids." }
          ]
        },
        {
          "id": "d3i7", "time": "16:00", "endTime": "17:30", "title": "NEMO Science Museum", "type": "activity", "stars": 3, "status": "planned",
          "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/95/NEMO_Amsterdam.jpg/960px-NEMO_Amsterdam.jpg",
          "place": "Oosterdok 2, Amsterdam", "coords": { "lat": 52.3741, "lon": 4.9123 }, "bookingId": "b-nemo",
          "desc": "Five floors of hands-on science; the chain-reaction show at 15:00 and 17:00. Rooftop terrace with a view over the harbour.",
          "critical": "Closes at 17:30 — go straight to the top floor and work down."
        },
        {
          "id": "d3i8", "time": "18:00", "title": "Canal ride by bike — Prinsengracht", "type": "bike", "status": "planned",
          "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Prinsengracht_Amsterdam.jpg/960px-Prinsengracht_Amsterdam.jpg",
          "place": "Prinsengracht, Amsterdam", "coords": { "lat": 52.3752, "lon": 4.8840 },
          "desc": "Slow loop Prinsengracht → Jordaan → Westerkerk. Stay right, watch the trams, kids in the middle."
        },
        {
          "id": "d3i9", "time": "19:30", "title": "Dinner in the Jordaan", "type": "meal", "status": "planned",
          "options": [
            { "id": "d3o1", "title": "Moeders", "desc": "Dutch home cooking, walls covered with photos of mums — book.", "place": "Rozengracht 251, Amsterdam", "menuUrl": "https://www.moeders.com" },
            { "id": "d3o2", "title": "Foodhallen", "desc": "Indoor food market, everyone picks their own — no booking.", "place": "Bellamyplein 51, Amsterdam" }
          ]
        },
        { "id": "d3i10", "title": "Night in Amsterdam", "type": "night", "status": "planned", "bookingId": "b-ams" }
      ]
    },
    {
      "id": "d4",
      "index": 4,
      "date": "2026-10-26",
      "title": "Windmills, then home",
      "intro": "Train to the Zaanse Schans windmills at opening, back for the bikes, then the long drive home with one charging stop.",
      "route": { "km": 510, "drive": "5h20", "charge": "Ionity Aire de Ressons (A1) — 25 min", "vehicleId": "v1" },
      "coords": { "lat": 52.4740, "lon": 4.8180, "label": "Zaanse Schans" },
      "tip": "Buy the NS train tickets in the app the evening before (contactless bank card works too at the gates).",
      "planB": "Bad weather: Rijksmuseum family route (Night Watch + the dolls' houses) instead of the windmills — 2 hours, tickets online.",
      "items": [
        { "id": "d4i1", "time": "07:45", "title": "Breakfast & check-out", "type": "checkout", "status": "planned", "bookingId": "b-ams", "desc": "Leave the bags at the desk, the car stays in the car park until 14:00." },
        {
          "id": "d4i2", "time": "08:34", "endTime": "08:52", "title": "Train Amsterdam Centraal → Zaandijk Zaanse Schans", "type": "train", "status": "planned",
          "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/Amsterdam_Centraal.jpg/960px-Amsterdam_Centraal.jpg",
          "bookingId": "b-train",
          "transport": { "carrier": "NS", "number": "Sprinter 4816", "from": { "name": "Amsterdam Centraal", "platform": "4b" }, "to": { "name": "Zaandijk Zaanse Schans" } },
          "desc": "17 minutes, every 15 min. Then a 15-min walk over the bridge to the windmills."
        },
        {
          "id": "d4i3", "time": "09:15", "endTime": "11:15", "title": "Zaanse Schans windmills", "type": "heritage", "stars": 3, "status": "planned",
          "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Zaanse_Schans_windmills.jpg/960px-Zaanse_Schans_windmills.jpg",
          "place": "Schansend 7, Zaandam", "coords": { "lat": 52.4740, "lon": 4.8180 },
          "desc": "Working windmills (climb De Kat, the dye mill), clog workshop, cheese farm with tastings. Free to walk around; mills ~€6 each.",
          "price": 30, "priceEstimated": true, "outfit": ["warm", "windproof"],
          "alternatives": [
            { "id": "d4a1", "trigger": "rain", "title": "Zaans Museum", "desc": "Indoor, chocolate & Verkade factory exhibit — kids' workshop." }
          ]
        },
        {
          "id": "d4i4", "time": "11:40", "title": "Train back to Amsterdam Centraal", "type": "train", "status": "planned",
          "transport": { "carrier": "NS", "from": { "name": "Zaandijk Zaanse Schans" }, "to": { "name": "Amsterdam Centraal" } }
        },
        { "id": "d4i5", "time": "12:15", "title": "Return the bikes", "type": "bike", "status": "planned", "place": "Stationsplein 5, Amsterdam", "personIds": ["p2"] },
        {
          "id": "d4i6", "time": "12:45", "title": "Quick lunch", "type": "meal", "status": "planned",
          "options": [
            { "id": "d4o1", "title": "Stubbe's Haring", "desc": "Herring stand on the bridge — the local thing.", "place": "Singel / Haarlemmersluis, Amsterdam" },
            { "id": "d4o2", "title": "Bakers & Roasters", "desc": "Brunch plates, big portions for the road.", "place": "Kadijksplein 16, Amsterdam" }
          ]
        },
        {
          "id": "d4i7", "time": "14:00", "title": "Drive home", "type": "drive", "status": "planned",
          "desc": "A4/A16 → Antwerp → E19/A1. Aim to be home for dinner.",
          "transport": { "vehicleId": "v1", "from": { "name": "Amsterdam" }, "to": { "name": "Paris" } }
        },
        {
          "id": "d4i8", "time": "17:00", "endTime": "17:30", "title": "Charge — Ionity Aire de Ressons (A1)", "type": "charging", "status": "planned",
          "coords": { "lat": 49.5410, "lon": 2.7590 }, "desc": "25 min to reach home comfortably. Snack & toilets.", "price": 32, "priceEstimated": true
        },
        { "id": "d4i9", "time": "19:30", "title": "Home", "type": "free", "status": "planned" }
      ]
    }
  ],
  "bookings": [
    {
      "id": "b-lille", "type": "stay", "status": "confirmed", "title": "Hotel L'Arbre Voyageur — Lille", "hotelStars": 4,
      "dates": "Night of 23–24 October", "checkin": "15:00", "checkout": "11:00", "breakfastIncluded": true,
      "rooms": [{ "label": "Family room (2 adults + 2 children)", "memberIds": ["m1", "m2", "m3", "m4"] }],
      "address": "45 boulevard Carnot, 59800 Lille", "gpsAddress": "Q-Park Grand-Place, rue des Manneliers, Lille",
      "phone": "+33 3 20 20 62 62", "website": "https://www.hotellarbrevoyageur.com",
      "cancellation": "Free cancellation until 21 October, 18:00",
      "instructions": "Early check-in possible if the room is ready; ask for the parking discount code at reception.",
      "price": 189, "payment": { "status": "onsite" },
      "refs": [{ "label": "Booking reference", "value": "LAV-20261023-4471" }],
      "tickets": [],
      "reminder": { "date": "2026-10-21", "action": "Confirm 14:00 early check-in by phone" }
    },
    {
      "id": "b-bruges", "type": "stay", "status": "confirmed", "title": "Hotel Ter Brughe — Bruges", "hotelStars": 4,
      "dates": "Night of 24–25 October", "checkin": "15:00", "checkout": "11:00", "breakfastIncluded": true,
      "rooms": [
        { "label": "Double canal view", "memberIds": ["m1", "m2"] },
        { "label": "Twin", "memberIds": ["m3", "m4"] }
      ],
      "address": "Oost-Gistelhof 2, 8000 Brugge", "gpsAddress": "Centrum 't Zand car park, 't Zand 12, Brugge",
      "phone": "+32 50 34 03 24", "website": "https://www.hotelterbrughe.com",
      "cancellation": "Free cancellation until 22 October",
      "price": 262, "payment": { "status": "deposit", "deposit": 80 },
      "refs": [{ "label": "Booking number", "value": "TB-88412" }, { "label": "Door code (after 22:00)", "value": "4471#", "sensitive": true }],
      "tickets": []
    },
    {
      "id": "b-boat", "type": "activity", "status": "confirmed", "title": "Canal cruise — Huidenvettersplein jetty",
      "dates": "24 October, 14:00", "address": "Huidenvettersplein 13, 8000 Brugge",
      "price": 48, "payment": { "status": "prepaid" },
      "refs": [{ "label": "Reservation", "value": "CAN-2410-0142" }],
      "tickets": [
        { "id": "t-boat", "label": "Family (2 adults + 2 children)", "code": "CAN-2410-0142", "memberId": "m1", "payload": "CAN|2410|0142|FAM4|20261024", "format": "qr", "date": "2026-10-24", "time": "14:00" }
      ]
    },
    {
      "id": "b-walk", "type": "activity", "status": "confirmed", "title": "Family walking tour with Jonas",
      "dates": "24 October, 15:00–17:00", "personIds": ["p1"],
      "instructions": "Meeting point: in front of the Belfry entrance, Markt 7. Blue umbrella. Pay the guide in cash or by card at the end.",
      "price": 90, "payment": { "status": "onsite" },
      "refs": [{ "label": "Tourist office ref.", "value": "VB-7731" }],
      "tickets": []
    },
    {
      "id": "b-belfry", "type": "activity", "status": "to_book", "title": "Belfry of Bruges — timed ticket 09:30",
      "dates": "25 October, 09:30", "address": "Markt 7, 8000 Brugge", "website": "https://www.museabrugge.be",
      "instructions": "Book the first slot online (limited to 70 people at a time). Kids under 6 free.",
      "price": 42, "priceEstimated": true,
      "refs": [], "tickets": [],
      "reminder": { "date": "2026-10-18", "action": "Buy the 09:30 belfry slot online" }
    },
    {
      "id": "b-ams", "type": "stay", "status": "confirmed", "title": "DoubleTree by Hilton Amsterdam Centraal", "hotelStars": 4,
      "dates": "Night of 25–26 October", "checkin": "15:00", "checkout": "12:00", "breakfastIncluded": false,
      "rooms": [{ "label": "Family room, 2 queen beds", "memberIds": ["m1", "m2", "m3", "m4"] }],
      "address": "Oosterdoksstraat 4, 1011 DK Amsterdam", "gpsAddress": "Parking Centrum Oosterdok, Oosterdokskade 5, Amsterdam",
      "phone": "+31 20 530 0800", "website": "https://www.hilton.com",
      "cancellation": "Non-refundable rate",
      "instructions": "SkyLounge on the 11th floor — free access for guests, great at sunset.",
      "price": 245, "payment": { "status": "prepaid" },
      "refs": [{ "label": "Confirmation", "value": "HH-3392847106" }],
      "tickets": []
    },
    {
      "id": "b-parking", "type": "parking", "status": "confirmed", "title": "Parking Centrum Oosterdok — 24 h",
      "dates": "25 Oct 14:30 → 26 Oct 14:00", "address": "Oosterdokskade 5, Amsterdam",
      "instructions": "Scan the code at the entry and exit barriers. Level -2, near the hotel lift.",
      "price": 45, "payment": { "status": "prepaid" },
      "refs": [{ "label": "E-ticket", "value": "PCO-58201933" }],
      "tickets": [
        { "id": "t-parking", "label": "Parking e-ticket", "code": "PCO-58201933", "payload": "PCO58201933", "format": "code128", "validUntil": "2026-10-26" }
      ]
    },
    {
      "id": "b-nemo", "type": "activity", "status": "confirmed", "title": "NEMO Science Museum",
      "dates": "25 October, 16:00 entry", "address": "Oosterdok 2, 1011 VX Amsterdam", "website": "https://www.nemosciencemuseum.nl",
      "price": 70, "payment": { "status": "prepaid" },
      "refs": [{ "label": "Order", "value": "NEMO-77120345" }],
      "tickets": [
        { "id": "t-nemo-1", "label": "Adult", "code": "NEMO-77120345-1", "memberId": "m1", "payload": "NEMO77120345-01-A", "format": "qr", "date": "2026-10-25", "time": "16:00" },
        { "id": "t-nemo-2", "label": "Adult", "code": "NEMO-77120345-2", "memberId": "m2", "payload": "NEMO77120345-02-A", "format": "qr", "date": "2026-10-25", "time": "16:00" },
        { "id": "t-nemo-3", "label": "Child 4–17", "code": "NEMO-77120345-3", "memberId": "m3", "payload": "NEMO77120345-03-C", "format": "qr", "date": "2026-10-25", "time": "16:00" },
        { "id": "t-nemo-4", "label": "Child 4–17", "code": "NEMO-77120345-4", "memberId": "m4", "payload": "NEMO77120345-04-C", "format": "qr", "date": "2026-10-25", "time": "16:00" }
      ]
    },
    {
      "id": "b-train", "type": "transport", "status": "optional", "title": "NS train — Amsterdam Centraal ↔ Zaandijk Zaanse Schans",
      "dates": "26 October", "website": "https://www.ns.nl",
      "instructions": "Buy in the NS app the evening before, or tap in/out with a contactless bank card. Kids 4–11: Railrunner €2.50.",
      "price": 22, "priceEstimated": true,
      "refs": [], "tickets": []
    }
  ],
  "checklists": [
    {
      "id": "c1", "title": "Bags", "emoji": "🎒",
      "items": [
        { "id": "c1i1", "label": "ID cards for the four of us", "done": false },
        { "id": "c1i2", "label": "Rain jackets — it is Flanders in October", "done": false },
        { "id": "c1i3", "label": "Sneakers for the belfries (700 steps in total)", "done": true },
        { "id": "c1i4", "label": "Picnic bag for the charging stops", "done": false },
        { "id": "c1i5", "label": "Kids' headphones for the car", "done": true }
      ]
    },
    {
      "id": "c2", "title": "Car", "emoji": "🔌",
      "items": [
        { "id": "c2i1", "label": "Charge to 100 % Thursday night", "done": false },
        { "id": "c2i2", "label": "Fastned / Ionity charging cards + app logged in", "done": true },
        { "id": "c2i3", "label": "Warning triangle & vests (mandatory in BE/NL)", "done": true }
      ]
    }
  ],
  "contacts": [
    { "id": "ct1", "name": "European emergency number", "phone": "112", "note": "Valid in France, Belgium and the Netherlands" },
    { "id": "ct2", "name": "Roadside assistance (insurer)", "phone": "+33 1 00 00 00 00", "note": "Contract number in the glovebox" }
  ],
  "logistics": [
    { "id": "l1", "emoji": "🅿️", "title": "Parking in Bruges", "content": "The whole centre is pedestrian. Centrum 't Zand car park: about €3.50 per 24 h, free shuttle bus to the Markt with the parking ticket." },
    { "id": "l2", "emoji": "🚗", "title": "Amsterdam low-emission zone", "content": "Milieuzone in the centre — no issue for an EV. Street parking is €7.50/h: always use the Oosterdok car park." },
    { "id": "l3", "emoji": "🚲", "title": "Cycling in Amsterdam", "content": "Ride on the right, hand signals, no phone. Bike lanes are for bikes only — never walk in them. Lock both locks when parked." }
  ],
  "apps": [
    { "id": "a1", "name": "Visit Bruges", "emoji": "🧭", "desc": "Official city maps and opening hours", "url": "https://www.visitbruges.be" },
    { "id": "a2", "name": "NS", "emoji": "🚆", "desc": "Dutch railways — tickets and live departures", "url": "https://www.ns.nl", "ios": "https://apps.apple.com/app/id370504240", "android": "https://play.google.com/store/apps/details?id=nl.ns.android.activity" },
    { "id": "a3", "name": "Fastned", "emoji": "⚡", "desc": "Fast chargers BE/NL — start a session from the app", "url": "https://www.fastned.nl" }
  ]
}
