departing rdu in
-- days
:
-- hrs
:
-- min
:
-- sec
rdu → dub · fri oct 2, 8:25 pm
Itinerary
Pick a day to see what’s on.
itinerary = FileAttachment ("itinerary.json" ). json ()
typeIcon = ({
"flight" : "🛫" ,
"arrival" : "🛬" ,
"food" : "🍽️" ,
"drinks" : "🍺" ,
"hotel" : "🛎️" ,
"sight" : "📍" ,
"activity" : "🎭" ,
"shop" : "🛍️" ,
"drive" : "🚗" ,
})
html `
<ul class="nav nav-tabs" role="tablist">
${ itinerary. map ((d, i) => `
<li class="nav-item" role="presentation">
<button class="nav-link ${ i === 0 ? ' active' : '' } "
data-bs-toggle="tab"
data-bs-target="#itin-panel- ${ i} "
type="button" role="tab"
aria-controls="itin-panel- ${ i} "
aria-selected=" ${ i === 0 ? 'true' : 'false' } ">
${ d. emoji } ${ d. date }
</button>
</li>
` ). join ("" )}
</ul>
<div class="tab-content mt-3">
${ itinerary. map ((d, i) => `
<div class="tab-pane fade ${ i === 0 ? ' show active' : '' } "
id="itin-panel- ${ i} " role="tabpanel">
<div class="itinerary-day-header">
<span class="itinerary-day-emoji"> ${ d. emoji } </span>
<span class="itinerary-day-title"> ${ d. date } — ${ d. city } </span>
</div>
<div class="itinerary-timeline">
${ d. items . map (item => `
<div class="itinerary-item itinerary-type- ${ item. type } ">
<div class="itinerary-time"> ${ item. time } </div>
<div class="itinerary-dot"></div>
<div class="itinerary-content">
<span class="itinerary-icon"> ${ typeIcon[item. type ] ?? "" } </span>
${ item. website ?
`<a href=" ${ item. website } " target="_blank" rel="noopener"
class="itinerary-link"> ${ item. text ?? "" } </a>`
: `<span class="itinerary-text"> ${ item. text } </span>` }
${ item. detail ?
`<span class="itinerary-detail"> ${ item. detail } </span>`
: "" }
${ item. needsBooking ?
`<span class="itinerary-needs-booking">Needs Booking</span>`
: "" }
</div>
</div>
` ). join ("" )}
</div>
</div>
` ). join ("" )}
</div>
`
Flights
flights = FileAttachment ("flights.json" ). json ()
html `
<div class="boarding-grid">
${ flights. map (f => `
<div class="boarding-pass">
<div class="bp-stub">
<div class="bp-airline">Aer<br>Lingus</div>
<div class="bp-flightno"> ${ f. flight } </div>
</div>
<div class="bp-body">
<div class="bp-route"> ${ f. fromCode } <span class="bp-arrow">✈</span> ${ f. toCode } </div>
<div class="bp-cities"> ${ f. from } → ${ f. to } </div>
<div class="bp-times">
<div><div class="lbl">Depart</div><div class="val"> ${ f. depart } </div></div>
<div><div class="lbl">Arrive</div><div class="val"> ${ f. arrive } </div></div>
<div><div class="lbl">Duration</div><div class="val"> ${ f. duration } </div></div>
</div>
<div class="bp-foot">
<span class="bp-date"> ${ f. date } </span>
<a class="bp-track" href="https://www.flightradar24.com/data/flights/ ${ f. track } "
target="_blank" rel="noopener">Track status ↗</a>
</div>
</div>
</div>` ). join ("" )}
</div>
`
Track links only go live within ~24h of each flight. Aer Lingus’s Dublin–Edinburgh hops (EI 3253/3254) are short-haul; if a tracker page is empty, try a quick search for the flight number instead.
Accommodations
Tap any photo to zoom; use the arrows to flip through each stay.
accommodations = FileAttachment ("accommodations.json" ). json ()
html `
<div class="trip-grid">
${ accommodations. map ((h, i) => `
<div class="trip-card">
<div id="lodge-car- ${ i} " class="carousel slide" data-bs-interval="false">
<div class="carousel-inner">
${ h. images . map ((src, j) => `
<div class="carousel-item ${ j === 0 ? ' active' : '' } ">
<a href=" ${ src} " class="glightbox" data-gallery="lodge- ${ i} ">
<img src=" ${ src} " class="trip-card-img" loading="lazy" alt=" ${ h. name } ">
</a>
</div>` ). join ("" )}
</div>
${ h. images . length > 1 ? `
<button class="carousel-control-prev" type="button" data-bs-target="#lodge-car- ${ i} " data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#lodge-car- ${ i} " data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
</button>` : `` }
</div>
<div class="trip-card-body">
<div class="trip-card-dates"> ${ h. dates } </div>
<h3 class="trip-card-name"> ${ h. name } </h3>
<div class="trip-card-loc"> ${ h. location } </div>
<div class="trip-card-room"> ${ h. room } </div>
<ul class="trip-card-amenities"> ${ h. amenities . map (a => `<li> ${ a} </li>` ). join ("" )} </ul>
<div class="trip-card-meta">
<span class="trip-card-phone"> ${ h. phone } </span>
<a class="trip-link" href=" ${ h. website } " target="_blank" rel="noopener">Website ↗</a>
</div>
</div>
</div>` ). join ("" )}
</div>
`
Dining
diningData = FileAttachment ("dining.json" ). json ()
Reservations
html `
<div class="trip-grid">
${ diningData. firmed . map ((r, i) => `
<div class="trip-card">
<div id="dine-car- ${ i} " class="carousel slide" data-bs-interval="false">
<div class="carousel-inner">
${ r. images . map ((src, j) => `
<div class="carousel-item ${ j === 0 ? ' active' : '' } ">
<a href=" ${ src} " class="glightbox" data-gallery="dine- ${ i} ">
<img src=" ${ src} " class="trip-card-img" loading="lazy" alt=" ${ r. name } ">
</a>
</div>` ). join ("" )}
</div>
${ r. images . length > 1 ? `
<button class="carousel-control-prev" type="button" data-bs-target="#dine-car- ${ i} " data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#dine-car- ${ i} " data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
</button>` : `` }
</div>
<div class="trip-card-body">
<div class="dining-row">
<span class="trip-card-dates"> ${ r. day } · ${ r. city } </span>
<span class="dining-time ${ r. anniversary ? ' is-anniv' : '' } "> ${ r. time } </span>
</div>
<h3 class="trip-card-name"> ${ r. name } </h3>
<div class="dining-cuisine"> ${ r. cuisine } </div>
${ r. anniversary ? `<div class="dining-anniv-flag">🎉 Anniversary dinner</div>` : `` }
<div class="trip-card-meta" style="border:0;padding-top:0;justify-content:flex-start;gap:1rem;">
<span class="trip-card-phone"> ${ r. phone } </span>
${ r. michelin ? `<a class="trip-link" href=" ${ r. michelin } " target="_blank" rel="noopener">Michelin ↗</a>` : `` }
</div>
<div class="menu-btns">
${ r. menus . map (m => `<a class="menu-btn" href=" ${ m. url } " target="_blank" rel="noopener"> ${ m. label } </a>` ). join ("" )}
</div>
</div>
</div>` ). join ("" )}
</div>
`
Other possibilities
{
const cities = Object . keys (diningData. possibilities );
return html `
<ul class="nav nav-tabs" role="tablist">
${ cities. map ((c, i) => `
<li class="nav-item" role="presentation">
<button class="nav-link ${ i === 0 ? ' active' : '' } " data-bs-toggle="tab"
data-bs-target="#poss- ${ i} " type="button" role="tab"> ${ c} </button>
</li>` ). join ("" )}
</ul>
<div class="tab-content mt-3">
${ cities. map ((c, i) => `
<div class="tab-pane fade ${ i === 0 ? ' show active' : '' } " id="poss- ${ i} " role="tabpanel">
<table class="poss-table">
<thead><tr><th>Place</th><th>Type</th><th>Notes</th></tr></thead>
<tbody>
${ diningData. possibilities [c]. map (p => `
<tr>
<td class="poss-name"> ${ p. name } </td>
<td class="poss-type"> ${ p. type } </td>
<td> ${ p. notes } </td>
</tr>` ). join ("" )}
</tbody>
</table>
</div>` ). join ("" )}
</div>` ;
}
Drives
drives = FileAttachment ("drives.json" ). json ()
Rental car
html `
<div class="car-card">
<a href=" ${ drives. car . image } " class="glightbox" data-gallery="car">
<img src=" ${ drives. car . image } " alt=" ${ drives. car . vehicle } ">
</a>
<div class="car-card-body">
<h3> ${ drives. car . vehicle } </h3>
<div class="car-card-co"> ${ drives. car . company } · ${ drives. car . location } </div>
<div class="car-card-grid">
<div><div class="lbl">Pick-up</div><div class="val"> ${ drives. car . pickup } </div></div>
<div><div class="lbl">Return</div><div class="val"> ${ drives. car . return } </div></div>
<div><div class="lbl">Phone</div><div class="val"> ${ drives. car . phone } </div></div>
</div>
<div class="car-card-note"> ${ drives. car . notes } </div>
</div>
</div>
<div class="drive-summary">
${ drives. days . map (d => `<span class="pill"> ${ d. date } : <b> ${ d. total } </b></span>` ). join ("" )}
</div>
`
Day-by-day routes
html `
${ drives. days . map ((d, di) => `
<div class="drive-day">
<div class="drive-day-title"> ${ d. date } — ${ d. title } <span class="total"> ${ d. total } </span></div>
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#d ${ di} -overall"
type="button" role="tab">Overall</button>
</li>
${ d. legs . map ((leg, li) => `
<li class="nav-item" role="presentation">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#d ${ di} -leg ${ li} "
type="button" role="tab"> ${ leg. from } → ${ leg. to } </button>
</li>` ). join ("" )}
</ul>
<div class="tab-content mt-3">
<div class="tab-pane fade show active" id="d ${ di} -overall" role="tabpanel">
<iframe class="drive-map" src=" ${ d. overallMap } " loading="lazy"
referrerpolicy="no-referrer-when-downgrade"></iframe>
<ul class="drive-notes"> ${ d. notes . map (n => `<li> ${ n} </li>` ). join ("" )} </ul>
</div>
${ d. legs . map ((leg, li) => `
<div class="tab-pane fade" id="d ${ di} -leg ${ li} " role="tabpanel">
<div class="drive-leg-meta">
<div><div class="lbl">Distance</div><div class="val"> ${ leg. distance } </div></div>
<div><div class="lbl">Drive time</div><div class="val"> ${ leg. duration } </div></div>
</div>
<iframe class="drive-map" src=" ${ leg. map } " loading="lazy"
referrerpolicy="no-referrer-when-downgrade"></iframe>
<ul class="drive-notes"> ${ leg. notes . map (n => `<li> ${ n} </li>` ). join ("" )} </ul>
</div>` ). join ("" )}
</div>
</div>` ). join ("" )}
`
Dublin
Places
Temple Bar — Historic cultural quarter, good for a first-night wander
Guinness Storehouse — Book tickets in advance
Long Room & Book of Kells — Trinity College; also book ahead
Dublin Castle — Free to walk the grounds
Marsh’s Library — Hidden gem, oldest public library in Ireland (1707)
Edinburgh
Neighborhoods & Walks
Stockbridge — Right by the hotel. Cobbled streets, Georgian terraces, the Sunday market
Dean Village — 10-min walk from Stockbridge along the Water of Leith; very photogenic
Circus Lane — Quick detour from Stockbridge; best for photos
Royal Mile — The backbone of Old Town; do it at least once
Victoria Street — Curved, colorful street; the Harry Potter / Diagon Alley one
Sights
Edinburgh Castle — Book tickets online. Consider the Afternoon Tea add-on
The Vennel Viewpoint — Free, underrated, best castle photo angle in the city
Palace of Holyroodhouse — Bottom of the Royal Mile; royal residence
National Portrait Gallery — Free; good for a slower morning
Isle of Skye
You’re self-driving from Fort William via Eilean Donan and the Skye Bridge — see the Drives section for legs and timings. Leave Skye by early afternoon on Sat Oct 10 so the return isn’t in the dark.
Sights
Old Man of Storr — ~20 min north of Portree; the classic Skye hike/photo
Kilt Rock & Mealt Falls — Roadside viewpoint, easy stop
The Quiraing — Otherworldly landslip landscape (longer detour)
Fairy Pools — Crystal pools below the Cuillins (west side; longer drive)
Drink & Experiences
Isle of Skye Distillers — Tasting room in Portree
Untethered Skye — Experiences & guided activities
Skye dining ideas are in the Dining section above.
Practical Notes
Ireland — US citizens don’t need a visa for short stays, but Ireland is not in the Schengen Area. Confirm requirements before travel.
Scotland / UK — No visa required for US citizens for stays under 6 months. You may need to show proof of onward travel at the border.
{
// Re-bind GLightbox to the dynamically rendered gallery images
accommodations; diningData; drives;
setTimeout (() => {
if (window . GLightbox ) {
if (window . _tripLightbox && window . _tripLightbox . reload ) window . _tripLightbox . reload ();
else window . _tripLightbox = GLightbox ({ selector : ".glightbox" });
}
}, 300 );
return html `<span style="display:none" aria-hidden="true"></span>` ;
}