@@ -18,22 +18,24 @@ const { tapes, id } = Astro.props;
1818---
1919
2020<div class =" tape-carousel" id ={ id } data-tape-carousel >
21- <div class =" tc-track" >
22- { tapes .map ((tape ) => (
23- <div class = " tc-slide" >
24- <div class = " tape-block" >
25- <div class = " tape-header" >
26- { tape .icon && <img src = { tape .icon } alt = " " class = " tape-logo" loading = " lazy" aria-hidden = " true" onerror = " this.style.display='none'" />}
27- <h4 >{ tape .title } </h4 >
21+ <div class =" tc-viewport" >
22+ <div class =" tc-track" >
23+ { tapes .map ((tape ) => (
24+ <div class = " tc-slide" >
25+ <div class = " tape-block" >
26+ <div class = " tape-header" >
27+ { tape .icon && <img src = { tape .icon } alt = " " class = " tape-logo" loading = " lazy" aria-hidden = " true" onerror = " this.style.display='none'" />}
28+ <h4 >{ tape .title } </h4 >
29+ </div >
30+ <p class = " tape-desc" >{ tape .description } </p >
31+ <Video src = { tape .src } title = { tape .title } caption = { tape .caption } />
2832 </div >
29- <p class = " tape-desc" >{ tape .description } </p >
30- <Video src = { tape .src } title = { tape .title } caption = { tape .caption } />
3133 </div >
32- </div >
33- ))}
34+ ))}
35+ </div >
36+ <button class =" tc-btn tc-prev" aria-label =" Previous" >← </button >
37+ <button class =" tc-btn tc-next" aria-label =" Next" >→ </button >
3438 </div >
35- <button class =" tc-btn tc-prev" aria-label =" Previous" >← </button >
36- <button class =" tc-btn tc-next" aria-label =" Next" >→ </button >
3739 <div class =" tc-dots" >
3840 { tapes .map ((tape , i ) => (
3941 <button class :list = { [' tc-dot' , { active: i === 0 }]} aria-label = { tape .title } data-index = { i } ></button >
@@ -43,6 +45,7 @@ const { tapes, id } = Astro.props;
4345
4446<script >
4547 document.querySelectorAll('[data-tape-carousel]').forEach((carousel) => {
48+ const viewport = carousel.querySelector('.tc-viewport') as HTMLElement;
4649 const track = carousel.querySelector('.tc-track') as HTMLElement;
4750 const slides = carousel.querySelectorAll('.tc-slide');
4851 const dots = carousel.querySelectorAll('.tc-dot');
@@ -68,8 +71,8 @@ const { tapes, id } = Astro.props;
6871 dots.forEach((dot) => dot.addEventListener('click', () => goTo(Number((dot as HTMLElement).dataset.index))));
6972
7073 let startX = 0;
71- track .addEventListener('touchstart', (e) => { startX = (e as TouchEvent).touches[0].clientX; }, { passive: true });
72- track .addEventListener('touchend', (e) => {
74+ viewport .addEventListener('touchstart', (e) => { startX = (e as TouchEvent).touches[0].clientX; }, { passive: true });
75+ viewport .addEventListener('touchend', (e) => {
7376 const dx = (e as TouchEvent).changedTouches[0].clientX - startX;
7477 if (Math.abs(dx) > 50) goTo(current + (dx < 0 ? 1 : -1));
7578 });
@@ -80,7 +83,12 @@ const { tapes, id } = Astro.props;
8083 .tape-carousel {
8184 position: relative;
8285 margin: 2rem 0;
86+ }
87+
88+ .tc-viewport {
89+ position: relative;
8390 overflow: hidden;
91+ border-radius: 8px;
8492 }
8593
8694 .tc-track {
@@ -91,6 +99,8 @@ const { tapes, id } = Astro.props;
9199 .tc-slide {
92100 min-width: 100%;
93101 flex-shrink: 0;
102+ box-sizing: border-box;
103+ padding: 0 0.25rem;
94104 }
95105
96106 /* Tape block styling (inline — no separate component needed in carousel) */
@@ -152,8 +162,8 @@ const { tapes, id } = Astro.props;
152162 background: var(--color-bg);
153163 }
154164
155- .tc-prev { left: -0.5rem ; }
156- .tc-next { right: -0.5rem ; }
165+ .tc-prev { left: 0.75rem ; }
166+ .tc-next { right: 0.75rem ; }
157167
158168 .tc-dots {
159169 display: flex;
0 commit comments