<script lang="ts">
  import { onMount } from 'svelte';
  import { page } from '$app/state';
  import ItemModal from '$lib/components/trips/ItemModal.svelte';
  import TripEditModal from '$lib/components/trips/TripEditModal.svelte';

  interface ItineraryEvent {
    time: string;
    name: string;
    description: string;
    category: string;
    mapsLink?: boolean;
    stayingOvernight?: boolean;
    image?: string;
    cost?: { points?: number; cash?: number };
    flightNumber?: string;
    reservation?: string;
    lat?: number | null;
    lng?: number | null;
    entityId?: string;
    entityType?: 'transportation' | 'lodging' | 'location';
    rawData?: any;
  }

  interface Day {
    day: number;
    date: string;
    description: string;
    events: ItineraryEvent[];
  }

  let trip = $state({ name: '', dates: '', away: '', duration: '', description: '' });
  let coverImages = $state<string[]>(['']);
  let itinerary = $state<Day[]>([]);
  let unscheduled = $state<{ name: string; description: string }[]>([]);
  let notes = $state<{ id: string; date: string; content: string }[]>([]);
  let mapLocations = $state<{ name: string; lat: number; lng: number; type: string }[]>([]);
  let rawTripData = $state<any>(null);
  let loading = $state(true);

  let itemModalOpen = $state(false);
  let itemModalType = $state<'transportation' | 'lodging' | 'location' | 'note'>('location');
  let itemModalEdit = $state<any>(null);
  let tripEditOpen = $state(false);
  let shareOpen = $state(false);
  let shareCopied = $state(false);
  let fabOpen = $state(false);
  let activeView = $state<'itinerary' | 'map' | 'ai'>('itinerary');
  let currentCoverIdx = $state(0);
  let expandedDays = $state<Set<number>>(new Set([1, 2, 3]));
  let noteDraft = $state('');
  const noteCount = $derived(notes.length);

  const tripId = $derived(page.url.searchParams.get('id') || '');
  const shareMode = $derived(page.url.searchParams.get('share') === 'true');
  const coverImage = $derived(coverImages[currentCoverIdx] || '');
  const shareUrl = $derived(
    rawTripData?.share_token && typeof window !== 'undefined'
      ? `${window.location.origin}/trips/view/${rawTripData.share_token}`
      : ''
  );

  const itineraryEvents = $derived(itinerary.flatMap((day) => day.events));
  const scheduledDays = $derived(itinerary.filter((day) => day.events.length > 0));
  const tripExpenses = $derived({
    points: itineraryEvents.reduce((sum, event) => sum + (event.cost?.points || 0), 0),
    cash: itineraryEvents.reduce((sum, event) => sum + (event.cost?.cash || 0), 0),
    flights: itineraryEvents.filter((event) => event.category === 'Flight').length,
    hotels: itineraryEvents.filter((event) => event.category === 'Hotel').length,
    activities: itineraryEvents.filter((event) => ['Activity', 'Hike', 'Restaurant'].includes(event.category)).length
  });

  const singleMapPin = $derived(mapLocations.length === 1 ? mapLocations[0] : null);
  const categoryColors: Record<string, { tint: string; ink: string }> = {
    Flight: { tint: 'rgba(199, 92, 42, 0.14)', ink: '#934114' },
    Hotel: { tint: 'rgba(126, 88, 214, 0.14)', ink: '#5a42a1' },
    Restaurant: { tint: 'rgba(201, 113, 45, 0.14)', ink: '#9a4b1e' },
    Activity: { tint: 'rgba(53, 121, 93, 0.14)', ink: '#1f6248' },
    Hike: { tint: 'rgba(83, 135, 62, 0.14)', ink: '#386a2f' },
    Drive: { tint: 'rgba(161, 113, 45, 0.14)', ink: '#8a581d' },
    Logistics: { tint: 'rgba(117, 98, 75, 0.14)', ink: '#6f6052' }
  };

  function formatDateRange(start: string, end: string): string {
    if (!start) return '';
    const s = new Date(start + 'T00:00:00');
    const e = new Date(end + 'T00:00:00');
    const sMonth = s.toLocaleDateString('en-US', { month: 'short' });
    const eMonth = e.toLocaleDateString('en-US', { month: 'short' });
    const sYear = s.getFullYear();
    const eYear = e.getFullYear();
    if (sMonth === eMonth && sYear === eYear) {
      return `${sMonth} ${s.getDate()} – ${e.getDate()}, ${sYear}`;
    }
    if (sYear === eYear) {
      return `${sMonth} ${s.getDate()} – ${eMonth} ${e.getDate()}, ${sYear}`;
    }
    return `${sMonth} ${s.getDate()}, ${sYear} – ${eMonth} ${e.getDate()}, ${eYear}`;
  }

  function durationDays(start: string, end: string): string {
    if (!start || !end) return '';
    const days = Math.ceil((new Date(end).getTime() - new Date(start).getTime()) / 86400000) + 1;
    return `${days} days`;
  }

  function daysAway(start: string): string {
    if (!start) return '';
    const diff = Math.ceil((new Date(start + 'T00:00:00').getTime() - Date.now()) / 86400000);
    if (diff <= 0) return '';
    if (diff === 1) return '1 day away';
    return `${diff} days away`;
  }

  function formatTime(dateStr: string): string {
    if (!dateStr) return '';
    const d = new Date(dateStr);
    if (Number.isNaN(d.getTime())) return '';
    return d.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true });
  }

  function compactReservation(value?: string): string {
    if (!value) return '';
    const tokens = value
      .split(/[,\s]+/)
      .map((token) => token.trim())
      .filter(Boolean);
    const unique = [...new Set(tokens)];
    const useful = unique.find((token) => /[a-z0-9]/i.test(token)) || '';
    if (!useful) return '';
    if (useful.length > 14) return `Ref ${useful.slice(0, 14)}`;
    return `Ref ${useful}`;
  }

  function stripHtml(value?: string): string {
    return (value || '')
      .replace(/<br\s*\/?>/gi, ' ')
      .replace(/<\/p>/gi, ' ')
      .replace(/<[^>]+>/g, ' ')
      .replace(/\s+/g, ' ')
      .trim();
  }

  function compactDescription(event: ItineraryEvent): string {
    const description = stripHtml(event.description || '');
    if (!description) return '';
    if (event.category === 'Hotel' && description.length > 72) {
      return 'Stay block with confirmation and check-in details.';
    }
    return description;
  }

  function sortedDayEvents(day: Day): ItineraryEvent[] {
    return [...day.events].sort((a, b) => {
      const aHotel = a.category === 'Hotel' ? 1 : 0;
      const bHotel = b.category === 'Hotel' ? 1 : 0;
      if (aHotel !== bHotel) return aHotel - bHotel;
      const aRaw = a.rawData?.date || a.rawData?.start_time || a.rawData?.check_in || '';
      const bRaw = b.rawData?.date || b.rawData?.start_time || b.rawData?.check_in || '';
      const aStamp = aRaw ? new Date(aRaw).getTime() : Number.MAX_SAFE_INTEGER;
      const bStamp = bRaw ? new Date(bRaw).getTime() : Number.MAX_SAFE_INTEGER;
      if (Number.isFinite(aStamp) && Number.isFinite(bStamp) && aStamp !== bStamp) return aStamp - bStamp;
      return (a.time || '').localeCompare(b.time || '');
    });
  }

  function activeDaySummary(day: Day): string {
    const nonHotelCount = day.events.filter((event) => event.category !== 'Hotel').length;
    const hotelCount = day.events.filter((event) => event.category === 'Hotel').length;
    if (nonHotelCount > 0 && hotelCount > 0) return `${nonHotelCount} stop${nonHotelCount === 1 ? '' : 's'} + stay`;
    if (nonHotelCount > 0) return `${nonHotelCount} stop${nonHotelCount === 1 ? '' : 's'}`;
    if (hotelCount > 0) return `${hotelCount} stay block${hotelCount === 1 ? '' : 's'}`;
    return 'Flexible';
  }

  function crispDescription(event: ItineraryEvent): string {
    const description = compactDescription(event);
    if (!description) return '';
    if (description.length > 110) return `${description.slice(0, 107)}...`;
    return description;
  }

  function eventMetaTokens(event: ItineraryEvent): string[] {
    const tokens: string[] = [];
    if (event.flightNumber) tokens.push(event.flightNumber);
    if (compactReservation(event.reservation)) tokens.push(compactReservation(event.reservation));
    if (event.cost?.points) tokens.push(`${Math.round((event.cost.points || 0) / 1000)}K pts`);
    if (event.cost?.cash) tokens.push(`$${event.cost.cash}`);
    if (event.mapsLink && event.lat && event.lng) tokens.push('Maps');
    return tokens.slice(0, 3);
  }

  function formatDayDate(dateStr: string): string {
    const d = new Date(dateStr + 'T00:00:00');
    return d.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });
  }

  function mapCategory(item: any, type: string): string {
    if (type === 'transportation') {
      const transportType = (item.type || '').toLowerCase();
      if (transportType === 'plane' || transportType === 'flight') return 'Flight';
      if (transportType === 'car' || transportType === 'rental') return 'Drive';
      return 'Logistics';
    }
    if (type === 'lodging') return 'Hotel';
    if (type === 'location') {
      const category = (item.category || '').toLowerCase();
      if (['restaurant', 'cafe', 'bar', 'food'].includes(category)) return 'Restaurant';
      if (['hiking', 'hike'].includes(category)) return 'Hike';
      return 'Activity';
    }
    return 'Activity';
  }

  function entityImage(tripImages: any[], entityId: string, entityOwnImages?: any[]): string {
    const img = (entityOwnImages || []).find((image: any) => image.file_path)
      || (tripImages || []).find((image: any) => image.entity_id === entityId);
    if (!img) return '';
    const path = img.file_path || '';
    return path.startsWith('/') ? path : `/images/${path}`;
  }

  function nextCover() {
    currentCoverIdx = (currentCoverIdx + 1) % coverImages.length;
  }

  function prevCover() {
    currentCoverIdx = (currentCoverIdx - 1 + coverImages.length) % coverImages.length;
  }

  function toggleDay(day: number) {
    const next = new Set(expandedDays);
    if (next.has(day)) next.delete(day);
    else next.add(day);
    expandedDays = next;
  }

  function openCreateModal(type: 'transportation' | 'lodging' | 'location' | 'note') {
    itemModalType = type;
    itemModalEdit = null;
    itemModalOpen = true;
    fabOpen = false;
  }

  function openEdit(evt: ItineraryEvent) {
    if (!evt.entityId || !evt.entityType) return;
    itemModalType = evt.entityType;
    itemModalEdit = evt.rawData || {};
    itemModalOpen = true;
  }

  async function copyShare() {
    if (!shareUrl) return;
    await navigator.clipboard.writeText(shareUrl);
    shareCopied = true;
    setTimeout(() => (shareCopied = false), 1800);
  }

  async function saveNote() {
    if (!tripId || !noteDraft.trim()) return;
    try {
      await fetch('/api/trips/note', {
        method: 'POST',
        credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          trip_id: tripId,
          name: noteDraft.trim().slice(0, 60),
          content: noteDraft.trim()
        })
      });
      noteDraft = '';
      await reloadTrip();
    } catch {
      // keep route stable
    }
  }

  async function deleteNote(noteId: string) {
    if (!confirm('Delete this note?')) return;
    try {
      await fetch('/api/trips/note/delete', {
        method: 'POST',
        credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ id: noteId })
      });
      await reloadTrip();
    } catch {
      // keep route stable
    }
  }

  async function deleteTrip() {
    if (!tripId) return;
    if (!confirm('Delete this trip and all its data? This cannot be undone.')) return;
    try {
      const res = await fetch('/api/trips/trip/delete', {
        method: 'POST',
        credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ id: tripId })
      });
      if (res.ok) window.location.href = '/trips';
    } catch {
      // keep route stable
    }
  }

  function buildItinerary(data: any) {
    trip = {
      name: data.name || '',
      dates: formatDateRange(data.start_date, data.end_date),
      away: daysAway(data.start_date),
      duration: durationDays(data.start_date, data.end_date),
      description: data.description || ''
    };

    const allImages: string[] = [];
    if (data.cover_image) allImages.push(data.cover_image);
    for (const img of data.images || []) {
      const path = img.file_path || '';
      if (path && !allImages.includes(`/images/${path}`)) allImages.push(`/images/${path}`);
    }
    coverImages = allImages.length > 0 ? allImages : [''];
    currentCoverIdx = 0;

    const startDate = new Date(data.start_date + 'T00:00:00');
    const endDate = new Date(data.end_date + 'T00:00:00');
    const totalDays = Math.ceil((endDate.getTime() - startDate.getTime()) / 86400000) + 1;
    const dayMap: Record<string, ItineraryEvent[]> = {};

    for (let i = 0; i < totalDays; i++) {
      const d = new Date(startDate);
      d.setDate(d.getDate() + i);
      dayMap[d.toISOString().slice(0, 10)] = [];
    }

    const allImgs = data.images || [];
    const allDocs = data.documents || [];
    function enrichRaw(item: any, type: string) {
      const eType = ({ transportation: 'transportation', lodging: 'lodging', location: 'location' } as Record<string, string>)[type] || type;
      return {
        ...item,
        images: item.images?.length ? item.images : allImgs.filter((image: any) => image.entity_type === eType && image.entity_id === item.id),
        documents: item.documents?.length ? item.documents : allDocs.filter((doc: any) => doc.entity_type === eType && doc.entity_id === item.id)
      };
    }

    for (const t of data.transportations || []) {
      const date = (t.date || '').slice(0, 10);
      if (!dayMap[date]) dayMap[date] = [];
      dayMap[date].push({
        time: formatTime(t.date),
        name: t.name || `${t.from_location} → ${t.to_location}`,
        description: t.description || (t.from_location && t.to_location ? `${t.from_location} → ${t.to_location}` : ''),
        category: mapCategory(t, 'transportation'),
        flightNumber: t.flight_number || '',
        cost: { points: t.cost_points || 0, cash: t.cost_cash || 0 },
        mapsLink: !!(t.from_lat || t.to_lat),
        lat: t.from_lat || t.to_lat,
        lng: t.from_lng || t.to_lng,
        image: entityImage(data.images, t.id, t.images),
        entityId: t.id,
        entityType: 'transportation',
        rawData: enrichRaw(t, 'transportation')
      });
    }

    for (const l of data.lodging || []) {
      const date = (l.check_in || '').slice(0, 10);
      if (!dayMap[date]) dayMap[date] = [];
      dayMap[date].push({
        time: formatTime(l.check_in),
        name: l.name,
        description: l.description || `${l.type || 'Hotel'} · ${l.location || ''}`.trim(),
        category: 'Hotel',
        stayingOvernight: true,
        mapsLink: !!l.latitude,
        lat: l.latitude,
        lng: l.longitude,
        cost: { points: l.cost_points || 0, cash: l.cost_cash || 0 },
        reservation: l.reservation_number || '',
        image: entityImage(data.images, l.id, l.images),
        entityId: l.id,
        entityType: 'lodging',
        rawData: enrichRaw(l, 'lodging')
      });
    }

    for (const loc of data.locations || []) {
      const date = loc.visit_date || (loc.start_time || '').slice(0, 10);
      if (!dayMap[date]) dayMap[date] = [];
      let desc = loc.description || '';
      if (loc.hike_distance) {
        desc = `${loc.hike_distance} · ${loc.hike_difficulty || ''} · ${loc.hike_time || ''}`.trim();
      }
      dayMap[date].push({
        time: formatTime(loc.start_time),
        name: loc.name,
        description: desc,
        category: mapCategory(loc, 'location'),
        mapsLink: !!loc.latitude,
        lat: loc.latitude,
        lng: loc.longitude,
        cost: { points: loc.cost_points || 0, cash: loc.cost_cash || 0 },
        image: entityImage(data.images, loc.id, loc.images),
        entityId: loc.id,
        entityType: 'location',
        rawData: enrichRaw(loc, 'location')
      });
    }

    const days: Day[] = [];
    let dayNum = 1;
    for (const [date, events] of Object.entries(dayMap).sort()) {
      events.sort((a, b) => (a.time || '').localeCompare(b.time || ''));
      days.push({
        day: dayNum,
        date: formatDayDate(date),
        description: events.length > 0 ? events[0].name : 'Open day',
        events
      });
      dayNum++;
    }
    itinerary = days;
    const preExpanded = days.filter((day) => day.events.length > 0).slice(0, 3).map((day) => day.day);
    expandedDays = new Set(preExpanded);

    notes = (data.notes || []).map((note: any) => ({
      id: note.id,
      date: note.date ? new Date(note.date + 'T00:00:00').toLocaleDateString('en-US', { month: 'short', day: 'numeric' }) : '',
      content: note.content || note.name || ''
    }));

    unscheduled = (data.locations || [])
      .filter((loc: any) => !loc.visit_date && !loc.start_time)
      .map((loc: any) => ({ name: loc.name, description: loc.description || '' }));

    const pins: typeof mapLocations = [];
    for (const t of data.transportations || []) {
      if (t.from_lat && t.from_lng) pins.push({ name: t.from_location || t.name, lat: t.from_lat, lng: t.from_lng, type: 'transport' });
      if (t.to_lat && t.to_lng) pins.push({ name: t.to_location || t.name, lat: t.to_lat, lng: t.to_lng, type: 'transport' });
    }
    for (const l of data.lodging || []) {
      if (l.latitude && l.longitude) pins.push({ name: l.name, lat: l.latitude, lng: l.longitude, type: 'hotel' });
    }
    for (const loc of data.locations || []) {
      if (loc.latitude && loc.longitude) pins.push({ name: loc.name, lat: loc.latitude, lng: loc.longitude, type: loc.category || 'activity' });
    }
    mapLocations = pins;
  }

  async function reloadTrip() {
    if (!tripId) return;
    try {
      const res = await fetch(`/api/trips/trip/${tripId}`, { credentials: 'include' });
      if (res.ok) {
        const data = await res.json();
        rawTripData = data;
        buildItinerary(data);
      }
    } catch {
      // keep route stable
    }
  }

  onMount(async () => {
    if (!tripId) {
      loading = false;
      return;
    }
    await reloadTrip();
    loading = false;
  });
</script>

<div class="trip-workspace">
  <section class="trip-hero reveal" style={coverImage ? `background-image:url('${coverImage}')` : ''}>
    <div class="hero-veil"></div>
    <div class="hero-top">
      <a class="hero-back" href="/trips">Back to Trips</a>
      {#if !shareMode}
        <div class="hero-tools">
          <button class="hero-tool" onclick={() => (shareOpen = true)}>Share</button>
          <button class="hero-tool primary" onclick={() => (tripEditOpen = true)}>Edit trip</button>
        </div>
      {/if}
    </div>

    <div class="hero-copy">
      <div class="hero-kicker">Trip detail</div>
      <h1>{trip.name || 'Trip'}</h1>
      <div class="hero-meta">{trip.dates}{#if trip.duration} · {trip.duration}{/if}{#if trip.away} · {trip.away}{/if}</div>
      {#if trip.description}
        <p>{trip.description}</p>
      {/if}
      <div class="hero-facts">
        <span>{scheduledDays.length} live day{scheduledDays.length === 1 ? '' : 's'}</span>
        <span>{Math.round(tripExpenses.points / 1000)}K points redeemed</span>
      </div>
    </div>

    {#if coverImages.length > 1}
      <div class="hero-nav">
        <button class="cover-nav" onclick={prevCover} aria-label="Previous cover">‹</button>
        <span>{currentCoverIdx + 1}/{coverImages.length}</span>
        <button class="cover-nav" onclick={nextCover} aria-label="Next cover">›</button>
      </div>
    {/if}

  </section>

  <div class="detail-grid">
    <div class="detail-main">
      <section class="board-head reveal">
        <div class="board-tools">
          {#if !shareMode}
            <button class:active={activeView === 'itinerary'} class="board-chip" onclick={() => (activeView = 'itinerary')}>Itinerary</button>
            <button class:active={activeView === 'map'} class="board-chip" onclick={() => (activeView = 'map')}>Map</button>
            <button class:active={activeView === 'ai'} class="board-chip" onclick={() => (activeView = 'ai')}>AI guide</button>
          {/if}
        </div>
      </section>

      {#if !shareMode && activeView === 'map'}
          <section class="map-panel reveal">
            {#if mapLocations.length > 1}
              <iframe
                title="Trip Map"
                src="https://www.openstreetmap.org/export/embed.html?bbox={Math.min(...mapLocations.map((p) => p.lng))-0.05},{Math.min(...mapLocations.map((p) => p.lat))-0.03},{Math.max(...mapLocations.map((p) => p.lng))+0.05},{Math.max(...mapLocations.map((p) => p.lat))+0.03}&layer=mapnik&marker={mapLocations[0].lat},{mapLocations[0].lng}"
                loading="lazy"
              ></iframe>
            {:else if singleMapPin}
              <div class="map-single">
                <div>
                  <div class="section-label">Pinned place</div>
                  <h3>{singleMapPin.name}</h3>
                  <p>This trip only has one mapped anchor right now, so the full canvas would be mostly empty.</p>
                </div>
                <a class="map-link" href={`https://www.google.com/maps/search/?api=1&query=${singleMapPin.lat},${singleMapPin.lng}`} target="_blank" rel="noopener">Open in Maps</a>
              </div>
            {:else}
              <div class="map-empty">No pinned locations yet.</div>
            {/if}
          </section>
      {:else if !shareMode && activeView === 'ai'}
          <section class="guide-panel reveal">
            <div class="guide-copy">
              <div class="section-label">AI guide</div>
              <h3>Still a placeholder</h3>
              <p>Restaurants, weather, and packing help should live here once the trip assistant is ready.</p>
            </div>
            <div class="guide-suggestions">
              <span>Best coffee near the hotel</span>
              <span>Weather shift on day 3</span>
              <span>Need a better hike window</span>
            </div>
          </section>
      {/if}

      {#if activeView === 'itinerary' || shareMode}
        <section class="itinerary-board reveal">
          {#each itinerary as day (day.day)}
            {@const isExpanded = expandedDays.has(day.day)}
            <article class="day-block" class:collapsed={!isExpanded} class:empty-day={day.events.length === 0}>
              <button class="day-head" onclick={() => toggleDay(day.day)}>
                <div class="day-title">
                  <span class="day-pill">Day {day.day}</span>
                  <div>
                    <div class="day-date">{day.date}</div>
                    {#if day.events.length === 0}
                      <div class="day-summary">Open day</div>
                    {/if}
                  </div>
                </div>
                <div class="day-count">{activeDaySummary(day)}</div>
              </button>

              {#if isExpanded}
                <div class="events-stack">
                  {#if day.events.length === 0}
                    <div class="empty-block">Open day. Use it for travel padding, a dinner hold, or one anchor activity.</div>
                  {:else}
                    {#each sortedDayEvents(day) as event}
                      {#if event.category === 'Hotel'}
                        <button class="stay-row" type="button" onclick={() => openEdit(event)}>
                          <div class="stay-label">Stay</div>
                          <div class="stay-main">
                            <div class="stay-name">{event.name}</div>
                            <div class="stay-meta">
                              <span>{event.time || 'Anytime'}</span>
                              {#if compactReservation(event.reservation)}<span>{compactReservation(event.reservation)}</span>{/if}
                              {#if event.cost?.points}<span>{Math.round((event.cost.points || 0) / 1000)}K pts</span>{/if}
                              {#if event.cost?.cash}<span>${event.cost.cash}</span>{/if}
                            </div>
                          </div>
                        </button>
                      {:else}
                        <button class="event-row" type="button" onclick={() => openEdit(event)}>
                          <div class="event-time-column">{event.time || 'Anytime'}</div>
                          <div class="event-line"></div>
                          <div class="event-card">
                            <div class="event-top">
                              <div class="event-header-line">
                                <div class="event-stamp-mobile">{event.time || 'Anytime'}</div>
                                <span
                                  class="event-kind"
                                  style={`background:${categoryColors[event.category]?.tint || 'rgba(117,98,75,0.14)'};color:${categoryColors[event.category]?.ink || '#6f6052'}`}
                                >
                                  {event.category}
                                </span>
                              </div>
                              <div class="event-name">{event.name}</div>
                            </div>
                            {#if crispDescription(event)}
                              <div class="event-description">{crispDescription(event)}</div>
                            {/if}
                            <div class="event-meta">
                              {#each eventMetaTokens(event) as token}
                                <span>{token}</span>
                              {/each}
                            </div>
                          </div>
                          {#if event.image}
                            <div class="event-thumb" style={`background-image:url('${event.image}')`}></div>
                          {/if}
                        </button>
                      {/if}
                    {/each}
                  {/if}
                </div>
              {/if}
            </article>
          {/each}
        </section>
      {/if}
    </div>

    <aside class="detail-rail">
      <section class="rail-block reveal">
        <div class="section-label">Notes</div>
        <div class="rail-headline">
          <h3>Trip desk</h3>
          <div class="rail-count">{noteCount} note{noteCount === 1 ? '' : 's'}</div>
        </div>
        <p>Keep booking reminders, handoff notes, and quick journal lines beside the plan.</p>
        <div class="notes-stack">
          {#if notes.length === 0}
            <div class="note-card muted">No notes yet.</div>
          {:else}
            {#each notes as note}
              <div class="note-card">
                <div class="note-date">{note.date || 'Trip note'}</div>
                <div class="note-content">{note.content}</div>
                {#if !shareMode}
                  <button class="note-delete" onclick={() => deleteNote(note.id)}>Remove</button>
                {/if}
              </div>
            {/each}
          {/if}
        </div>
        {#if !shareMode}
          <div class="note-compose">
            <textarea bind:value={noteDraft} rows="3" placeholder="Leave a reminder, booking note, or journal line..."></textarea>
            <button class="rail-action" onclick={saveNote} disabled={!noteDraft.trim()}>Save note</button>
          </div>
        {/if}
      </section>

      {#if unscheduled.length > 0}
        <section class="rail-block reveal">
          <div class="section-label">Unscheduled</div>
          <div class="unscheduled-stack">
            {#each unscheduled as item}
              <div class="unscheduled-row">
                <div class="unscheduled-name">{item.name}</div>
                <div class="unscheduled-description">{item.description || 'No details yet.'}</div>
              </div>
            {/each}
          </div>
        </section>
      {/if}
    </aside>
  </div>
</div>

{#if shareOpen}
  <!-- svelte-ignore a11y_no_static_element_interactions -->
  <div class="share-overlay" onclick={() => (shareOpen = false)}>
    <!-- svelte-ignore a11y_no_static_element_interactions -->
    <div class="share-panel" onclick={(event) => event.stopPropagation()}>
      <div class="section-label">Share trip</div>
      <h3>{rawTripData?.share_token ? 'Viewer link is ready' : 'Create sharing in Edit trip'}</h3>
      <p>{rawTripData?.share_token ? 'Anyone with the link can open the itinerary.' : 'Use Edit trip to create a share token first.'}</p>
      {#if rawTripData?.share_token}
        <div class="share-row">
          <input readonly value={shareUrl} />
          <button onclick={copyShare}>{shareCopied ? 'Copied' : 'Copy'}</button>
        </div>
      {/if}
    </div>
  </div>
{/if}

{#if !shareMode}
  <button class="trip-fab" class:open={fabOpen} onclick={() => (fabOpen = !fabOpen)} aria-label="Add to trip">
    {fabOpen ? 'Close' : 'Add'}
  </button>

  {#if fabOpen}
    <!-- svelte-ignore a11y_no_static_element_interactions -->
    <div class="fab-overlay" onclick={() => (fabOpen = false)}></div>
    <div class="fab-sheet">
      <button onclick={() => openCreateModal('location')}>Add activity</button>
      <button onclick={() => openCreateModal('lodging')}>Add accommodation</button>
      <button onclick={() => openCreateModal('transportation')}>Add transport</button>
      <button onclick={() => openCreateModal('note')}>Add note</button>
      <button onclick={() => { fabOpen = false; tripEditOpen = true; }}>Edit trip</button>
      <button class="danger" onclick={deleteTrip}>Delete trip</button>
    </div>
  {/if}
{/if}

<ItemModal bind:open={itemModalOpen} tripId={tripId} itemType={itemModalType} editItem={itemModalEdit} onSaved={reloadTrip} />
<TripEditModal bind:open={tripEditOpen} tripData={rawTripData} onSaved={reloadTrip} />

<style>
  .trip-workspace {
    display: flex;
    flex-direction: column;
    gap: 22px;
    padding-bottom: 96px;
    min-width: 0;
    overflow-x: clip;
    touch-action: pan-y;
  }

  .trip-hero {
    position: relative;
    min-height: 320px;
    border-radius: 26px;
    overflow: hidden;
    background:
      linear-gradient(135deg, rgba(101, 72, 44, 0.4), rgba(42, 32, 21, 0.15)),
      radial-gradient(circle at top left, rgba(248, 239, 227, 0.92), rgba(223, 206, 185, 0.72));
    background-size: cover;
    background-position: center;
    border: 1px solid rgba(144, 116, 86, 0.18);
    box-shadow: 0 22px 60px rgba(76, 53, 30, 0.14);
    padding: 22px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }

  .hero-veil {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(30, 22, 14, 0.08), rgba(30, 22, 14, 0.7));
  }

  .hero-top,
  .hero-copy,
  .hero-nav {
    position: relative;
    z-index: 1;
  }

  .hero-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
  }

  .hero-back,
  .hero-tool {
    display: inline-flex;
    align-items: center;
    min-height: 38px;
    padding: 0 14px;
    border-radius: 999px;
    border: 1px solid rgba(255, 248, 238, 0.18);
    background: rgba(35, 25, 16, 0.24);
    color: rgba(255, 248, 238, 0.96);
    backdrop-filter: blur(12px);
    font-size: 0.92rem;
  }

  .hero-tool.primary {
    background: rgba(235, 218, 196, 0.92);
    color: #3a2818;
    border-color: transparent;
  }

  .hero-tools {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: flex-end;
  }

  .hero-copy {
    max-width: 720px;
    color: #fff7f0;
  }

  .hero-kicker,
  .section-label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: rgba(255, 242, 229, 0.72);
  }

  .hero-copy h1 {
    margin: 8px 0 10px;
    font-size: clamp(2.3rem, 4.8vw, 4.8rem);
    line-height: 0.94;
    letter-spacing: -0.04em;
    color: #fff8f2;
  }

  .hero-meta {
    font-size: 1rem;
    color: rgba(255, 242, 229, 0.84);
  }

  .hero-copy p {
    margin: 10px 0 0;
    max-width: 40ch;
    font-size: 0.96rem;
    line-height: 1.55;
    color: rgba(255, 242, 229, 0.88);
  }

  .hero-copy > :global(*) {
    position: relative;
    z-index: 1;
  }

  .hero-copy {
    display: flex;
    flex-direction: column;
    gap: 0;
  }

  .hero-kicker {
    margin-bottom: 2px;
  }

  .hero-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 14px;
  }

  .hero-facts span {
    padding: 8px 11px;
    border-radius: 999px;
    background: rgba(255, 248, 238, 0.18);
    color: rgba(255, 242, 229, 0.96);
    font-size: 0.8rem;
    border: 1px solid rgba(255, 248, 238, 0.1);
    backdrop-filter: blur(12px);
  }

  .hero-nav {
    display: flex;
    align-items: center;
    gap: 10px;
    color: rgba(255, 242, 229, 0.86);
  }

  .rail-headline {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
  }

  .rail-count {
    display: inline-flex;
    align-items: center;
    min-height: 30px;
    padding: 0 10px;
    border-radius: 999px;
    background: rgba(255, 251, 245, 0.82);
    border: 1px solid rgba(153, 129, 102, 0.16);
    color: #6d5b4a;
    font-size: 0.78rem;
    font-weight: 600;
  }

  .cover-nav {
    width: 34px;
    height: 34px;
    border-radius: 999px;
    border: 1px solid rgba(255, 248, 238, 0.18);
    background: rgba(35, 25, 16, 0.26);
    color: inherit;
  }

  .rail-block,
  .map-panel,
  .guide-panel {
    background: rgba(249, 244, 237, 0.84);
    border: 1px solid rgba(153, 129, 102, 0.14);
    border-radius: 22px;
    box-shadow: 0 10px 34px rgba(89, 66, 44, 0.06);
  }

  .detail-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) 340px;
    gap: 22px;
    align-items: start;
  }

  .detail-main {
    display: flex;
    flex-direction: column;
    gap: 18px;
    min-width: 0;
  }

  .board-head {
    display: flex;
    justify-content: center;
  }

  .guide-copy h3,
  .rail-block h3 {
    margin: 6px 0 0;
    font-size: 1.55rem;
    line-height: 1.05;
    letter-spacing: -0.03em;
    color: #2f2218;
  }

  .board-tools {
    display: inline-grid;
    grid-auto-flow: column;
    gap: 8px;
    justify-content: center;
    width: auto;
    padding: 6px;
    border-radius: 18px;
    background: rgba(247, 240, 231, 0.92);
    border: 1px solid rgba(153, 129, 102, 0.14);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.5);
  }

  .board-chip {
    min-height: 44px;
    padding: 0 18px;
    border-radius: 14px;
    border: 1px solid transparent;
    background: transparent;
    color: #6f5b48;
    font-weight: 600;
  }

  .board-chip.active {
    background: #2f2218;
    color: #fbf5ee;
    border-color: #2f2218;
    box-shadow: 0 8px 18px rgba(51, 37, 24, 0.16);
  }

  .board-chip:not(.active) {
    background: rgba(255, 251, 245, 0.65);
  }

  .map-panel iframe {
    width: 100%;
    height: 220px;
    border: none;
    display: block;
    border-radius: 22px;
  }

  .map-empty,
  .guide-panel {
    padding: 22px;
  }

  .map-single {
    padding: 22px;
    display: flex;
    align-items: end;
    justify-content: space-between;
    gap: 16px;
  }

  .map-single h3 {
    margin: 6px 0 0;
    font-size: 1.35rem;
    line-height: 1.1;
    color: #2f2218;
  }

  .map-single p {
    margin: 10px 0 0;
    color: #6b5848;
    line-height: 1.6;
  }

  .map-link {
    min-height: 40px;
    padding: 0 14px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    background: #2f2218;
    color: #fbf5ee;
    white-space: nowrap;
  }

  .guide-panel p,
  .rail-block p {
    margin: 10px 0 0;
    color: #6b5848;
    line-height: 1.6;
  }

  .guide-suggestions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 16px;
  }

  .guide-suggestions span {
    padding: 8px 12px;
    border-radius: 999px;
    background: rgba(96, 74, 53, 0.08);
    color: #6a5542;
    font-size: 0.9rem;
  }

  .itinerary-board {
    display: flex;
    flex-direction: column;
    gap: 18px;
  }

  .day-block {
    position: relative;
    padding-top: 24px;
    margin-top: 10px;
  }

  .day-block::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 2px;
    background: linear-gradient(90deg, rgba(169, 114, 63, 0.34), rgba(169, 114, 63, 0.08));
  }

  .day-head {
    width: 100%;
    display: flex;
    align-items: start;
    justify-content: space-between;
    gap: 18px;
    background: none;
    border: none;
    text-align: left;
    padding: 0;
  }

  .day-title {
    display: flex;
    gap: 12px;
    align-items: center;
    min-width: 0;
  }

  .day-pill {
    min-width: 74px;
    min-height: 30px;
    padding: 0 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    font-size: 0.8rem;
    color: #8f4c24;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    background: rgba(190, 120, 62, 0.1);
    border: 1px solid rgba(190, 120, 62, 0.16);
  }

  .day-date {
    font-size: 1rem;
    letter-spacing: -0.02em;
    color: #2f2218;
    font-weight: 600;
  }

  .day-summary {
    margin-top: 6px;
    font-size: 0.9rem;
    color: #7a6552;
    font-weight: 500;
    overflow-wrap: anywhere;
    line-height: 1.2;
  }

  .day-count {
    font-size: 0.76rem;
    color: #7d6753;
    padding-top: 0;
    padding-inline: 10px;
    min-height: 28px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    background: rgba(96, 74, 53, 0.08);
  }

  .events-stack {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 16px 0 8px 88px;
  }

  .event-row {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    width: 100%;
    padding: 0;
    background: none;
    border: none;
    color: inherit;
    text-align: left;
    min-width: 0;
  }

  .event-time-column {
    width: 72px;
    flex-shrink: 0;
    padding-top: 12px;
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: #8c6f51;
    text-align: left;
  }

  .event-line {
    width: 1px;
    background: rgba(153, 129, 102, 0.18);
    align-self: stretch;
    position: relative;
  }

  .event-line::after {
    content: '';
    position: absolute;
    top: 12px;
    left: 50%;
    width: 9px;
    height: 9px;
    border-radius: 999px;
    transform: translateX(-50%);
    background: rgba(170, 108, 54, 0.82);
    box-shadow: 0 0 0 4px rgba(247, 240, 231, 1);
  }

  .event-card {
    flex: 1;
    min-width: 0;
    position: relative;
    padding: 15px 16px 15px;
    border-radius: 20px;
    border: 1px solid rgba(153, 129, 102, 0.12);
    background: rgba(252, 249, 245, 0.96);
    box-shadow: 0 8px 24px rgba(87, 64, 43, 0.04);
    overflow: hidden;
  }

  .event-card::before {
    content: '';
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    background: rgba(170, 108, 54, 0.16);
  }

  .event-stamp-mobile {
    display: none;
  }

  .event-thumb {
    width: 128px;
    min-height: 116px;
    border-radius: 20px;
    background-size: cover;
    background-position: center;
    background-color: rgba(226, 215, 200, 0.7);
    flex-shrink: 0;
    box-shadow: 0 14px 34px rgba(87, 64, 43, 0.08);
  }

  .event-top {
    display: flex;
    align-items: start;
    justify-content: space-between;
    gap: 10px;
    flex-direction: column;
  }

  .event-header-line {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
  }

  .event-kind {
    padding: 4px 8px;
    border-radius: 999px;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-weight: 700;
  }

  .event-name {
    margin-top: 2px;
    font-size: 1.06rem;
    line-height: 1.22;
    color: #2f2218;
    font-weight: 600;
  }

  .event-description {
    margin-top: 7px;
    color: #6d5947;
    line-height: 1.46;
    font-size: 0.88rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .event-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
    margin-top: 10px;
  }

  .event-meta span {
    padding: 0;
    border-radius: 0;
    background: none;
    color: #86725f;
    font-size: 0.73rem;
    position: relative;
  }

  .event-meta span:not(:last-child)::after {
    content: '•';
    margin-left: 7px;
    color: rgba(134, 114, 95, 0.6);
  }

  .empty-block,
  .note-card,
  .unscheduled-row,
  .stay-row {
    border-radius: 16px;
    background: rgba(250, 247, 242, 0.86);
    border: 1px solid rgba(153, 129, 102, 0.14);
  }

  .empty-block {
    padding: 16px;
    color: #7b6652;
  }

  .empty-day .day-head {
    opacity: 0.84;
  }

  .stay-row {
    display: grid;
    grid-template-columns: 60px minmax(0, 1fr);
    gap: 12px;
    padding: 13px 15px;
    text-align: left;
    color: inherit;
    background: rgba(248, 244, 238, 0.94);
  }

  .stay-label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: #8c6f51;
    padding-top: 4px;
  }

  .stay-main {
    min-width: 0;
  }

  .stay-name {
    font-size: 0.96rem;
    font-weight: 600;
    color: #2f2218;
  }

  .stay-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 6px;
  }

  .stay-meta span {
    padding: 5px 8px;
    border-radius: 999px;
    background: rgba(96, 74, 53, 0.08);
    color: #6f5b48;
    font-size: 0.76rem;
  }

  .detail-rail {
    display: flex;
    flex-direction: column;
    gap: 14px;
    position: sticky;
    top: 76px;
  }

  .rail-block {
    padding: 20px;
  }

  .notes-stack,
  .unscheduled-stack {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 14px;
  }

  .note-card,
  .unscheduled-row {
    padding: 14px;
  }

  .note-card {
    background: rgba(253, 250, 246, 0.96);
  }

  .note-card.muted {
    color: #7b6652;
  }

  .note-date {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: #8c6f51;
  }

  .note-content,
  .unscheduled-description {
    margin-top: 6px;
    color: #645140;
    line-height: 1.55;
  }

  .note-delete {
    margin-top: 10px;
    color: #a14f35;
    font-size: 0.84rem;
    background: none;
    border: none;
    padding: 0;
  }

  .note-compose {
    margin-top: 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding-top: 14px;
    border-top: 1px solid rgba(153, 129, 102, 0.12);
  }

  .note-compose textarea,
  .share-row input {
    width: 100%;
    border-radius: 16px;
    border: 1px solid rgba(153, 129, 102, 0.18);
    background: rgba(253, 250, 246, 0.96);
    padding: 12px 14px;
    color: #2f2218;
    font: inherit;
  }

  .rail-action,
  .share-row button {
    min-height: 40px;
    padding: 0 14px;
    border-radius: 999px;
    border: none;
    background: #2f2218;
    color: #fbf5ee;
    font: inherit;
  }

  .unscheduled-name {
    color: #2f2218;
    font-weight: 600;
  }

  .share-overlay,
  .fab-overlay {
    position: fixed;
    inset: 0;
    background: rgba(28, 21, 14, 0.32);
    z-index: 60;
  }

  .share-panel {
    width: min(520px, calc(100vw - 32px));
    margin: 10vh auto 0;
    background: rgba(250, 247, 242, 0.98);
    border-radius: 24px;
    padding: 22px;
    border: 1px solid rgba(153, 129, 102, 0.16);
    box-shadow: 0 22px 70px rgba(67, 47, 31, 0.15);
  }

  .share-row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 10px;
    margin-top: 14px;
  }

  .trip-fab {
    position: fixed;
    right: 22px;
    bottom: 20px;
    min-width: 64px;
    height: 52px;
    padding: 0 18px;
    border-radius: 999px;
    background: #2f2218;
    color: #fbf5ee;
    border: none;
    box-shadow: 0 18px 34px rgba(67, 47, 31, 0.22);
    z-index: 65;
  }

  .fab-sheet {
    position: fixed;
    right: 22px;
    bottom: 84px;
    width: min(300px, calc(100vw - 32px));
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    border-radius: 22px;
    background: rgba(250, 247, 242, 0.98);
    border: 1px solid rgba(153, 129, 102, 0.16);
    box-shadow: 0 22px 60px rgba(67, 47, 31, 0.16);
    z-index: 66;
  }

  .fab-sheet button {
    min-height: 44px;
    padding: 0 14px;
    border-radius: 14px;
    background: rgba(96, 74, 53, 0.07);
    color: #2f2218;
    border: none;
    text-align: left;
    font: inherit;
  }

  .fab-sheet button.danger {
    color: #9a442b;
    background: rgba(185, 77, 45, 0.08);
  }

  @media (max-width: 1040px) {
    .detail-grid {
      grid-template-columns: 1fr;
    }

    .detail-rail {
      position: static;
    }
  }

  @media (max-width: 720px) {
    .trip-workspace {
      gap: 16px;
      padding-bottom: 88px;
      padding-inline: 16px;
      -webkit-overflow-scrolling: touch;
    }

    .trip-hero {
      min-height: 280px;
      border-radius: 22px;
      padding: 18px 16px;
    }

    .hero-top {
      align-items: flex-start;
      margin-bottom: 22px;
    }

    .hero-tools {
      display: none;
    }

    .hero-copy h1 {
      font-size: clamp(2rem, 11vw, 3rem);
      letter-spacing: -0.035em;
    }

    .hero-meta {
      font-size: 0.94rem;
      line-height: 1.45;
    }

    .hero-copy p {
      max-width: 100%;
      font-size: 0.92rem;
    }

    .board-tools {
      width: 100%;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 6px;
      padding: 5px;
    }

    .board-chip {
      min-width: 0;
      padding: 0 12px;
      font-size: 0.92rem;
    }

    .map-single {
      padding: 18px;
      flex-direction: column;
      align-items: start;
    }

    .events-stack {
      padding-left: 0;
      padding-top: 12px;
    }

    .day-head {
      flex-direction: column;
      align-items: start;
      gap: 10px;
      padding: 0;
    }

    .day-title {
      gap: 10px;
      flex-direction: row;
      align-items: center;
    }

    .day-block {
      padding-top: 18px;
      margin-top: 8px;
    }

    .day-count {
      font-size: 0.78rem;
      min-height: 26px;
    }

    .event-row {
      flex-direction: column;
      gap: 0;
      overflow: hidden;
      border-radius: 20px;
      border: 1px solid rgba(153, 129, 102, 0.12);
      background: rgba(252, 249, 245, 0.96);
      box-shadow: 0 10px 26px rgba(87, 64, 43, 0.05);
    }

    .event-time-column {
      display: none;
    }

    .event-line {
      display: none;
    }

    .event-thumb {
      width: 100%;
      height: 156px;
      order: -1;
      border-radius: 0;
      box-shadow: none;
    }

    .event-stamp-mobile {
      display: inline-flex;
      align-items: center;
      min-height: 24px;
      margin-bottom: 0;
      padding: 0;
      border-radius: 999px;
      background: none;
      color: #8f4c24;
      font-size: 0.76rem;
      font-weight: 700;
      line-height: 1;
      text-transform: uppercase;
      letter-spacing: 0.1em;
    }

    .event-card {
      border: none;
      background: transparent;
      box-shadow: none;
      border-radius: 0;
      padding: 14px 14px 16px;
      width: 100%;
      box-sizing: border-box;
    }

    .event-card::before {
      display: none;
    }

    .event-top {
      display: flex;
      flex-direction: column;
      gap: 8px;
      align-items: stretch;
      width: 100%;
      box-sizing: border-box;
    }

    .event-header-line {
      display: grid;
      grid-template-columns: minmax(0, 1fr) auto;
      align-items: center;
      width: 100%;
      box-sizing: border-box;
      min-height: 24px;
      column-gap: 10px;
    }

    .event-stamp-mobile {
      justify-self: start;
    }

    .event-top .event-kind {
      min-height: 24px;
      display: inline-flex;
      align-items: center;
      position: static;
      margin: 0;
      white-space: nowrap;
      text-align: right;
      justify-self: end;
      align-self: center;
      max-width: none;
    }

    .event-kind {
      padding: 3px 7px;
      font-size: 0.64rem;
      letter-spacing: 0.08em;
    }

    .event-name {
      margin-top: 0;
      font-size: 1.02rem;
    }

    .events-stack .event-row:first-child .event-name {
      font-size: 1.02rem;
    }

    .event-description {
      font-size: 0.86rem;
    }

    .event-meta span {
      font-size: 0.72rem;
    }

    .events-stack .event-row:first-child {
      display: flex;
      box-shadow: 0 10px 26px rgba(87, 64, 43, 0.05);
    }

    .events-stack .event-row:first-child .event-thumb {
      height: 156px;
      min-height: 156px;
    }

    .stay-row {
      grid-template-columns: 1fr;
      gap: 8px;
      padding: 13px 14px 15px;
    }

    .stay-label {
      padding-top: 0;
    }

    .trip-fab {
      right: 16px;
      bottom: 72px;
    }

    .fab-sheet {
      right: 16px;
      left: 16px;
      width: auto;
      bottom: 136px;
    }
  }
</style>
