Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 184 additions & 0 deletions app.css
Original file line number Diff line number Diff line change
Expand Up @@ -5540,3 +5540,187 @@ footer a:hover { color: var(--accent-2); }
.cc-salary-box { margin: 0 1rem .6rem; padding: .6rem .8rem; }
.cc-skill-section, .cc-qual-section, .cc-overview { padding-left: 1rem; padding-right: 1rem; }
}

/* ── TouristTrip β€” Travel Itinerary ── */
.card.itinerary-card {
border-color: rgba(13,148,136,.12);
overflow: hidden;
}
.card.itinerary-card .hd.hidden { display: none; }

/* Hero header */
.ti-hero {
position: relative;
height: 260px;
overflow: hidden;
}
.ti-hero-img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.ti-hero-scrim {
position: absolute;
inset: 0;
background: linear-gradient(to bottom,
rgba(0,0,0,0) 0%,
rgba(0,0,0,.1) 40%,
rgba(0,0,0,.6) 70%,
rgba(0,0,0,.88) 100%);
pointer-events: none;
}
.ti-hero-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 0 1.5rem 1.2rem;
z-index: 2;
}
.ti-hero-icon {
font-size: 1.5rem;
display: block;
margin-bottom: .2rem;
}
.ti-hero-title {
font-size: 1.6rem;
font-weight: 800;
color: #fff;
line-height: 1.2;
letter-spacing: -.015em;
margin: 0;
text-shadow: 0 2px 12px rgba(0,0,0,.5);
}

/* Trip-style chips */
.ti-trip-chips {
display: flex;
flex-wrap: wrap;
gap: .35rem;
padding: .8rem 1.5rem .4rem;
}
.ti-trip-chip {
display: inline-flex;
align-items: center;
gap: .25rem;
font-size: .73rem;
font-weight: 600;
padding: .25rem .65rem;
border-radius: 4px;
background: rgba(13,148,136,.08);
color: #0d9488;
border: 1px solid rgba(13,148,136,.15);
}
.ti-chip-icon {
font-size: .8rem;
}

/* Section label */
.ti-section-label {
font-size: .7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .12em;
color: var(--muted-2);
margin-bottom: .4rem;
}

/* Vertical timeline */
.ti-timeline {
padding: .6rem 1.5rem .4rem;
position: relative;
}
.ti-timeline::before {
content: "";
position: absolute;
left: calc(1.5rem + 14px);
top: 1.2rem;
bottom: .8rem;
width: 2px;
background: linear-gradient(to bottom, #0d9488, #f59e0b);
border-radius: 1px;
}
.ti-timeline-stop {
display: flex;
gap: 1rem;
padding-bottom: 1rem;
position: relative;
}
.ti-timeline-dot {
flex-shrink: 0;
width: 30px; height: 30px;
border-radius: 50%;
background: linear-gradient(135deg, #0d9488, #14b8a6);
color: #fff;
font-size: .72rem;
font-weight: 800;
display: inline-flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 6px rgba(13,148,136,.3);
border: 2px solid var(--card-bg, #fff);
z-index: 1;
}
.ti-timeline-content {
flex: 1;
padding-top: .15rem;
}
.ti-timeline-label {
font-size: .72rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .1em;
color: #0d9488;
margin-bottom: .2rem;
}
.ti-timeline-body {
font-size: .82rem;
line-height: 1.65;
color: var(--ink-2);
margin: 0;
}

/* Overview fallback */
.ti-overview {
padding: .6rem 1.5rem .8rem;
}
.ti-overview-body {
font-size: .84rem;
line-height: 1.75;
color: var(--muted);
margin: 0;
}

/* Book CTA */
.ti-book-cta {
display: inline-flex;
align-items: center;
gap: .35rem;
margin: .4rem 1.5rem 1rem;
padding: .6rem 1.4rem;
background: linear-gradient(135deg, #0d9488, #f59e0b);
color: #fff;
font-size: .85rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .03em;
border-radius: 6px;
text-decoration: none;
box-shadow: 0 3px 10px rgba(13,148,136,.3);
transition: filter .15s;
}
.ti-book-cta:hover {
filter: brightness(1.1);
}

@media (max-width: 480px) {
.ti-hero { height: 200px; }
.ti-hero-title { font-size: 1.25rem; }
.ti-hero-overlay { padding: 0 1rem .8rem; }
.ti-trip-chips { padding: .6rem 1rem .3rem; }
.ti-timeline { padding: .5rem 1rem .3rem; }
.ti-timeline::before { left: calc(1rem + 14px); }
.ti-overview { padding: .5rem 1rem .6rem; }
.ti-book-cta { margin: .3rem 1rem .8rem; }
}
101 changes: 101 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3640,6 +3640,107 @@
}
}

// ── TOURISTTRIP (Travel Itinerary) ──
if (cfg.type === "TouristTrip") {
const card = document.querySelector(".card");
if (card) card.classList.add("itinerary-card");

// Hide normal header
const hd = document.querySelector(".hd");
if (hd) hd.classList.add("hidden");

// Remove generic hero
const heroMount = document.getElementById("hero-mount");
if (heroMount) heroMount.querySelector('.hero')?.remove();

// ── Hero header with trip name + image ──
const tiHeader = document.createElement("div"); tiHeader.className = "ti-hero";
const imgUrl = data["image"];
if (imgUrl) {
const img = document.createElement("img"); img.className = "ti-hero-img";
img.src = imgUrl; img.alt = data[cfg.titleProp] || "";
img.loading = "lazy";
tiHeader.appendChild(img);
const scrim = document.createElement("div"); scrim.className = "ti-hero-scrim";
tiHeader.appendChild(scrim);
handled.add("image");
}
const tiOverlay = document.createElement("div"); tiOverlay.className = "ti-hero-overlay";
const tiIcon = document.createElement("span"); tiIcon.className = "ti-hero-icon";
tiIcon.textContent = "\u{1F9C3}";
tiOverlay.appendChild(tiIcon);
const h1 = document.createElement("h1"); h1.className = "ti-hero-title";
h1.textContent = data[cfg.titleProp] || "";
tiOverlay.appendChild(h1);
tiHeader.appendChild(tiOverlay);
heroMount.appendChild(tiHeader);
handled.add("name");

// ── Trip-style chips from touristType ──
const touristType = data["touristType"];
if (touristType) {
const chipRow = document.createElement("div"); chipRow.className = "ti-trip-chips";
touristType.split(",").forEach(t => {
const chip = document.createElement("span"); chip.className = "ti-trip-chip";
chip.innerHTML = "<span class=\"ti-chip-icon\">\u{1F6E9}\uFE0F</span> " + t.trim();
chipRow.appendChild(chip);
});
view.appendChild(chipRow);
handled.add("touristType");
}

// ── Day-by-day timeline from description ──
const desc = data["description"];
if (desc) {
// Parse "Day one: ... Day two: ..." or "Day 1: ... Day 2: ..." patterns
const dayParts = desc.split(/\s*Day\s+(?:one|two|three|four|five|six|seven|eight|1|2|3|4|5|6|7|8)[:.]?\s*/i)
.filter(s => s.trim());
const dayLabels = desc.match(/Day\s+(?:one|two|three|four|five|six|seven|eight|1|2|3|4|5|6|7|8)[:.]?/gi);

if (dayParts.length >= 2 && dayLabels && dayLabels.length >= 2) {
// Render as vertical timeline
const timeline = document.createElement("div"); timeline.className = "ti-timeline";
dayParts.forEach((text, i) => {
const stop = document.createElement("div"); stop.className = "ti-timeline-stop";
const dot = document.createElement("div"); dot.className = "ti-timeline-dot";
dot.textContent = String(i + 1);
stop.appendChild(dot);
const content = document.createElement("div"); content.className = "ti-timeline-content";
const label = document.createElement("div"); label.className = "ti-timeline-label";
label.textContent = dayLabels[i] ? dayLabels[i].replace(/[:.]?$/, "") : ("Day " + (i + 1));
content.appendChild(label);
const body = document.createElement("p"); body.className = "ti-timeline-body";
body.textContent = text.trim();
content.appendChild(body);
stop.appendChild(content);
timeline.appendChild(stop);
});
view.appendChild(timeline);
} else {
// No day pattern β€” show as overview
const overview = document.createElement("div"); overview.className = "ti-overview";
const label = document.createElement("div"); label.className = "ti-section-label";
label.textContent = "Trip Overview";
overview.appendChild(label);
const body = document.createElement("p"); body.className = "ti-overview-body";
body.textContent = desc;
overview.appendChild(body);
view.appendChild(overview);
}
handled.add("description");
}

// ── Book This Trip CTA ──
const url = data["url"];
if (url) {
const cta = document.createElement("a"); cta.className = "ti-book-cta";
cta.href = url; cta.target = "_blank"; cta.rel = "noopener";
cta.innerHTML = "\u2708\uFE0F Book This Trip <span>\u2192</span>";
view.appendChild(cta);
handled.add("url");
}
}

return handled;
}

Expand Down
Loading