diff --git a/assets/images/header.jpg b/assets/images/header.jpg index 6678dc8..8ce0a33 100644 Binary files a/assets/images/header.jpg and b/assets/images/header.jpg differ diff --git a/assets/images/header.psd b/assets/images/header.psd new file mode 100644 index 0000000..7e94f31 Binary files /dev/null and b/assets/images/header.psd differ diff --git a/concert/concert.html b/concert/concert.html index 25a09c1..b53cc48 100644 --- a/concert/concert.html +++ b/concert/concert.html @@ -40,14 +40,24 @@ z-index: 5; } - /* 巡迴搜尋:輸入列 + 結果列表(黑底區,白字) */ + /* 巡迴搜尋:寬度/圓角對齊 .concert-container、.con-1 */ + .concert-page .search-section { + width: 100%; + max-width: 1200px; + margin-left: auto; + margin-right: auto; + padding-left: 20px; + padding-right: 20px; + box-sizing: border-box; + } + .concert-search-box { width: 100%; - max-width: 920px; - padding: 0 20px; + max-width: none; + padding: 0; display: flex; flex-direction: column; - align-items: center; + align-items: stretch; gap: 12px; } @@ -175,7 +185,6 @@ .concert-search-result { display: block; width: 100%; - max-width: 720px; } .concert-search-summary { @@ -186,57 +195,54 @@ color: #fff; } + /* 結果列表:結構複用 concert.css;外殼與下方 con-1 同寬同圓角 */ .concert-search-hits { - list-style: none; + width: 100%; + } + + body.concert-page .concert-search-mirror-card.con-1 { + width: 100%; + max-width: 100%; margin: 0; - padding: 0; - display: grid; - gap: 8px; - text-align: left; + border-radius: 16px; + padding: 50px 100px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05); + border: 1px solid rgba(0, 0, 0, 0.02); } - .concert-search-hits li { - padding: 10px 12px 10px 14px; - background: rgba(255, 255, 255, 0.06); - border: none; - border-left: 3px solid rgba(255, 204, 0, 0.55); - border-radius: 0 10px 10px 0; - font-size: 0.88rem; - line-height: 1.5; + @media (max-width: 920px) { + body.concert-page .search-section { + padding-left: clamp(12px, 3vw, 20px); + padding-right: clamp(12px, 3vw, 20px); + } + + body.concert-page .concert-search-mirror-card.con-1 { + padding: clamp(32px, 5vw, 44px) clamp(22px, 5vw, 48px); + } } - .concert-search-hits li.concert-search-hit-jump { + body.concert-page .concert-search-mirror-card .con-yk-1.concert-search-hit-jump { cursor: pointer; - transition: background 0.2s ease, border-color 0.2s ease; + transition: box-shadow 0.2s ease; } - .concert-search-hits li.concert-search-hit-jump:hover, - .concert-search-hits li.concert-search-hit-jump:focus-visible, - .concert-search-hits li.concert-search-hit-jump.is-active { - background: rgba(255, 204, 0, 0.12); - border-left-color: #ffcc00; + body.concert-page .concert-search-mirror-card .con-yk-1.concert-search-hit-jump:hover, + body.concert-page .concert-search-mirror-card .con-yk-1.concert-search-hit-jump:focus-visible { + box-shadow: 0 4px 14px rgba(255, 204, 0, 0.2); outline: none; } - .concert-search-hits .hit-track { - display: block; - font-weight: 700; - color: #ffdd00; + body.concert-page .concert-search-mirror-card .con-yk-1.concert-search-hit-jump.is-active { + box-shadow: 0 0 0 2px #ffcc00; } - .concert-search-hits .hit-meta { - display: block; - margin-top: 4px; - color: rgba(255, 255, 255, 0.72); - font-size: 0.8rem; - line-height: 1.5; - } - - .concert-search-hits .hit-more { + .concert-search-more { + margin: 10px 0 0; + padding: 8px 12px; text-align: center; - border-left-style: dashed; - color: rgba(255, 255, 255, 0.75); - cursor: default; + font-size: 0.85rem; + line-height: 1.5; + color: rgba(255, 255, 255, 0.8); } .track-item.is-search-hit .track { diff --git a/concert/search.js b/concert/search.js index 8ebf074..09f0100 100644 --- a/concert/search.js +++ b/concert/search.js @@ -60,12 +60,58 @@ function jumpToTrackHit(hit) { hit.el.scrollIntoView({ behavior: "smooth", block: "center" }); } -function setActiveSearchListItem(list, activeLi) { - if (!list) return; - list.querySelectorAll(".concert-search-hit-jump").forEach(function (item) { +function setActiveSearchHit(container, activeEl) { + if (!container) return; + container.querySelectorAll(".concert-search-hit-jump").forEach(function (item) { item.classList.remove("is-active"); }); - if (activeLi) activeLi.classList.add("is-active"); + if (activeEl) activeEl.classList.add("is-active"); +} + +function createSearchHitVenue(hit) { + const venue = document.createElement("div"); + venue.className = "con-yk-1"; + + const locText = [hit.tourTitle, hit.location].filter(Boolean).join(" · "); + if (locText) { + const loc = document.createElement("span"); + loc.className = "location"; + loc.textContent = locText; + venue.appendChild(loc); + } + + const trackList = document.createElement("div"); + trackList.className = "track-list"; + const trackItem = document.createElement("div"); + trackItem.className = "track-item"; + const trackSpan = document.createElement("span"); + trackSpan.className = "track"; + trackSpan.textContent = hit.trackName; + trackItem.appendChild(trackSpan); + trackList.appendChild(trackItem); + venue.appendChild(trackList); + + return venue; +} + +function bindSearchHitJump(venueEl, hit, container) { + venueEl.classList.add("concert-search-hit-jump"); + venueEl.setAttribute("role", "button"); + venueEl.setAttribute("tabindex", "0"); + venueEl.setAttribute("aria-label", `跳到曲目:${hit.trackName}`); + + function go() { + setActiveSearchHit(container, venueEl); + jumpToTrackHit(hit); + } + + venueEl.addEventListener("click", go); + venueEl.addEventListener("keydown", function (event) { + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + go(); + } + }); } function renderSearchResults(getQuery, getMember, hits) { @@ -88,50 +134,28 @@ function renderSearchResults(getQuery, getMember, hits) { summary.textContent = `曲目或場次「${getQuery}」:共 ${hits.length} 筆。請點列表中的場次,再跳到下方歌單。`; } - const list = document.createElement("ul"); - list.className = "concert-search-hits"; + const hitsWrap = document.createElement("div"); + hitsWrap.className = "concert-search-hits"; + + const mirrorCard = document.createElement("div"); + mirrorCard.className = "con-1 concert-search-mirror-card"; hits.slice(0, SEARCH_LIST_MAX).forEach(function (hit) { - const li = document.createElement("li"); - li.className = "concert-search-hit-jump"; - li.setAttribute("role", "button"); - li.setAttribute("tabindex", "0"); - li.setAttribute("aria-label", `跳到曲目:${hit.trackName}`); - - const trackLine = document.createElement("span"); - trackLine.className = "hit-track"; - trackLine.textContent = hit.trackName; - - const metaLine = document.createElement("span"); - metaLine.className = "hit-meta"; - metaLine.textContent = [hit.tourTitle, hit.location].filter(Boolean).join(" · "); - - li.appendChild(trackLine); - if (metaLine.textContent) li.appendChild(metaLine); - - li.addEventListener("click", function () { - setActiveSearchListItem(list, li); - jumpToTrackHit(hit); - }); - li.addEventListener("keydown", function (event) { - if (event.key === "Enter" || event.key === " ") { - event.preventDefault(); - setActiveSearchListItem(list, li); - jumpToTrackHit(hit); - } - }); - - list.appendChild(li); + const venue = createSearchHitVenue(hit); + bindSearchHitJump(venue, hit, mirrorCard); + mirrorCard.appendChild(venue); }); + hitsWrap.appendChild(mirrorCard); + if (hits.length > SEARCH_LIST_MAX) { - const more = document.createElement("li"); - more.className = "hit-more"; + const more = document.createElement("p"); + more.className = "concert-search-more"; more.textContent = `另有 ${hits.length - SEARCH_LIST_MAX} 筆未顯示,請縮小曲目或場次。`; - list.appendChild(more); + hitsWrap.appendChild(more); } - myResult.replaceChildren(summary, list); + myResult.replaceChildren(summary, hitsWrap); } function runSearch() {