@@ -7,7 +7,6 @@ import type { Course } from "../../types/schedule";
77 <div class =" modal-close-container" >
88 <span class =" close" >× </span >
99 </div >
10- <img id =" modalPersonImage" src =" " alt =" Speaker" class =" modal-person-image" style =" display: none;" />
1110 <h2 id =" modalTitle" class =" emfont-NotoSansTC-600" ></h2 >
1211 <h3 id =" modalSubtitle" class =" emfont-NotoSansTC-600" ></h3 >
1312 <div class =" section-title emfont-NotoSansTC-600" >課程介紹</div >
@@ -45,12 +44,12 @@ import type { Course } from "../../types/schedule";
4544 background-color: #028fdb;
4645 color: #efefef;
4746 padding: 3rem;
48- border-radius: 8px ;
47+ border-radius: 16px ;
4948 max-width: 800px;
5049 width: 90%;
5150 position: relative !important;
5251 margin: auto;
53- box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3 );
52+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4 );
5453 max-height: 96dvh;
5554 overflow-y: auto;
5655 -webkit-overflow-scrolling: touch;
@@ -203,47 +202,42 @@ import type { Course } from "../../types/schedule";
203202 border-bottom: 1px solid #a2a2a2;
204203 }
205204
206- .modal-person-image {
207- position: absolute;
208- top: 1.5rem;
209- right: 3.5rem;
210- width: 90px;
211- height: 90px;
212- border-radius: 50%;
213- object-fit: cover;
214- z-index: 5;
215- }
216-
217205 @media (max-width: 600px) {
218206 .modal {
219207 padding: 0;
220208 align-items: center;
221209 }
222210
223211 .modal-content {
224- padding: 1.5rem;
225- width: 90 %;
212+ padding: 2rem 1.5rem;
213+ width: 95 %;
226214 max-height: 90dvh;
227215 overflow-y: auto;
228- border-radius: 12px ;
229- margin: 0 0 env(safe-area-inset-bottom, 20px);
216+ border-radius: 18px ;
217+ margin: 2rem 0 env(safe-area-inset-bottom, 20px);
230218 -webkit-overflow-scrolling: touch;
231219 overscroll-behavior-y: contain;
232- padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 20px));
220+ padding-bottom: calc(2rem + env(safe-area-inset-bottom, 20px));
233221 }
234222
235223 #modalTitle {
236224 font-size: 1.5rem;
237225 padding-right: 0;
226+ line-height: 1.3;
238227 }
239228
240229 #modalSubtitle {
241230 font-size: 1rem;
242231 margin-bottom: 1.5rem;
243232 }
244233
245- .modal-person-image {
246- display: none;
234+ .section-title {
235+ font-size: 1.2rem;
236+ margin-top: 1.2rem;
237+ }
238+
239+ .description-container {
240+ margin-bottom: 1.5rem;
247241 }
248242
249243 .close-button {
@@ -263,20 +257,32 @@ import type { Course } from "../../types/schedule";
263257 font-size: 1.618rem !important;
264258 font-weight: 600;
265259 color: #efefef;
266- margin-bottom: 0.5rem ;
260+ margin-bottom: 0.8rem ;
267261 display: flex !important;
268262 place-items: center;
269- gap: 0.75rem !important;
263+ gap: 1rem !important;
270264 }
271265
272266 #speakerDescription .speaker-inline-image {
273- width: 40px ;
274- height: 40px ;
267+ width: 55px ;
268+ height: 55px ;
275269 border-radius: 50%;
276270 object-fit: cover;
277271 flex-shrink: 0;
278272 }
279273
274+ @media (max-width: 600px) {
275+ #speakerDescription .speaker-name {
276+ font-size: 1.4rem !important;
277+ gap: 0.75rem !important;
278+ }
279+
280+ #speakerDescription .speaker-inline-image {
281+ width: 45px;
282+ height: 45px;
283+ }
284+ }
285+
280286 #speakerDescription p {
281287 margin-bottom: 1rem;
282288 line-height: 1.6;
@@ -354,7 +360,12 @@ import type { Course } from "../../types/schedule";
354360 // Function to render markdown content
355361 function renderMarkdown(text) {
356362 if (!text) return '';
357- return marked.parse(text);
363+ try {
364+ return marked.parse(text);
365+ } catch (e) {
366+ console.error('Error parsing markdown:', e);
367+ return text; // Fallback to plain text
368+ }
358369 }
359370
360371 document.addEventListener("astro:page-load", () => {
@@ -393,7 +404,6 @@ import type { Course } from "../../types/schedule";
393404 const linksContainerEl = modalElement.querySelector("#modalLinks") as HTMLElement;
394405 const speakerSectionTitleEl = modalElement.querySelector("#speakerSectionTitle") as HTMLElement;
395406 const speakerDescriptionEl = modalElement.querySelector("#speakerDescription") as HTMLElement;
396- const modalPersonImageEl = modalElement.querySelector("#modalPersonImage") as HTMLImageElement;
397407
398408 if (modalTitleEl) modalTitleEl.textContent = course.zh.title?.split("\n")[0] || "";
399409 if (modalSubtitleEl) modalSubtitleEl.textContent = course.zh.title?.split("\n")[1] || "";
@@ -402,7 +412,6 @@ import type { Course } from "../../types/schedule";
402412 if (course.type === "Game") {
403413 if (speakerSectionTitleEl) speakerSectionTitleEl.style.display = "none";
404414 if (speakerDescriptionEl) speakerDescriptionEl.style.display = "none";
405- if (modalPersonImageEl) modalPersonImageEl.style.display = "none";
406415 } else if (course.type === "Community") {
407416 // Handle Community type events - show booth list instead of speakers
408417 if (speakerSectionTitleEl) {
@@ -427,7 +436,6 @@ import type { Course } from "../../types/schedule";
427436 }
428437 speakerDescriptionEl.classList.add("description-text");
429438 }
430- if (modalPersonImageEl) modalPersonImageEl.style.display = "none";
431439 } else {
432440 // Show speaker section for non-Game and non-Community events
433441 if (speakerSectionTitleEl) speakerSectionTitleEl.style.display = "block";
@@ -449,29 +457,18 @@ import type { Course } from "../../types/schedule";
449457 const speakersWithDesc = speakers?.filter(speaker => speaker.zh.bio && speaker.zh.bio.trim() !== "") || [];
450458
451459 if (speakers && speakers.length === 1) {
452- // Single speaker - show image in top-right position
460+ // Single speaker - add image in speaker section
453461 const speaker = speakers[0];
454- if (modalPersonImageEl && speaker.id) {
455- // Use .webp extension
456- modalPersonImageEl.src = `/2025/speakers/${speaker.id}.webp`;
457- modalPersonImageEl.style.display = "block";
458- modalPersonImageEl.onerror = () => {
459- modalPersonImageEl.style.display = "none";
460- };
461- }
462+ const imageHtml = speaker.id ? `<img src="/2025/speakers/${speaker.id}.webp" alt="${speaker.zh.name}" class="speaker-inline-image">` : "";
462463
463- // Show speaker description without inline image
464+ // Show speaker description with inline image
464465 if (speakersWithDesc.length > 0) {
465- speakerDescriptionEl.innerHTML = `<div class="speaker-name emfont-NotoSansTC-600">${speakersWithDesc[0].zh.name}</div>${renderMarkdown(speakersWithDesc[0].zh.bio)}`;
466+ speakerDescriptionEl.innerHTML = `<div class="speaker-name emfont-NotoSansTC-600">${imageHtml}<span>${ speakersWithDesc[0].zh.name}</span> </div>${renderMarkdown(speakersWithDesc[0].zh.bio)}`;
466467 } else if (speakerText) {
467- speakerDescriptionEl.innerHTML = `<div class="speaker-name emfont-NotoSansTC-600">${speaker.zh.name}</div>${speakerText}是本課程的講師。<br>其他資訊可能得等你自己通靈`;
468+ speakerDescriptionEl.innerHTML = `<div class="speaker-name emfont-NotoSansTC-600">${imageHtml}<span>${ speaker.zh.name}</span> </div>${speakerText}是本課程的講師。<br>其他資訊可能得等你自己通靈`;
468469 }
469470 } else if (speakers && speakers.length > 1) {
470- // Multiple speakers - hide top image and show inline images
471- if (modalPersonImageEl) {
472- modalPersonImageEl.style.display = "none";
473- }
474-
471+ // Multiple speakers with inline images
475472 if (speakersWithDesc.length > 0) {
476473 speakerDescriptionEl.innerHTML = speakersWithDesc.map(speaker => {
477474 // Use .webp extension
@@ -487,9 +484,6 @@ import type { Course } from "../../types/schedule";
487484 }
488485 } else {
489486 // No speakers
490- if (modalPersonImageEl) {
491- modalPersonImageEl.style.display = "none";
492- }
493487 speakerDescriptionEl.innerHTML = "無講者資訊";
494488 }
495489 speakerDescriptionEl.classList.add("description-text");
@@ -585,14 +579,16 @@ import type { Course } from "../../types/schedule";
585579
586580 // Close modal function
587581 const closeModal = () => {
588- if (modalElement) {
582+ if (modalElement && modalContent ) {
589583 modalContent.style.transform = "scale(0)";
590584 modalElement.style.backdropFilter = "blur(0px)";
591585 modalContent.style.transition = "transform .3s cubic-bezier(.5, 1, 0, 1)";
592586 modalElement.style.backgroundColor = "transparent";
593587 setTimeout(() => {
594588 modalElement.style.display = "none";
595- modalContent.style.transition = "transform .3s cubic-bezier(.5, 1, .1, 1.20)";
589+ if (modalContent) {
590+ modalContent.style.transition = "transform .3s cubic-bezier(.5, 1, .1, 1.20)";
591+ }
596592 }, 300);
597593 document.body.style.overflow = "";
598594 }
0 commit comments