1423 lines
45 KiB
HTML
1423 lines
45 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<title>Taekwondo Match Card</title>
|
||
<style>
|
||
body { font-family: system-ui, sans-serif; margin: 0; background: #020617; color: #e5e7eb; } /* [page:1] */
|
||
.page { max-width: 1280px; margin: 0 auto; padding: 24px 16px 64px; }
|
||
|
||
.video-shell {
|
||
background: #020617;
|
||
border-radius: 16px;
|
||
padding: 16px;
|
||
box-shadow: 0 18px 60px rgba(0,0,0,.75);
|
||
position: relative;
|
||
overflow: hidden;
|
||
border: 1px solid #111827;
|
||
}
|
||
|
||
.video-wrapper { position: relative; }
|
||
video { width: 100%; border-radius: 12px; background: #000; }
|
||
video::-webkit-media-controls { display:none !important; }
|
||
|
||
.controls { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }
|
||
.controls-top { display: flex; align-items: center; gap: 10px; }
|
||
.play-btn {
|
||
width: 26px; height: 26px;
|
||
border-radius: 999px; border: 1px solid #111827;
|
||
background: #020314;
|
||
display:flex; align-items:center; justify-content:center;
|
||
cursor:pointer; color:#e5e7eb; font-size:14px;
|
||
}
|
||
.time-labels { font-size: 0.8rem; color: #9ca3af; display:flex; gap:8px; align-items:center; }
|
||
.progress-wrapper { position:relative; width:100%; height:16px; display:flex; align-items:center; cursor:pointer; }
|
||
.progress-bar {
|
||
position:relative; width:100%; height:4px;
|
||
border-radius:999px; background:#020314; border:1px solid #111827;
|
||
overflow:hidden;
|
||
}
|
||
.progress-fill { position:absolute; left:0; top:0; bottom:0; width:0%; background:linear-gradient(90deg,#06b6d4,#22d3ee); }
|
||
.progress-handle {
|
||
position:absolute; top:50%; width:10px; height:10px;
|
||
border-radius:999px; background:#e5e7eb; box-shadow:0 0 0 2px #020314;
|
||
transform:translate(-50%,-50%); pointer-events:none;
|
||
}
|
||
|
||
.event-header {
|
||
display:flex;
|
||
align-items:center;
|
||
justify-content:space-between;
|
||
gap:12px;
|
||
margin-top:16px;
|
||
}
|
||
.event-header-left {
|
||
display:flex;
|
||
align-items:center;
|
||
gap:12px;
|
||
min-width:0;
|
||
}
|
||
.event-logo {
|
||
width:56px;
|
||
height:56px;
|
||
border-radius:14px;
|
||
overflow:hidden;
|
||
background:#020314;
|
||
border:1px solid #1f2937;
|
||
flex-shrink:0;
|
||
display:flex;
|
||
align-items:center;
|
||
justify-content:center;
|
||
}
|
||
.event-logo img { width:100%; height:100%; object-fit:contain; }
|
||
.event-text {
|
||
display:flex;
|
||
flex-direction:column;
|
||
gap:2px;
|
||
min-width:0;
|
||
}
|
||
.title { font-size: 1.4rem; margin: 0; }
|
||
.meta { font-size: 0.85rem; color: #9ca3af; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
|
||
|
||
.event-header-actions {
|
||
display:flex;
|
||
align-items:center;
|
||
gap:6px;
|
||
flex-shrink:0;
|
||
}
|
||
.btn-icon {
|
||
border:none;
|
||
border-radius:999px;
|
||
padding:5px 10px;
|
||
font-size:0.78rem;
|
||
cursor:pointer;
|
||
background:#020314;
|
||
border:1px solid #1f2937;
|
||
color:#d1d5db;
|
||
display:flex;
|
||
align-items:center;
|
||
gap:4px;
|
||
}
|
||
.btn-icon span:first-child { font-size:0.9rem; }
|
||
|
||
.match-card {
|
||
margin-top: 16px;
|
||
padding: 16px 18px;
|
||
border-radius: 14px;
|
||
border: 1px solid #111827;
|
||
background: radial-gradient(circle at top, #020314 0, #020617 45%, #020617 100%);
|
||
}
|
||
|
||
.match-header {
|
||
display:flex;
|
||
justify-content:space-between;
|
||
align-items:center;
|
||
margin-bottom:12px;
|
||
}
|
||
.match-label {
|
||
font-size:0.8rem;
|
||
text-transform:uppercase;
|
||
letter-spacing:0.16em;
|
||
color:#9ca3af;
|
||
}
|
||
|
||
.fighters-row {
|
||
display:grid;
|
||
grid-template-columns: 1.1fr 0.8fr 1.1fr;
|
||
align-items:stretch;
|
||
gap: 16px;
|
||
}
|
||
|
||
.fighter-card {
|
||
background: #020314;
|
||
border-radius: 14px;
|
||
padding: 10px;
|
||
border: 1px solid #111827;
|
||
display:flex;
|
||
flex-direction:column;
|
||
align-items:center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.fighter-top {
|
||
display:flex;
|
||
align-items:center;
|
||
justify-content:center;
|
||
gap:10px;
|
||
width:100%;
|
||
}
|
||
|
||
.fighter-photo {
|
||
width:110px; height:145px;
|
||
border-radius:12px;
|
||
overflow:hidden;
|
||
box-shadow:0 0 0 1px #020617;
|
||
flex-shrink:0;
|
||
}
|
||
.fighter-photo img { width:100%; height:100%; object-fit:cover; }
|
||
|
||
.fighter-logo {
|
||
width:64px; height:64px;
|
||
border-radius:20px;
|
||
overflow:hidden;
|
||
background:#020617;
|
||
}
|
||
.fighter-logo img { width:100%; height:100%; object-fit:contain; }
|
||
|
||
.fighter-badge {
|
||
font-size:0.75rem;
|
||
text-transform:uppercase;
|
||
letter-spacing:0.12em;
|
||
padding:3px 8px;
|
||
border-radius:999px;
|
||
border:1px solid #1f2937;
|
||
color:#e5e7eb;
|
||
}
|
||
.fighter-badge.blue { background:rgba(37,99,235,.15); border-color:#1d4ed8; }
|
||
.fighter-badge.red { background:rgba(239,68,68,.14); border-color:#b91c1c; }
|
||
|
||
.fighter-info {
|
||
display:flex;
|
||
flex-direction:column;
|
||
gap:2px;
|
||
width:100%;
|
||
text-align:center;
|
||
font-size:0.8rem;
|
||
}
|
||
.fighter-name { font-weight:600; font-size:0.95rem; }
|
||
.fighter-team { color:#9ca3af; }
|
||
.fighter-country {
|
||
display:inline-flex;
|
||
justify-content:center;
|
||
align-items:center;
|
||
gap:4px;
|
||
color:#9ca3af;
|
||
margin-top:2px;
|
||
}
|
||
.fighter-country-flag { font-size:0.9rem; }
|
||
|
||
.match-center {
|
||
display:flex;
|
||
flex-direction:column;
|
||
align-items:center;
|
||
justify-content:space-between;
|
||
gap:10px;
|
||
}
|
||
.score-pill {
|
||
display:flex;
|
||
align-items:center;
|
||
justify-content:center;
|
||
gap:8px;
|
||
padding:6px 12px;
|
||
border-radius:999px;
|
||
background:#020314;
|
||
border:1px solid #111827;
|
||
}
|
||
.score-number { font-size:2.0rem; font-weight:700; }
|
||
.score-label { font-size:0.75rem; color:#9ca3af; }
|
||
|
||
.referee-block {
|
||
display:flex;
|
||
flex-direction:column;
|
||
align-items:center;
|
||
gap:4px;
|
||
}
|
||
.ref-photo {
|
||
width:54px; height:54px;
|
||
border-radius:999px;
|
||
overflow:hidden;
|
||
border:2px solid #020314;
|
||
box-shadow:0 0 0 1px #020617;
|
||
}
|
||
.ref-photo img { width:100%; height:100%; object-fit:cover; }
|
||
.ref-name { font-size:0.75rem; color:#e5e7eb; }
|
||
.ref-label { font-size:0.7rem; color:#9ca3af; }
|
||
|
||
.match-footer {
|
||
margin-top:12px;
|
||
font-size:0.8rem;
|
||
color:#6b7280;
|
||
text-align:center;
|
||
}
|
||
|
||
.markdown-body { font-size: 0.95rem; line-height: 1.6; margin-top: 16px; }
|
||
.markdown-body h2 { font-size: 1.05rem; margin-top: 14px; }
|
||
|
||
.description-panel {
|
||
margin-top: 16px;
|
||
border-radius: 12px;
|
||
border: 1px solid #111827;
|
||
background: #020314;
|
||
padding: 8px 10px 10px;
|
||
}
|
||
|
||
.description-toggle {
|
||
width: 100%;
|
||
border: none;
|
||
background: transparent;
|
||
color: #e5e7eb;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
font-size: 0.85rem;
|
||
cursor: pointer;
|
||
padding: 4px 0;
|
||
}
|
||
|
||
.description-toggle:hover {
|
||
color: #f9fafb;
|
||
}
|
||
|
||
.description-body {
|
||
margin-top: 6px;
|
||
display: none;
|
||
}
|
||
|
||
.description-body.open {
|
||
display: block;
|
||
}
|
||
|
||
.coach-modal-backdrop,
|
||
.comment-modal-backdrop,
|
||
.share-modal-backdrop {
|
||
position:fixed;
|
||
inset:0;
|
||
background:rgba(15,23,42,0.8);
|
||
display:none;
|
||
align-items:center;
|
||
justify-content:center;
|
||
z-index:50;
|
||
}
|
||
.coach-modal-backdrop.open,
|
||
.comment-modal-backdrop.open,
|
||
.share-modal-backdrop.open {
|
||
display:flex;
|
||
}
|
||
.coach-modal,
|
||
.comment-modal,
|
||
.share-modal {
|
||
width:100%;
|
||
max-width:620px;
|
||
background:#020617;
|
||
border-radius:14px;
|
||
border:1px solid #111827;
|
||
box-shadow:0 20px 60px rgba(0,0,0,.8);
|
||
padding:14px 16px 16px;
|
||
}
|
||
.coach-modal-header,
|
||
.comment-modal-header,
|
||
.share-modal-header {
|
||
display:flex;
|
||
justify-content:space-between;
|
||
align-items:center;
|
||
margin-bottom:8px;
|
||
}
|
||
.coach-modal-header h3,
|
||
.comment-modal-header h3,
|
||
.share-modal-header h3 {
|
||
margin:0;
|
||
font-size:0.95rem;
|
||
}
|
||
.coach-modal-close,
|
||
.comment-modal-close,
|
||
.share-modal-close {
|
||
border:none;
|
||
background:transparent;
|
||
color:#9ca3af;
|
||
cursor:pointer;
|
||
font-size:1.2rem;
|
||
line-height:1;
|
||
}
|
||
.coach-panel-hint,
|
||
.comment-panel-hint {
|
||
font-size:0.78rem;
|
||
color:#9ca3af;
|
||
margin-bottom:8px;
|
||
}
|
||
.coach-form-row {
|
||
display:grid;
|
||
grid-template-columns: 0.9fr 1.1fr;
|
||
gap:10px;
|
||
align-items:flex-start;
|
||
margin-bottom:8px;
|
||
}
|
||
.coach-emoji-select {
|
||
display:flex;
|
||
gap:4px;
|
||
flex-wrap:wrap;
|
||
background:#020314;
|
||
border-radius:999px;
|
||
padding:3px 6px;
|
||
border:1px solid #111827;
|
||
}
|
||
.coach-emoji-select button {
|
||
border:none;
|
||
background:transparent;
|
||
cursor:pointer;
|
||
font-size:1rem;
|
||
line-height:1;
|
||
}
|
||
.coach-time-range {
|
||
display:flex;
|
||
gap:6px;
|
||
align-items:center;
|
||
font-size:0.8rem;
|
||
color:#9ca3af;
|
||
}
|
||
.coach-time-range input {
|
||
width:70px;
|
||
padding:4px 6px;
|
||
border-radius:6px;
|
||
border:1px solid #111827;
|
||
background:#020314;
|
||
color:#e5e7eb;
|
||
font-size:0.8rem;
|
||
}
|
||
.coach-comment textarea {
|
||
width:100%;
|
||
min-height:60px;
|
||
resize:vertical;
|
||
border-radius:8px;
|
||
border:1px solid #111827;
|
||
background:#020314;
|
||
color:#e5e7eb;
|
||
font-size:0.85rem;
|
||
padding:6px 8px;
|
||
}
|
||
.coach-actions,
|
||
.comment-modal-actions,
|
||
.share-modal-actions {
|
||
display:flex;
|
||
justify-content:flex-end;
|
||
margin-top:6px;
|
||
gap:8px;
|
||
}
|
||
.btn-small {
|
||
border:none;
|
||
border-radius:999px;
|
||
padding:5px 10px;
|
||
font-size:0.75rem;
|
||
cursor:pointer;
|
||
background:#06b6d4;
|
||
color:#0f172a;
|
||
}
|
||
.btn-small:hover { background:#22d3ee; }
|
||
|
||
.btn-ghost {
|
||
border:1px solid #111827;
|
||
border-radius:999px;
|
||
padding:5px 10px;
|
||
font-size:0.75rem;
|
||
cursor:pointer;
|
||
background:#020314;
|
||
color:#9ca3af;
|
||
}
|
||
|
||
.comments-panel {
|
||
margin-top:18px;
|
||
padding:14px 16px;
|
||
border-radius:12px;
|
||
border:1px solid #111827;
|
||
background:#020314;
|
||
}
|
||
.comments-panel-header {
|
||
display:flex;
|
||
justify-content:space-between;
|
||
align-items:center;
|
||
margin-bottom:8px;
|
||
}
|
||
.comments-tabs {
|
||
display:flex;
|
||
gap:6px;
|
||
}
|
||
.comments-tab {
|
||
border:none;
|
||
border-radius:999px;
|
||
padding:4px 8px;
|
||
font-size:0.75rem;
|
||
cursor:pointer;
|
||
background:transparent;
|
||
color:#9ca3af;
|
||
border:1px solid transparent;
|
||
}
|
||
.comments-tab.active {
|
||
background:#06b6d4;
|
||
color:#0f172a;
|
||
border-color:#06b6d4;
|
||
}
|
||
|
||
.comments-list {
|
||
border-top:1px solid #111827;
|
||
padding-top:8px;
|
||
margin-top:4px;
|
||
}
|
||
.comment-item {
|
||
display:flex;
|
||
gap:8px;
|
||
padding:6px 0;
|
||
border-bottom:1px solid #020617;
|
||
}
|
||
.comment-avatar {
|
||
width:28px;
|
||
height:28px;
|
||
border-radius:999px;
|
||
overflow:hidden;
|
||
background:#020314;
|
||
flex-shrink:0;
|
||
}
|
||
.comment-avatar img { width:100%; height:100%; object-fit:cover; }
|
||
.comment-body { flex:1; }
|
||
.comment-header-line {
|
||
display:flex;
|
||
align-items:center;
|
||
gap:6px;
|
||
font-size:0.78rem;
|
||
color:#9ca3af;
|
||
}
|
||
.comment-author { font-weight:500; color:#e5e7eb; }
|
||
.comment-time-chip {
|
||
padding:2px 6px;
|
||
border-radius:999px;
|
||
border:1px solid #1f2937;
|
||
background:#020314;
|
||
font-size:0.75rem;
|
||
cursor:pointer;
|
||
color:#93c5fd;
|
||
}
|
||
.comment-content { margin-top:2px; font-size:0.85rem; }
|
||
.comment-actions {
|
||
margin-top:4px;
|
||
font-size:0.75rem;
|
||
color:#6b7280;
|
||
display:flex;
|
||
gap:10px;
|
||
align-items:center;
|
||
}
|
||
.comment-actions button {
|
||
border:none;
|
||
background:transparent;
|
||
color:#6b7280;
|
||
cursor:pointer;
|
||
font-size:0.75rem;
|
||
padding:0;
|
||
}
|
||
.reply-item {
|
||
margin-top:4px;
|
||
margin-left:24px;
|
||
padding-left:8px;
|
||
border-left:1px solid #111827;
|
||
font-size:0.8rem;
|
||
color:#9ca3af;
|
||
}
|
||
|
||
.comment-modal-body {
|
||
display:flex;
|
||
flex-direction:column;
|
||
gap:8px;
|
||
}
|
||
.comment-row {
|
||
display:flex;
|
||
gap:8px;
|
||
flex-wrap:wrap;
|
||
align-items:center;
|
||
}
|
||
.comment-timestamp-type {
|
||
display:flex;
|
||
gap:6px;
|
||
font-size:0.78rem;
|
||
color:#9ca3af;
|
||
}
|
||
.comment-timestamp-type button {
|
||
border:none;
|
||
border-radius:999px;
|
||
padding:3px 8px;
|
||
background:#020314;
|
||
border:1px solid #111827;
|
||
color:#9ca3af;
|
||
cursor:pointer;
|
||
font-size:0.75rem;
|
||
}
|
||
.comment-timestamp-type button.active {
|
||
background:#06b6d4;
|
||
color:#0f172a;
|
||
border-color:#06b6d4;
|
||
}
|
||
.comment-time-inputs {
|
||
display:flex;
|
||
gap:6px;
|
||
align-items:center;
|
||
font-size:0.8rem;
|
||
color:#9ca3af;
|
||
}
|
||
.comment-time-inputs input {
|
||
width:70px;
|
||
padding:4px 6px;
|
||
border-radius:6px;
|
||
border:1px solid #111827;
|
||
background:#020314;
|
||
color:#e5e7eb;
|
||
font-size:0.8rem;
|
||
}
|
||
.comment-textarea {
|
||
width:100%;
|
||
min-height:60px;
|
||
resize:vertical;
|
||
border-radius:8px;
|
||
border:1px solid #111827;
|
||
background:#020314;
|
||
color:#e5e7eb;
|
||
font-size:0.85rem;
|
||
padding:6px 8px;
|
||
}
|
||
.comment-like-toggle {
|
||
display:flex;
|
||
align-items:center;
|
||
gap:4px;
|
||
font-size:0.8rem;
|
||
color:#9ca3af;
|
||
}
|
||
|
||
.share-options {
|
||
display:flex;
|
||
flex-wrap:wrap;
|
||
gap:8px;
|
||
margin-bottom:10px;
|
||
}
|
||
.share-pill {
|
||
border:none;
|
||
border-radius:999px;
|
||
padding:6px 10px;
|
||
font-size:0.8rem;
|
||
cursor:pointer;
|
||
background:#020314;
|
||
border:1px solid #111827;
|
||
color:#d1d5db;
|
||
display:flex;
|
||
align-items:center;
|
||
gap:6px;
|
||
}
|
||
.share-link-wrapper {
|
||
display:flex;
|
||
gap:6px;
|
||
align-items:center;
|
||
font-size:0.8rem;
|
||
color:#9ca3af;
|
||
}
|
||
.share-link-wrapper input {
|
||
flex:1;
|
||
padding:4px 6px;
|
||
border-radius:6px;
|
||
border:1px solid #111827;
|
||
background:#020314;
|
||
color:#e5e7eb;
|
||
font-size:0.8rem;
|
||
}
|
||
|
||
.events-sidebar {
|
||
position: fixed;
|
||
top: 0;
|
||
right: 0;
|
||
width: 340px;
|
||
max-width: 80vw;
|
||
height: 100vh;
|
||
background: #020617;
|
||
border-left: 1px solid #111827;
|
||
box-shadow: -12px 0 40px rgba(0,0,0,.6);
|
||
transform: translateX(100%);
|
||
transition: transform 0.3s ease-out;
|
||
display: flex;
|
||
flex-direction: column;
|
||
z-index: 40;
|
||
}
|
||
.events-sidebar.open { transform: translateX(0); }
|
||
|
||
.events-sidebar-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 10px 14px;
|
||
border-bottom: 1px solid #111827;
|
||
}
|
||
.events-sidebar-header h3 { margin: 0; font-size: 0.95rem; }
|
||
.close-btn {
|
||
border: none; background: transparent; color: #9ca3af;
|
||
cursor: pointer; font-size: 1rem;
|
||
}
|
||
|
||
.tab-header {
|
||
display: flex; gap: 6px;
|
||
margin: 10px 12px 6px;
|
||
border-bottom: 1px solid #111827;
|
||
padding-bottom: 4px;
|
||
}
|
||
.tab-button {
|
||
flex: 1; text-align: center; padding: 6px 0;
|
||
font-size: 0.85rem; color: #9ca3af; cursor: pointer;
|
||
border-radius: 999px; background: transparent; border: none;
|
||
position: relative;
|
||
}
|
||
.tab-button.active {
|
||
background: #020314; color: #e5e7eb; font-weight: 500;
|
||
}
|
||
.tab-button.active::after {
|
||
content: ""; position: absolute; left: 8px; right: 8px; bottom: -4px;
|
||
height: 4px; background: #020617;
|
||
}
|
||
|
||
.tab-panels { flex: 1; overflow-y: auto; padding: 0 10px 12px; min-height: 0; }
|
||
.tab-panel { display: none; }
|
||
.tab-panel.active { display: block; }
|
||
|
||
.event-list { margin-top: 6px; border-top: 1px solid #111827; padding-top: 6px; }
|
||
.event-item {
|
||
display: grid; grid-template-columns: auto 1fr;
|
||
gap: 6px 10px; padding: 6px 4px;
|
||
border-radius: 6px; cursor: pointer;
|
||
}
|
||
.event-item:hover { background: #020314; }
|
||
.event-time {
|
||
font-size: 0.8rem;
|
||
color: #93c5fd;
|
||
min-width: 80px;
|
||
text-align: center;
|
||
}
|
||
.event-label { font-size: 0.9rem; }
|
||
.event-meta { font-size: 0.75rem; color: #6b7280; }
|
||
.pill { display:inline-block; padding:2px 6px; border-radius:999px; font-size:0.7rem; margin-left:4px; }
|
||
.pill-blue { background:rgba(59,130,246,.18); color:#bfdbfe; }
|
||
.pill-red { background:rgba(248,113,113,.16); color:#fecaca; }
|
||
.section-label { text-transform:uppercase; font-size:0.75rem; letter-spacing:.08em; color:#6b7280; margin:4px 0 2px; }
|
||
|
||
/* Round marker between points */
|
||
.round-marker {
|
||
display:flex;
|
||
align-items:center;
|
||
justify-content:center;
|
||
padding:4px 8px;
|
||
border-radius:999px;
|
||
background:#facc15;
|
||
color:#000;
|
||
font-size:0.8rem;
|
||
font-weight:700;
|
||
margin:4px 0;
|
||
}
|
||
|
||
.events-controller {
|
||
position: absolute;
|
||
top: 28px;
|
||
right: 28px;
|
||
display:flex;
|
||
gap:8px;
|
||
z-index:20;
|
||
}
|
||
.events-controller button {
|
||
border:none; border-radius:999px; padding:6px 10px;
|
||
font-size:0.75rem; cursor:pointer;
|
||
background:rgba(15,23,42,0.9); color:#d1d5db; border:1px solid #111827;
|
||
}
|
||
.events-controller button:hover { background:#020314; }
|
||
|
||
@media (max-width: 900px) {
|
||
.fighters-row { grid-template-columns: 1fr; }
|
||
.match-center { order: -1; }
|
||
.event-header { flex-direction:column; align-items:flex-start; }
|
||
.event-header-actions { align-self:flex-end; }
|
||
.coach-form-row { grid-template-columns: 1fr; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="page">
|
||
<div class="video-shell">
|
||
<div class="events-controller">
|
||
<button data-open-sidebar="both">Bookmarks</button>
|
||
</div>
|
||
|
||
<div class="video-wrapper">
|
||
<video id="sportsVideo" src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"></video>
|
||
|
||
<div class="controls">
|
||
<div class="controls-top">
|
||
<button class="play-btn" id="playPauseBtn">►</button>
|
||
<div class="time-labels">
|
||
<span id="currentTimeLabel">0:00</span>
|
||
<span>/</span>
|
||
<span id="durationLabel">0:00</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="progress-wrapper" id="progressWrapper">
|
||
<div class="progress-bar" id="progressBar">
|
||
<div class="progress-fill" id="progressFill"></div>
|
||
<div class="progress-handle" id="progressHandle"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="event-header">
|
||
<div class="event-header-left">
|
||
<div class="event-logo">
|
||
<img src="https://picsum.photos/seed/event-logo/200/200" alt="Event logo">
|
||
</div>
|
||
<div class="event-text">
|
||
<h1 class="title">Taekwondo Finals – Blue vs Red (U18)</h1>
|
||
<div class="meta">Championship 2026 • Court 2 • Best of 3 rounds</div>
|
||
</div>
|
||
</div>
|
||
<div class="event-header-actions">
|
||
<button class="btn-icon" type="button" id="shareVideoBtn">
|
||
<span>⤴️</span>
|
||
<span>Share</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Collapsible card + description (YouTube style) -->
|
||
<section class="description-panel">
|
||
<button class="description-toggle" type="button" id="toggleDescription">
|
||
<span id="descriptionToggleLabel">Show description</span>
|
||
<span id="descriptionToggleIcon">▼</span>
|
||
</button>
|
||
|
||
<div class="description-body" id="descriptionBody">
|
||
<!-- Match card inside collapsible body -->
|
||
<section class="match-card">
|
||
<div class="match-header">
|
||
<div class="match-label">Final • Male -63kg division</div>
|
||
</div>
|
||
|
||
<div class="fighters-row">
|
||
<article class="fighter-card">
|
||
<div class="fighter-top">
|
||
<div class="fighter-photo">
|
||
<img src="https://picsum.photos/seed/blue-competitor/200/260" alt="Blue fighter">
|
||
</div>
|
||
<div style="display:flex; flex-direction:column; align-items:center; gap:8px;">
|
||
<div class="fighter-logo">
|
||
<img src="https://picsum.photos/seed/blue-logo/160/160" alt="Blue team logo">
|
||
</div>
|
||
<span class="fighter-badge blue">Blue</span>
|
||
</div>
|
||
</div>
|
||
<div class="fighter-info">
|
||
<div class="fighter-name">Ali Mohammed</div>
|
||
<div class="fighter-team">Blue Dragons Club</div>
|
||
<div class="fighter-country">
|
||
<span class="fighter-country-flag">🇧🇭</span>
|
||
<span>Bahrain</span>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
|
||
<div class="match-center">
|
||
<div class="score-pill">
|
||
<span class="score-number">7</span>
|
||
<span class="score-label">Final score</span>
|
||
<span class="score-number">5</span>
|
||
</div>
|
||
<div class="referee-block">
|
||
<div class="ref-photo">
|
||
<img src="https://picsum.photos/seed/referee/160/160" alt="Referee">
|
||
</div>
|
||
<div class="ref-name">M. Al‑Khalifa</div>
|
||
<div class="ref-label">Center Referee</div>
|
||
</div>
|
||
</div>
|
||
|
||
<article class="fighter-card">
|
||
<div class="fighter-top">
|
||
<div style="display:flex; flex-direction:column; align-items:center; gap:8px;">
|
||
<div class="fighter-logo">
|
||
<img src="https://picsum.photos/seed/red-logo/160/160" alt="Red team logo">
|
||
</div>
|
||
<span class="fighter-badge red">Red</span>
|
||
</div>
|
||
<div class="fighter-photo">
|
||
<img src="https://picsum.photos/seed/red-competitor/200/260" alt="Red fighter">
|
||
</div>
|
||
</div>
|
||
<div class="fighter-info">
|
||
<div class="fighter-name">Omar Al‑Khaled</div>
|
||
<div class="fighter-team">Red Tigers TKD</div>
|
||
<div class="fighter-country">
|
||
<span class="fighter-country-flag">🇸🇦</span>
|
||
<span>Saudi Arabia</span>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
|
||
<div class="match-footer">
|
||
Manama Sports Hall • Electronic scoring system (PSS & head‑gear) • Video replay available for head kicks and gam-jeom appeals
|
||
</div>
|
||
</section>
|
||
|
||
<section class="markdown-body">
|
||
<div style="font-size:0.8rem; color:#9ca3af; margin-bottom:4px;">
|
||
3 x 2:00 rounds • Golden point if tied
|
||
</div>
|
||
<h2>Match overview</h2>
|
||
<p>
|
||
This final features two explosive male U18 -63kg fighters: Blue builds pressure with strong body kicks and ring control, while Red
|
||
waits to counter with head shots and angle changes. Use this replay to analyze how each fighter manages distance after exchanges,
|
||
how quickly they reset their guard, and where hesitation after conceding points changes the momentum of the round.
|
||
</p>
|
||
<p>
|
||
Coaches can also focus on corner instructions between rounds, the timing of tactical time-outs, and how often each athlete follows
|
||
the game plan under fatigue in the closing 30 seconds of every round.
|
||
</p>
|
||
</section>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Comments always visible -->
|
||
<section class="comments-panel">
|
||
<div class="comments-panel-header">
|
||
<h3 style="margin:0; font-size:0.95rem;">Comments & replies</h3>
|
||
<div style="display:flex; align-items:center; gap:6px;">
|
||
<div class="comments-tabs">
|
||
<button class="comments-tab active" type="button">All</button>
|
||
<button class="comments-tab" type="button">Highlights</button>
|
||
</div>
|
||
<button class="btn-icon" type="button" id="openCommentModal">
|
||
💬
|
||
<span>Comment</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="comments-list">
|
||
<div class="comment-item">
|
||
<div class="comment-avatar">
|
||
<img src="https://picsum.photos/seed/user1/80/80" alt="User avatar">
|
||
</div>
|
||
<div class="comment-body">
|
||
<div class="comment-header-line">
|
||
<span class="comment-author">Viewer_21</span>
|
||
<span>•</span>
|
||
<span>2 min ago</span>
|
||
<span>•</span>
|
||
<span class="comment-time-chip">@00:32–00:50</span>
|
||
</div>
|
||
<div class="comment-content">
|
||
Love how Blue keeps pressure here, but you can see the guard dropping right after scoring.
|
||
</div>
|
||
<div class="comment-actions">
|
||
<button type="button">Reply</button>
|
||
<span>12 likes</span>
|
||
</div>
|
||
<div class="reply-item">
|
||
<strong>Coach Ahmed:</strong> Exactly. This is the clip we use in training when we talk about “score and cover”.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="comment-item">
|
||
<div class="comment-avatar">
|
||
<img src="https://picsum.photos/seed/user2/80/80" alt="User avatar">
|
||
</div>
|
||
<div class="comment-body">
|
||
<div class="comment-header-line">
|
||
<span class="comment-author">TKDfan</span>
|
||
<span>•</span>
|
||
<span>10 min ago</span>
|
||
<span>•</span>
|
||
<span class="comment-time-chip">@full video</span>
|
||
</div>
|
||
<div class="comment-content">
|
||
Great match overall, both fighters stayed active until the last seconds. Respect to both teams.
|
||
</div>
|
||
<div class="comment-actions">
|
||
<button type="button">Reply</button>
|
||
<span>5 likes</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Comment modal -->
|
||
<div class="comment-modal-backdrop" id="commentModal">
|
||
<div class="comment-modal" role="dialog" aria-modal="true">
|
||
<div class="comment-modal-header">
|
||
<h3>Add comment</h3>
|
||
<button class="comment-modal-close" id="closeCommentModal" aria-label="Close comment">×</button>
|
||
</div>
|
||
<div class="comment-panel-hint">
|
||
Choose how you want to link this comment: whole video, a single time stamp, or a time range for a specific exchange.
|
||
</div>
|
||
<div class="comment-modal-body">
|
||
<div class="comment-row">
|
||
<div class="comment-timestamp-type">
|
||
<span style="font-size:0.78rem;">Link type:</span>
|
||
<button type="button" class="active">Video</button>
|
||
<button type="button">Time stamp</button>
|
||
<button type="button">Time range</button>
|
||
</div>
|
||
<div class="comment-time-inputs">
|
||
<span>From</span>
|
||
<input type="text" placeholder="00:45">
|
||
<span>To</span>
|
||
<input type="text" placeholder="01:10">
|
||
</div>
|
||
</div>
|
||
<textarea class="comment-textarea" placeholder="Share your thoughts about this match or this moment..."></textarea>
|
||
<div style="display:flex; justify-content:space-between; align-items:center; margin-top:4px;">
|
||
<label class="comment-like-toggle">
|
||
<input type="checkbox" style="accent-color:#22c55e; margin:0;">
|
||
<span>Like this video</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="comment-modal-actions">
|
||
<button class="btn-ghost" type="button" id="cancelCommentModal">Cancel</button>
|
||
<button class="btn-small" type="button">Post comment</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Share modal -->
|
||
<div class="share-modal-backdrop" id="shareModal">
|
||
<div class="share-modal" role="dialog" aria-modal="true">
|
||
<div class="share-modal-header">
|
||
<h3>Share this match</h3>
|
||
<button class="share-modal-close" id="closeShareModal" aria-label="Close share">×</button>
|
||
</div>
|
||
<p style="font-size:0.8rem; color:#9ca3af; margin:4px 0 8px;">
|
||
Copy a link or share directly to your favorite apps.
|
||
</p>
|
||
<div class="share-options">
|
||
<button class="share-pill" type="button">
|
||
📨 <span>Copy link</span>
|
||
</button>
|
||
<button class="share-pill" type="button">
|
||
💬 <span>WhatsApp</span>
|
||
</button>
|
||
<button class="share-pill" type="button">
|
||
🐦 <span>Twitter / X</span>
|
||
</button>
|
||
<button class="share-pill" type="button">
|
||
📘 <span>Facebook</span>
|
||
</button>
|
||
</div>
|
||
<div class="share-link-wrapper">
|
||
<span>Link</span>
|
||
<input type="text" value="https://example.com/video/taekwondo-finals" readonly>
|
||
</div>
|
||
<div class="share-modal-actions">
|
||
<button class="btn-ghost" type="button" id="cancelShareModal">Close</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Points / Foul modal -->
|
||
<div class="coach-modal-backdrop" id="pointsModal">
|
||
<div class="coach-modal" role="dialog" aria-modal="true">
|
||
<div class="coach-modal-header">
|
||
<h3>Register point / foul</h3>
|
||
<button class="coach-modal-close" id="closePointsModal" aria-label="Close points modal">×</button>
|
||
</div>
|
||
<div class="coach-panel-hint">
|
||
Select the round, fighter, and whether this is a point or a foul, then set the time and impact on the score.
|
||
</div>
|
||
|
||
<div class="coach-form-row">
|
||
<div>
|
||
<div style="font-size:0.75rem; color:#9ca3af; margin-bottom:4px;">Type</div>
|
||
<div class="coach-emoji-select">
|
||
<button type="button" data-type="point">🥋</button>
|
||
<button type="button" data-type="foul">⚠️</button>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div style="font-size:0.75rem; color:#9ca3af; margin-bottom:4px;">Round / fighter</div>
|
||
<div style="display:flex; gap:6px; flex-wrap:wrap; font-size:0.8rem;">
|
||
<select style="flex:1; min-width:80px; padding:4px 6px; border-radius:6px; border:1px solid #111827; background:#020314; color:#e5e7eb;">
|
||
<option>Round 1</option>
|
||
<option>Round 2</option>
|
||
<option>Round 3</option>
|
||
</select>
|
||
<select style="flex:1; min-width:80px; padding:4px 6px; border-radius:6px; border:1px solid #111827; background:#020314; color:#e5e7eb;">
|
||
<option>Blue</option>
|
||
<option>Red</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="coach-form-row">
|
||
<div>
|
||
<div style="font-size:0.75rem; color:#9ca3af; margin-bottom:4px;">Time</div>
|
||
<div class="coach-time-range">
|
||
<span>At</span>
|
||
<input type="text" placeholder="01:12">
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div style="font-size:0.75rem; color:#9ca3af; margin-bottom:4px;">Impact on score</div>
|
||
<div style="display:flex; gap:6px; align-items:center; font-size:0.8rem; color:#9ca3af;">
|
||
<span>Δ score</span>
|
||
<input type="number" placeholder="+1 / -1" style="width:80px; padding:4px 6px; border-radius:6px; border:1px solid #111827; background:#020314; color:#e5e7eb;">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="coach-comment">
|
||
<div style="font-size:0.75rem; color:#9ca3af; margin-bottom:4px;">Note (optional)</div>
|
||
<textarea placeholder="E.g. body kick scored, gam-jeom for pushing, etc."></textarea>
|
||
</div>
|
||
|
||
<div class="coach-actions">
|
||
<button class="btn-ghost" type="button" id="cancelPointsModal">Cancel</button>
|
||
<button class="btn-small" type="button">Add event</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<aside class="events-sidebar" id="eventsSidebar">
|
||
<div class="events-sidebar-header">
|
||
<h3>Match events</h3>
|
||
<button class="close-btn" id="closeSidebar">×</button>
|
||
</div>
|
||
|
||
<div class="tab-header">
|
||
<button class="tab-button active" data-tab="official">Points</button>
|
||
<button class="tab-button" data-tab="review">Coach review</button>
|
||
</div>
|
||
|
||
<div class="tab-panels">
|
||
<div class="tab-panel active" id="tab-official">
|
||
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:4px;">
|
||
<div>
|
||
<div class="section-label">Rounds & points</div>
|
||
</div>
|
||
<button class="btn-icon" type="button" id="openPointsModal">
|
||
➕
|
||
<!--<span>Add point</span>-->
|
||
</button>
|
||
</div>
|
||
|
||
<div class="event-list" id="officialEvents">
|
||
|
||
<!-- Round marker for Round 1 -->
|
||
<div class="round-marker">ROUND 1</div>
|
||
|
||
<!-- Round 1 points -->
|
||
<div class="event-item" data-time-start="20">
|
||
<div class="event-time">@00:20</div>
|
||
<div>
|
||
<div class="event-label">
|
||
Blue body kick (1 pt)
|
||
<span class="pill pill-blue">Blue</span>
|
||
</div>
|
||
<div class="event-meta">Round 1 • Score 1 – 0 • Clean contact.</div>
|
||
</div>
|
||
</div>
|
||
<div class="event-item" data-time-start="45">
|
||
<div class="event-time">@00:45</div>
|
||
<div>
|
||
<div class="event-label">
|
||
Blue scores body kick
|
||
<span class="pill pill-blue">Blue</span>
|
||
</div>
|
||
<div class="event-meta">Round 1 • Score 2 – 0 • Judge: Central.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Round marker for Round 2 -->
|
||
<div class="round-marker">ROUND 2</div>
|
||
|
||
<!-- Round 2 points -->
|
||
<div class="event-item" data-time-start="90">
|
||
<div class="event-time">@01:30</div>
|
||
<div>
|
||
<div class="event-label">
|
||
Red head kick (3 pts)
|
||
<span class="pill pill-red">Red</span>
|
||
</div>
|
||
<div class="event-meta">Round 2 • Score 2 – 3 • Video replay requested.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- You can add more Round markers like this:
|
||
<div class="round-marker">ROUND 3</div>
|
||
followed by that round's events.
|
||
-->
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tab-panel" id="tab-review">
|
||
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:4px;">
|
||
<div class="section-label">Private notes</div>
|
||
<button class="btn-icon" type="button" id="openCoachModalFromSidebar">
|
||
➕
|
||
<!--<span>Coach note</span>-->
|
||
</button>
|
||
</div>
|
||
<div class="event-list" id="reviewEvents">
|
||
<div class="event-item" data-time-start="32" data-time-end="50">
|
||
<div style="display:flex; flex-direction:column; align-items:center; justify-content:center;">
|
||
<div style="font-size:1.2rem; margin-bottom:2px;">🔥</div>
|
||
<div class="event-time">@00:32–00:50</div>
|
||
</div>
|
||
<div>
|
||
<div class="event-label">Good pressure, but guard too low after first kick</div>
|
||
<div class="event-meta">
|
||
Coach Ahmed • Hands drop after scoring, drill guard recovery immediately.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="event-item" data-time-start="125" data-time-end="140">
|
||
<div style="display:flex; flex-direction:column; align-items:center; justify-content:center;">
|
||
<div style="font-size:1.2rem; margin-bottom:2px;">🤔</div>
|
||
<div class="event-time">@02:05–02:20</div>
|
||
</div>
|
||
<div>
|
||
<div class="event-label">Missed counter opportunity</div>
|
||
<div class="event-meta">
|
||
Coach Sara • Great angle, but no follow up. Use this clip to discuss risk vs reward.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="event-item" data-time-start="205">
|
||
<div style="display:flex; flex-direction:column; align-items:center; justify-content:center;">
|
||
<div style="font-size:1.2rem; margin-bottom:2px;">😄</div>
|
||
<div class="event-time">@03:25</div>
|
||
</div>
|
||
<div>
|
||
<div class="event-label">Excellent angle change and follow-up</div>
|
||
<div class="event-meta">
|
||
Coach Ahmed • Save as positive highlight, ideal example of exit and re-entry after scoring.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
<script>
|
||
const video = document.getElementById('sportsVideo');
|
||
const playBtn = document.getElementById('playPauseBtn');
|
||
const progressBar = document.getElementById('progressBar');
|
||
const progressFill = document.getElementById('progressFill');
|
||
const progressHandle = document.getElementById('progressHandle');
|
||
const currentTimeLabel = document.getElementById('currentTimeLabel');
|
||
const durationLabel = document.getElementById('durationLabel');
|
||
|
||
function formatTime(t) {
|
||
if (!isFinite(t)) return '0:00';
|
||
const m = Math.floor(t / 60);
|
||
const s = Math.floor(t % 60).toString().padStart(2, '0');
|
||
return `${m}:${s}`;
|
||
}
|
||
|
||
function updateTimeUI() {
|
||
currentTimeLabel.textContent = formatTime(video.currentTime);
|
||
durationLabel.textContent = formatTime(video.duration);
|
||
const ratio = video.duration ? video.currentTime / video.duration : 0;
|
||
const pct = Math.max(0, Math.min(1, ratio)) * 100;
|
||
progressFill.style.width = pct + '%';
|
||
progressHandle.style.left = pct + '%';
|
||
}
|
||
|
||
video.addEventListener('timeupdate', updateTimeUI);
|
||
video.addEventListener('loadedmetadata', updateTimeUI);
|
||
|
||
playBtn.addEventListener('click', () => {
|
||
if (video.paused) {
|
||
video.play();
|
||
playBtn.textContent = '❚❚';
|
||
} else {
|
||
video.pause();
|
||
playBtn.textContent = '►';
|
||
}
|
||
});
|
||
|
||
video.addEventListener('play', () => { playBtn.textContent = '❚❚'; });
|
||
video.addEventListener('pause', () => { playBtn.textContent = '►'; });
|
||
|
||
function seekToRatio(ratio) {
|
||
if (!video.duration) return;
|
||
const clamped = Math.max(0, Math.min(1, ratio));
|
||
video.currentTime = clamped * video.duration;
|
||
}
|
||
|
||
progressBar.addEventListener('click', (e) => {
|
||
const rect = progressBar.getBoundingClientRect();
|
||
const ratio = (e.clientX - rect.left) / rect.width;
|
||
seekToRatio(ratio);
|
||
});
|
||
|
||
function seekWithOptionalSegment(start, end) {
|
||
video.currentTime = start;
|
||
video.play();
|
||
if (!isNaN(end) && end > start) {
|
||
const handler = () => {
|
||
if (video.currentTime >= end) {
|
||
video.pause();
|
||
video.removeEventListener('timeupdate', handler);
|
||
}
|
||
};
|
||
video.addEventListener('timeupdate', handler);
|
||
}
|
||
}
|
||
|
||
function attachEvents(containerId) {
|
||
const container = document.getElementById(containerId);
|
||
if (!container || !video) return;
|
||
container.addEventListener('click', (e) => {
|
||
const item = e.target.closest('.event-item');
|
||
if (!item) return;
|
||
const start = parseFloat(item.dataset.timeStart || '0');
|
||
const end = parseFloat(item.dataset.timeEnd || '0');
|
||
seekWithOptionalSegment(start, end);
|
||
});
|
||
}
|
||
|
||
const sidebar = document.getElementById('eventsSidebar');
|
||
const controllerButtons = document.querySelectorAll('[data-open-sidebar]');
|
||
const closeSidebarBtn = document.getElementById('closeSidebar');
|
||
|
||
let sidebarHover = false;
|
||
let sidebarRequested = false;
|
||
|
||
function openSidebar(mode) {
|
||
sidebar.classList.add('open');
|
||
sidebarRequested = true;
|
||
if (mode === 'official') switchTab('official');
|
||
else if (mode === 'review') switchTab('review');
|
||
else if (mode === 'both') switchTab('official');
|
||
}
|
||
|
||
function closeSidebar() {
|
||
sidebar.classList.remove('open');
|
||
sidebarRequested = false;
|
||
}
|
||
|
||
controllerButtons.forEach(btn => {
|
||
btn.addEventListener('click', () => {
|
||
const mode = btn.dataset.openSidebar;
|
||
openSidebar(mode);
|
||
});
|
||
});
|
||
|
||
closeSidebarBtn.addEventListener('click', () => { closeSidebar(); });
|
||
|
||
sidebar.addEventListener('mouseenter', () => { sidebarHover = true; });
|
||
|
||
sidebar.addEventListener('mouseleave', () => {
|
||
sidebarHover = false;
|
||
setTimeout(() => {
|
||
if (!sidebarHover && sidebarRequested) {
|
||
sidebar.classList.remove('open');
|
||
sidebarRequested = false;
|
||
}
|
||
}, 150);
|
||
});
|
||
|
||
const tabButtons = document.querySelectorAll('.tab-button');
|
||
const tabPanels = {
|
||
official: document.getElementById('tab-official'),
|
||
review: document.getElementById('tab-review'),
|
||
};
|
||
|
||
function switchTab(tab) {
|
||
tabButtons.forEach(b => {
|
||
b.classList.toggle('active', b.dataset.tab === tab);
|
||
});
|
||
Object.keys(tabPanels).forEach(key => {
|
||
tabPanels[key].classList.toggle('active', key === tab);
|
||
});
|
||
}
|
||
|
||
tabButtons.forEach(btn => {
|
||
btn.addEventListener('click', () => {
|
||
switchTab(btn.dataset.tab);
|
||
});
|
||
});
|
||
|
||
attachEvents('officialEvents');
|
||
attachEvents('reviewEvents');
|
||
|
||
// Comment modal
|
||
const commentModal = document.getElementById('commentModal');
|
||
const openCommentModalBtn = document.getElementById('openCommentModal');
|
||
const closeCommentModalBtn = document.getElementById('closeCommentModal');
|
||
const cancelCommentModalBtn = document.getElementById('cancelCommentModal');
|
||
|
||
function openCommentModal() {
|
||
commentModal.classList.add('open');
|
||
}
|
||
function closeCommentModal() {
|
||
commentModal.classList.remove('open');
|
||
}
|
||
|
||
openCommentModalBtn.addEventListener('click', openCommentModal);
|
||
closeCommentModalBtn.addEventListener('click', closeCommentModal);
|
||
cancelCommentModalBtn.addEventListener('click', closeCommentModal);
|
||
commentModal.addEventListener('click', (e) => {
|
||
if (e.target === commentModal) closeCommentModal();
|
||
});
|
||
|
||
// Share modal
|
||
const shareModal = document.getElementById('shareModal');
|
||
const shareVideoBtn = document.getElementById('shareVideoBtn');
|
||
const closeShareModalBtn = document.getElementById('closeShareModal');
|
||
const cancelShareModalBtn = document.getElementById('cancelShareModal');
|
||
|
||
function openShareModal() {
|
||
shareModal.classList.add('open');
|
||
}
|
||
function closeShareModal() {
|
||
shareModal.classList.remove('open');
|
||
}
|
||
|
||
shareVideoBtn.addEventListener('click', openShareModal);
|
||
closeShareModalBtn.addEventListener('click', closeShareModal);
|
||
cancelShareModalBtn.addEventListener('click', closeShareModal);
|
||
shareModal.addEventListener('click', (e) => {
|
||
if (e.target === shareModal) closeShareModal();
|
||
});
|
||
|
||
// Points modal
|
||
const pointsModal = document.getElementById('pointsModal');
|
||
const openPointsModalBtn = document.getElementById('openPointsModal');
|
||
const closePointsModalBtn = document.getElementById('closePointsModal');
|
||
const cancelPointsModalBtn = document.getElementById('cancelPointsModal');
|
||
|
||
function openPointsModal() {
|
||
pointsModal.classList.add('open');
|
||
}
|
||
function closePointsModal() {
|
||
pointsModal.classList.remove('open');
|
||
}
|
||
|
||
openPointsModalBtn.addEventListener('click', openPointsModal);
|
||
closePointsModalBtn.addEventListener('click', closePointsModal);
|
||
cancelPointsModalBtn.addEventListener('click', closePointsModal);
|
||
pointsModal.addEventListener('click', (e) => {
|
||
if (e.target === pointsModal) closePointsModal();
|
||
});
|
||
|
||
// Collapsible description
|
||
const descriptionBody = document.getElementById('descriptionBody');
|
||
const descriptionToggle = document.getElementById('toggleDescription');
|
||
const descriptionToggleLabel = document.getElementById('descriptionToggleLabel');
|
||
const descriptionToggleIcon = document.getElementById('descriptionToggleIcon');
|
||
|
||
if (descriptionToggle && descriptionBody) {
|
||
descriptionToggle.addEventListener('click', () => {
|
||
const isOpen = descriptionBody.classList.toggle('open');
|
||
descriptionToggleLabel.textContent = isOpen ? 'Hide description' : 'Show description';
|
||
descriptionToggleIcon.textContent = isOpen ? '▲' : '▼';
|
||
});
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|